Ich habe zwei Listen mit unterschiedlichen Objekten.
List<Object1> list1;
List<Object2> list2;
Ich möchte überprüfen, ob ein Element aus Liste1 in Liste2 vorhanden ist, basierend auf einem bestimmten Attribut (Objekt1 und Objekt2 haben (unter anderem) ein gemeinsames Attribut (mit dem Typ Long) mit dem Namen attributeSame).
im Moment mache ich es so:
boolean found = false;
for(Object1 object1 : list1){
for(Object2 object2: list2){
if(object1.getAttributeSame() == object2.getAttributeSame()){
found = true;
//also do something
}
}
if(!found){
//do something
}
found = false;
}
Aber ich denke, es gibt einen besseren und schnelleren Weg, dies zu tun :) Kann jemand es vorschlagen?
Vielen Dank!
Antworten:
Wenn Sie nur die grundlegende Gleichheit testen müssen, können Sie dies mit dem grundlegenden JDK tun, ohne die Eingabelisten in der einen Zeile zu ändern
Wenn Sie eine bestimmte Eigenschaft testen müssen, ist dies schwieriger. Ich würde standardmäßig empfehlen,
... die die unterschiedlichen Werte in sammelt
list2
und jeden Wertlist1
auf Präsenz prüft .quelle
list1
in a zu kopierenSet
, erhalten Sie O (n) + O (m), dh O (n + m), auf Kosten eines zusätzlichen Arbeitsspeichers. Es ist eine Frage der Wahl zwischen Geschwindigkeit oder Speicher.Sie können Apache Commons CollectionUtils verwenden :
Dies setzt voraus, dass Sie die Gleichheitsfunktionalität für Ihre benutzerdefinierten Objekte ordnungsgemäß überladen haben.
quelle
Um Narendras Logik zu verkürzen, können Sie Folgendes verwenden:
quelle
list1.stream().anyMatch(list2::contains);
Es ist eine Methode von dem
Collection
Namen ,retainAll
aber mit einigen Nebenwirkungen für Sie ReferenzEs ist wie
quelle
Loius Antwort ist richtig, ich möchte nur ein Beispiel hinzufügen:
quelle
Ein schnellerer Weg erfordert zusätzlichen Platz.
Beispielsweise:
Fügen Sie alle Elemente in einer Liste in ein HashSet ein (Sie müssen die Hash-Funktion selbst implementieren, um object.getAttributeSame () verwenden zu können.)
Gehen Sie die andere Liste durch und prüfen Sie, ob sich ein Element im HashSet befindet.
Auf diese Weise wird jedes Objekt höchstens einmal besucht. und HashSet ist schnell genug, um ein Objekt in O (1) zu überprüfen oder einzufügen.
quelle
Laut JavaDoc für die
.contains(Object obj)
:Wenn Sie also Ihre
.equals()
Methode für Ihr bestimmtes Objekt überschreiben , sollten Sie in der Lage sein:if(list1.contains(object2))...
Wenn die Elemente eindeutig sind (dh unterschiedliche Attribute haben), können Sie das
.equals()
und überschreiben.hashcode()
und alles in speichernHashSets
. Auf diese Weise können Sie in konstanter Zeit überprüfen, ob eines ein anderes Element enthält.quelle
Um es schneller zu machen, können Sie eine Pause hinzufügen. Auf diese Weise stoppt die Schleife, wenn gefunden auf true gesetzt ist:
Wenn Sie Karten anstelle von Listen mit den Schlüsseln attributeSame als Schlüssel haben würden, könnten Sie schneller nach einem Wert in einer Karte suchen, ob die zweite Karte einen entsprechenden Wert enthält oder nicht.
quelle
Können Sie die Art der Daten definieren, die Sie speichern? ist es Big Data? ist es sortiert? Ich denke, dass Sie je nach Daten unterschiedliche Effizienzansätze berücksichtigen müssen.
Wenn Ihre Daten beispielsweise groß und unsortiert sind, können Sie versuchen, die beiden Listen zusammen nach Index zu iterieren und jedes Listenattribut in einem anderen Listenhelfer zu speichern. Dann können Sie die aktuellen Attribute in den Hilfslisten überprüfen.
Viel Glück
bearbeitet: und ich würde nicht empfehlen, gleich viel zu überladen. Es ist gefährlich und wahrscheinlich gegen Ihr Objekt.
quelle
org.springframework.util.CollectionUtils
quelle
Mit
java 8
können wir wie folgt prüfen, ob eine Liste ein Element einer anderen Liste enthältquelle
Wenn Sie überprüfen möchten, ob ein Element in einer Liste vorhanden ist, verwenden Sie die Methode includes.
quelle