Bedingungen: Ändern Sie nicht die ursprünglichen Listen; Nur JDK, keine externen Bibliotheken. Bonuspunkte für einen Einzeiler oder eine JDK 1.3-Version.
Gibt es einen einfacheren Weg als:
List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);
Antworten:
In Java 8:
quelle
List<String> newList = Stream.concat(listOne.stream(), listTwo.stream()).distinct().collect(Collectors.toList());
Stream.of(listOne, listTwo).flatMap(Collection::stream).collect(Collectors.toList())
Auf den ersten Blick kann ich es um eine Zeile kürzen:
quelle
addAll()
von beiden. Ich habe alle ausprobiert, die vorschlagen, die Listen nicht zu kopieren, und sie haben viel Overhead, den wir diesmal nicht brauchten.addAll(Collection)
gibt a zurückboolean
.Sie können die Apache Commons-Collections- Bibliothek verwenden:
quelle
Eine Ihrer Anforderungen ist es, die ursprünglichen Listen beizubehalten. Wenn Sie eine neue Liste erstellen und verwenden
addAll()
, verdoppeln Sie effektiv die Anzahl der Verweise auf die Objekte in Ihren Listen. Dies kann zu Speicherproblemen führen, wenn Ihre Listen sehr groß sind.Wenn Sie das verkettete Ergebnis nicht ändern müssen, können Sie dies mithilfe einer benutzerdefinierten Listenimplementierung vermeiden. Die benutzerdefinierte Implementierungsklasse besteht natürlich aus mehr als einer Zeile ... aber die Verwendung ist kurz und bündig.
CompositeUnmodizableList.java:
Verwendungszweck:
quelle
Collections.unmodifiableList()
Methode macht, die eine Liste umschließt, um sie unveränderbar zu machen.CompositeUnmodifiableList
macht dasselbe, außer dass es zwei Listen umschließt und eine verkettete Ansicht bietet. Alle Punkte, über die Sie sprechenCompositeUnmodifiableList
sprechen gelten auchCollections.unmodifiableList()
.List<? extends E>
Wahrscheinlich nicht einfacher, aber faszinierend und hässlich:
Verwenden Sie es nicht im Produktionscode ...;)
quelle
Ein weiterer Java 8 Einzeiler:
Als Bonus
Stream.of()
können Sie beliebig viele Listen verketten , da dies variabel ist.quelle
x -> x.stream()
könnte durch ersetzt werdenCollection::stream
.List::stream
.Nicht einfacher, aber ohne Größenänderung:
quelle
Ich habe diese Frage gefunden, um eine beliebige Anzahl von Listen zu verketten, ohne Rücksicht auf externe Bibliotheken. Vielleicht hilft es jemand anderem:
Nützlich, wenn Sie dieselbe Logik auf mehrere verschiedene Sammlungen in einer for () anwenden möchten.
quelle
com.google.common.collect.Iterators#concat(java.util.Iterator<? extends java.util.Iterator<? extends T>>)
stattIterables#concat()
; weil die später noch elemente in temp link kopieren!Die vorgeschlagene Lösung gilt für drei Listen, kann jedoch auch für zwei Listen angewendet werden. In Java 8 können wir Stream.of oder Stream.concat verwenden als:
Stream.concat
Nimmt zwei Streams als Eingabe und erstellt einen träge verketteten Stream, dessen Elemente alle Elemente des ersten Streams sind, gefolgt von allen Elementen des zweiten Streams. Da wir drei Listen haben, haben wir diese Methode (Stream.concat
) zweimal verwendet.Wir können auch eine Utility-Klasse mit einer Methode schreiben, die eine beliebige Anzahl von Listen (unter Verwendung von varargs ) verwendet und eine verkettete Liste wie folgt zurückgibt:
Dann können wir diese Methode wie folgt anwenden:
quelle
Hier ist eine Java 8-Lösung mit zwei Zeilen:
Beachten Sie, dass diese Methode nicht verwendet werden sollte, wenn
newList
ist nicht bekannt und kann bereits mit anderen Threads geteilt werdennewList
wird , ist ein paralleler Stream und der Zugriff aufnewList
ist nicht synchronisiert oder threadsicheraufgrund von Nebenwirkungen Überlegungen.
Beide oben genannten Bedingungen gelten nicht für den oben genannten Fall der Verbindung zweier Listen, daher ist dies sicher.
Basierend auf dieser Antwort auf eine andere Frage.
quelle
newList
ist von keinem anderen Thread zu beobachten. Aber Sie haben Recht, dass dies wahrscheinlich nicht getan werden sollte, wenn nicht bekannt ist, woher der Wert vonnewList
stammt (zum Beispiel, wenn ernewList
als Parameter übergeben wurde..forEach(newList::addAll);
statt.collect(Collectors.toList());
?List<List<Object>>
. Was Sie vielleicht im Sinn haben, ist ungefährflatMap
.Dies ist einfach und nur eine Zeile, fügt jedoch den Inhalt von listTwo zu listOne hinzu. Müssen Sie den Inhalt wirklich in eine dritte Liste aufnehmen?
quelle
Etwas einfacher:
quelle
List
Struktur unterwirft keine Eindeutigkeitsbeschränkungen. Sie können Dupes entfernen, indem Sie dasselbe mit Sets tun.Set<String> newSet = new HashSet<>(setOne); newSet.addAll(setTwo);
Ein bisschen kürzer wäre:
quelle
Sie können Ihre generische Java 8- Dienstprogrammmethode erstellen, um eine beliebige Anzahl von Listen zu verknüpfen .
quelle
Sie können einen Oneliner erstellen, wenn die Zielliste vordeklariert ist.
quelle
In Java 8 (umgekehrt):
quelle
Eine andere Einzeiler-Lösung mit
Java8
Stream, da dieflatMap
Lösung bereits veröffentlicht ist, ist hier eine Lösung ohneflatMap
oder
Code
Ausgabe
quelle
flatMap
, da die Listen nur einmal wiederholt werden, wenn sie gesammelt werdenDas klügste meiner Meinung nach:
quelle
@SafeVarargs
!Sie können dies mit einem statischen Import und einer Hilfsklasse tun
nb Die Generierung dieser Klasse könnte wahrscheinlich verbessert werden
Dann können Sie Dinge wie tun
quelle
Java 8-Version mit Unterstützung für das Verbinden nach Objektschlüssel:
quelle
quelle
Verwenden Sie eine Helferklasse.
Ich schlage vor:
quelle
quelle
Wir können 2 Listen mit Java8 mit 2 Ansätzen verbinden.
1) Verwenden von concat:
2) Verwenden von flatMap:
quelle
Fast alle Antworten schlagen vor, eine ArrayList zu verwenden.
Verwenden Sie lieber eine LinkedList für effiziente Additionsvorgänge.
ArrayList add ist O (1) amortisiert, aber O (n) im schlimmsten Fall, da die Größe des Arrays geändert und kopiert werden muss. Während LinkedList add ist immer konstant O (1).
Weitere Informationen https://stackoverflow.com/a/322742/311420
quelle
Ich behaupte nicht, dass es einfach ist, aber Sie haben den Bonus für Einzeiler erwähnt ;-)
quelle
Kein Weg in die Nähe von Einzeiler, aber ich denke, das ist das einfachste:
quelle
Hier ist ein Ansatz mit Streams und Java 8, wenn Ihre Listen unterschiedliche Typen haben und Sie sie zu einer Liste eines anderen Typs kombinieren möchten.
quelle
Wenn Sie dies statisch tun möchten, können Sie Folgendes tun.
In den Beispielen werden 2 EnumSets in natürlicher Reihenfolge (== Enum-Reihenfolge) verwendet
A, B
und dann in einerALL
Liste verknüpft .quelle
quelle