Frage

Frage ist einfach:

Ich habe zwei List

List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);

Und ich brauche die Kreuzung von diesen zu bekommen. Gibt es einen schnellen Weg, um dies zu erreichen?

War es hilfreich?

Lösung

Sie können mit retainAll Methode:

columnsOld.retainAll (columnsNew);

Andere Tipps

Da retainAll das Argument Sammlung nicht berühren, das wäre schneller:

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);
}

Der Schnittpunkt werden die Werte in columnsNew links sein. Entfernen von bereits verglichenen Werte FOM columnsOld wird die Anzahl der Vergleiche reduzieren erforderlich.

Mit Guava:

Sets.intersection(Sets.newHashSet(setA), Sets.newHashSet(setB))

Google Guava Bibliothek

Wie wäre es

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;
}

Es gibt eine schöne Art und Weise mit Strömen, die dies in einer Zeile Code tun können, und Sie können zwei Listen, die nicht vom gleichen Typ sind, die afaik nicht möglich, mit der containsAll Methode ist:

columnsOld.stream().filter(c -> columnsNew.contains(c)).collect(Collectors.toList());

Ein Beispiel für Listen mit verschiedenen Typen. Wenn Sie eine real zwischen foo und bar und Sie können eine Bar-Objekt aus foo als Sie Ihren Stream ändern können:

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());

Wenn Sie die zweite Liste in einem Satz setzen sagen HashSet. Und iterieren nur über die erste Liste auf dem Set für Anwesenheitskontrolle und entfernen, wenn nicht vorhanden, Ihre erste Liste wird schließlich die Kreuzung, die Sie brauchen. Es wird viel schneller als retainAll oder enthält auf einer Liste. Die Betonung liegt hier eine Reihe statt Liste zu verwenden. Lookups sind O (1). firstList.retainAll (neu HashSet (secondList)) wird auch funktionieren.

mit retainAll wenn nicht Vorkommen kümmern, sonst N.intersection mit

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 ist eine Utility-Klasse in AbacusUtil

Verwendung org.apache.commons.collections4.ListUtils # Kreuzung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top