Java Сравните два списка
У меня есть два списка (не java-списки, вы можете сказать два столбца)
Например
**List 1** **Lists 2**
milan hafil
dingo iga
iga dingo
elpha binga
hafil mike
meat dingo
milan
elpha
meat
iga
neeta.peeta
Мне нужен метод, который возвращает количество элементов одинаково. В этом примере это должно быть
3, и он должен возвращать мне аналогичные значения как для списка, так и для разных значений.
Должен ли я использовать hashmap, если да, то какой метод получить мой результат?
Пожалуйста, помогите
P.S: Это не школьное задание:) Так что, если вы просто руководите мной, этого будет достаточно
Ответы
Ответ 1
ИЗМЕНИТЬ
Вот две версии. Один из них использует ArrayList
и другие, используя HashSet
Сравните их и создайте свою собственную версию, пока не получите то, что вам нужно.
Этого должно быть достаточно, чтобы покрыть:
P.S: Это не школьное задание:) Так что, если вы просто руководите мной, этого будет достаточно
часть вашего вопроса.
, продолжая исходный ответ:
Для этого вы можете использовать java.util.Collection
и/или java.util.ArrayList
.
Метод retainAll выполняет следующие действия:
Сохраняет только элементы в этой коллекции, которые содержатся в указанной коллекции
см. этот пример:
import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;
public class Repeated {
public static void main( String [] args ) {
Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));
listOne.retainAll( listTwo );
System.out.println( listOne );
}
}
ИЗМЕНИТЬ
Для второй части (аналогичные значения) вы можете использовать метод removeAll:
Удаляет все элементы коллекции, которые также содержатся в указанной коллекции.
Эта вторая версия дает вам также аналогичные значения и повторяющиеся дескрипторы (путем отбрасывания их).
На этот раз Collection
может быть Set
вместо List
(разница в том, что Set не позволяет повторять значения)
import java.util.Collection;
import java.util.HashSet;
import java.util.Arrays;
class Repeated {
public static void main( String [] args ) {
Collection<String> listOne = Arrays.asList("milan","iga",
"dingo","iga",
"elpha","iga",
"hafil","iga",
"meat","iga",
"neeta.peeta","iga");
Collection<String> listTwo = Arrays.asList("hafil",
"iga",
"binga",
"mike",
"dingo","dingo","dingo");
Collection<String> similar = new HashSet<String>( listOne );
Collection<String> different = new HashSet<String>();
different.addAll( listOne );
different.addAll( listTwo );
similar.retainAll( listTwo );
different.removeAll( similar );
System.out.printf("One:%s%nTwo:%s%nSimilar:%s%nDifferent:%s%n", listOne, listTwo, similar, different);
}
}
Вывод:
$ java Repeated
One:[milan, iga, dingo, iga, elpha, iga, hafil, iga, meat, iga, neeta.peeta, iga]
Two:[hafil, iga, binga, mike, dingo, dingo, dingo]
Similar:[dingo, iga, hafil]
Different:[mike, binga, milan, meat, elpha, neeta.peeta]
Если это не делает то, что вам нужно, это дает вам хорошее начало, чтобы вы могли справиться здесь.
Вопрос для читателя: как бы вы включили все повторяющиеся значения?
Ответ 2
Вы можете попробовать intersection()
и subtract()
из CollectionUtils
.
intersection()
метод дает вам коллекцию, содержащую общие элементы, а метод subtract()
дает вам все необычные.
Они также должны заботиться о похожих элементах
Ответ 3
Это действительно списки (упорядоченные с дубликатами), или они sets (неупорядоченный, без дубликатов)?
Потому что, если это последнее, вы можете использовать, скажем, java.util.HashSet<E>
и делать это в ожидаемом линейном времени, используя удобный retainAll
.
List<String> list1 = Arrays.asList(
"milan", "milan", "iga", "dingo", "milan"
);
List<String> list2 = Arrays.asList(
"hafil", "milan", "dingo", "meat"
);
// intersection as set
Set<String> intersect = new HashSet<String>(list1);
intersect.retainAll(list2);
System.out.println(intersect.size()); // prints "2"
System.out.println(intersect); // prints "[milan, dingo]"
// intersection/union as list
List<String> intersectList = new ArrayList<String>();
intersectList.addAll(list1);
intersectList.addAll(list2);
intersectList.retainAll(intersect);
System.out.println(intersectList);
// prints "[milan, milan, dingo, milan, milan, dingo]"
// original lists are structurally unmodified
System.out.println(list1); // prints "[milan, milan, iga, dingo, milan]"
System.out.println(list2); // prints "[hafil, milan, dingo, meat]"
Ответ 4
Использование java 8 removeIf
public int getSimilarItems(){
List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta");
List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection
int initial = two.size();
two.removeIf(one::contains);
return initial - two.size();
}
Ответ 5
Если вы ищете удобный способ проверить равенство двух коллекций, вы можете использовать org.apache.commons.collections.CollectionUtils.isEqualCollection
, который сравнивает две коллекции независимо от порядка.
Ответ 6
Предполагая hash1
и hash2
List< String > sames = whatever
List< String > diffs = whatever
int count = 0;
for( String key : hash1.keySet() )
{
if( hash2.containsKey( key ) )
{
sames.add( key );
}
else
{
diffs.add( key );
}
}
//sames.size() contains the number of similar elements.
Ответ 7
Я нашел очень простой пример сравнения List в Список сравнения
В этом примере сначала проверяется размер, а затем проверяется доступность конкретного элемента из одного списка в другом.
Ответ 8
Простое решение: -
List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "d", "c"));
List<String> list2 = new ArrayList<String>(Arrays.asList("b", "f", "c"));
list.retainAll(list2);
list2.removeAll(list);
System.out.println("similiar " + list);
System.out.println("different " + list2);
Выход :-
similiar [b, c]
different [f]
Ответ 9
В модульных тестах: org.junit.Assert.assertArrayEquals(list1.toArray(), list2.toArray());
Ответ 10
Из всех подходов я считаю, что использование org.apache.commons.collections.CollectionUtils#isEqualCollection
- лучший подход. Вот причины -
- Я не должен объявлять какой-либо дополнительный список/установить себя
- Я не изменяю списки ввода
- Это очень эффективно. Он проверяет равенство в O (N) сложности.
Если не возможно иметь apache.commons.collections
в качестве зависимости, я бы порекомендовал реализовать алгоритм, который следует для проверки равенства списка из-за его эффективности.
Ответ 11
public static boolean compareList(List ls1, List ls2){
return ls1.containsAll(ls2) && ls1.size() == ls2.size() ? true :false;
}
public static void main(String[] args) {
ArrayList<String> one = new ArrayList<String>();
one.add("one");
one.add("two");
one.add("six");
ArrayList<String> two = new ArrayList<String>();
two.add("one");
two.add("six");
two.add("two");
System.out.println("Output1 :: " + compareList(one, two));
two.add("ten");
System.out.println("Output2 :: " + compareList(one, two));
}