2010-11-18 4 views
0

Я новенький Java :)Компаратора для Списка Строк

У меня есть 2 списка String, и мне было интересно, что будет наиболее эффективным способом, чтобы сравнить два и иметь результирующий массив, который содержит строки, которые не являются в другом. Например, у меня есть список, называемый oldStrings, и один называется Strings. Я видел функцию компаратора, но не в полной мере понять, как это работает, сейчас я думал, что я мог бы создать цикл, цикл через каждую строку, а затем сохранить эту строку:

for (final String str : oldStrings) { 
    if(!strings.contains(str)) 
    {      
    getLogger().info(str + " is not in strings list "); 
    } 
} 

Там собирается быть вверх до 200 строк в этом списке. Будет ли это лучшим способом для этого? Спасибо!

+0

Это домашнее задание? Если это так, отметьте его как таковой, чтобы мы могли ответить соответствующим образом. – javamonkey79

+0

Это не модуль, который я пишу для Wowza, список строк будет содержать разные потоки :) –

+0

@ javamonkey79: Домашний тег теперь обескуражен. –

ответ

8
Collection firstList = new ArrayList() {{ 
    add("str1"); 
    add("str2"); 
}}; 

Collection secondList = new ArrayList() {{ 
    add("str1"); 
    add("str3"); 
    add("str4"); 
}}; 


System.out.println("First List: " + firstList); 
System.out.println("Second List: " + secondList); 

// Here is main part 
secondList.removeAll(firstList); 

System.out.println("Result: " + secondList); 

Обновление: Более сложный вариант кода

Collection<String> firstList = new ArrayList<String>(); 
firstList.add("str1"); 
firstList.add("str2"); 

Collection<String> secondList = new ArrayList<String>(); 
secondList.add("str1"); 
secondList.add("str2"); 
secondList.add("str3"); 


System.out.println("First List: " + firstList); 
System.out.println("Second List: " + secondList); 

// Here is main part 
secondList.removeAll(firstList); 

Update:

получить acctual разницу между как список Струнный пойти на это.

Set<String> setOne = new HashSet<String>();   
    Set<String> setTwo = new HashSet<String>(); 
    setOne.add("1"); 
    setOne.add("2"); 
    setOne.add("5"); 
    setTwo.add("1"); 
    setTwo.add("3"); 
    setTwo.add("4"); 
    Set<String> setTwoDummy = new HashSet<String>(setTwo); 
    setTwo.retainAll(setOne);   
    setTwoDummy.addAll(setOne); 
    setTwoDummy.removeAll(setTwo); 
    System.out.println(""+setTwoDummy); 
+0

Спасибо, это сработает для меня :) –

+0

Argh no, я ненавижу эту идиому (как вы заполняете списки)! Он подклассифицирует ArrayList, добавляя новые конкретные классы к вашей базе классов, которые должны быть загружены отдельно загрузчиком классов, чтобы сохранить несколько символов.Я знаю, что это не относится к тому, что вы на самом деле пытаетесь показать, поэтому я не делал d/v, но это действительно плохой опыт IMO, и не следует показывать уязвимым :-). –

+0

Если мне не хватает точки вопроса, не будет ли это решение не печатать 'str2', который не находится во втором списке? Я думал, что идея состоит в том, чтобы получить разницу между 2 - которые будут: 'str2', 'str3', 'str4' – javamonkey79

4

Во-первых, проблема с вашим решением является то, что он будет только найти элементы, которые находятся в oldStrings и не strings. Если вы идете с этим подходом, вам нужно также зациклиться на другом списке.

Если это не для домашней работы, то ознакомьтесь с CollectionUtils.disjunction от Apache Commons Collections.

+0

Да, вы правы. У меня было это неправильно, ty –

1

Сравнение двух списков строк и имеют результирующий массив, который содержит строки , которые не в другом.

Описание неоднозначно, потому что мы не знаем, нужны ли нам только несоответствующие строки из первого списка, второго списка или обоих. Ниже приведен псевдокод для обоих.

for (String str : oldStrings) 
{ 
    if(strings.contains(str)) 
    { 
    intersectionList.add(str); 
    } 
} 

oldStrings.removeAll(intersectionList); 
strings.removeAll(intersectionList); 
result = strings.addAll(oldStrings).toArray(); 

Или

copyStrings = strings.clone(); 
strings.removeAll(oldStrings); 
oldStrings.removeAll(copyStrings); 
result = strings.addAll(oldStrings).toArray(); 
+0

Вам не нужен список пересечений. Просто выполните 'oldStrings.removeAll (строки)' и 'strings.removeAll (oldStrings)', а затем добавьте один к другому. Все, что вы делаете, используя 'intersectionList', удостоверяется, что ничего из старогоStrings не удалено из oldStrings ..., которое не может произойти в любом случае. –

+0

old = [1,2,3,4,5], current = [3,4,5,6], old.removeAll (current) => old = [1,2], current.removeAll (старый) = > current = [3,4,5,6]. Это неправильно? –

+0

Увы, извините, да, вы абсолютно правы. Я должен был сказать, что не имеет значения, действительно ли intersectionList содержит пересечение или в этом случае просто содержит копию oldStrings ('oldStrings.removeAll (строки); strings.removeAll (oldStringsCopy)'). Если вы столкнулись с проблемой создания списка вручную, почему бы не переломить логику и не построить прямое соединение? ('if (! strings.contains (str)) {disjunct.add (str);}') –

0

Вы должны использовать Sets утилиты Google гуавы в.

Set<String> s = Sets.newHashSet("a", "b", "c", "d"); 
Set<String> t = Sets.newHashSet("f", "g", "a", "c"); 
Sets.SetView<String> difference = Sets.difference(s, t); 
System.out.println(difference); // prints [b, d] 
Смежные вопросы