intersection efficace de deux Liste en Java?
-
18-09-2019 - |
Question
La question est simple:
J'ai deux listes
List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);
Et je dois obtenir l'intersection de ces derniers. Y at-il un moyen rapide pour y parvenir?
La solution
Vous pouvez utiliser méthode retainAll
:
columnsOld.retainAll (columnsNew);
Autres conseils
Depuis retainAll ne touche pas la collection d'arguments, ce serait plus rapide:
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);
}
L'intersection sera les valeurs laissées dans columnsNew. Suppression des valeurs déjà par rapport Fom columnsOld réduiront le nombre de comparaisons nécessaires.
Utilisation Goyave:
Sets.intersection(Sets.newHashSet(setA), Sets.newHashSet(setB))
Qu'en est-
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;
}
Il y a une façon agréable avec des flux qui peut le faire en une seule ligne de code et vous pouvez deux listes qui ne sont pas du même type qui est impossible avec la méthode containsAll afaik:
columnsOld.stream().filter(c -> columnsNew.contains(c)).collect(Collectors.toList());
Un exemple pour les listes avec différents types. Si vous avez un realtion entre foo et bar et vous pouvez obtenir un bar-objet de foo que vous pouvez modifier votre flux:
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());
Si vous mettez la deuxième liste dans un ensemble HashSet dire. Et itérer sur la première liste de vérification de la présence sur le plateau et le retrait sinon présente, votre première liste finira par avoir l'intersection dont vous avez besoin. Ce sera beaucoup plus rapide que retainAll ou contient une liste. L'accent ici est d'utiliser un ensemble au lieu de la liste. Lookups sont O (1). firstList.retainAll (nouveau HashSet (secondList)) sera également.
à l'aide retainAll si ne se soucient pas des événements, sinon en utilisant 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 est une classe de service en AbacusUtil
utilisation org.apache.commons.collections4.ListUtils # intersection