Вопрос прост:
У меня есть два списка
List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);
И мне нужно получить их пересечение. Есть ли быстрый способ достичь этого?
Вопрос прост:
У меня есть два списка
List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);
И мне нужно получить их пересечение. Есть ли быстрый способ достичь этого?
Вы можете использовать метод retainAll
:
columnsOld.retainAll (columnsNew);
Так как keepAll не коснется коллекции аргументов, это будет быстрее:
List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);
for(int i = columnsNew.size() - 1; i > -1; --i){
String str = columnsNew.get(i);
if(!columnsOld.remove(str))
columnsNew.remove(str);
}
Пересечение будет значением, оставшимся в столбцахNew. Удаление уже сравниваемых значений fom columnsOld уменьшит количество необходимых сравнений.
Использование гуавы:
Sets.intersection(Sets.newHashSet(setA), Sets.newHashSet(setB))
Как насчет
private List<String> intersect(List<String> A, List<String> B) {
List<String> rtnList = new LinkedList<>();
for(String dto : A) {
if(B.contains(dto)) {
rtnList.add(dto);
}
}
return rtnList;
}
Есть хороший способ с потоками, которые могут сделать это в одной строке кода, и вы можете использовать два списка, которые не из того же типа, что невозможно с помощью метода containsAll afaik:
columnsOld.stream().filter(c -> columnsNew.contains(c)).collect(Collectors.toList());
Пример для списков с разными типами. Если у вас есть реальность между foo и bar, и вы можете получить бар-объект из foo, чем вы можете изменить свой поток:
List<foo> fooList = new ArrayList<>(Arrays.asList(new foo(), new foo()));
List<bar> barList = new ArrayList<>(Arrays.asList(new bar(), new bar()));
fooList.stream().filter(f -> barList.contains(f.getBar()).collect(Collectors.toList());
Если вы поместите второй список в набор, сообщите HashSet. И просто перебирайте первый список, проверяя наличие на наборе и удаляя, если его нет, ваш первый список, в конечном счете, будет иметь пересечение, в котором вы нуждаетесь. Это будет быстрее, чем keepAll или содержится в списке. Акцент здесь заключается в использовании набора вместо списка. Поиск - это O (1). firstList.retainAll(новый HashSet (второй список)) также будет работать.
используя retainAll, если все равно, иначе используйте N.intersection
a = N.asList(12, 16, 16, 17, 19);
b = N.asList(16, 19, 107);
a.retainAll(b); // [16, 16, 19]
N.println(a);
a = N.asList(12, 16, 16, 17, 19);
b = N.asList(16, 19, 107);
a = N.intersect(a, b);
N.println(a); // [16, 19]
N - это служебный класс в AbacusUtil
использовать org.apache.commons.collections4.ListUtils # пересечение