Zwei verknüpfte Listen ohne Kopieren zusammenfügen - Java, Standard-API verwenden [duplizieren]

8

Ich habe zwei LinkedList in meinem Code und ich muss einen erstellen, der beides hat. Ich werde diese Listen nicht mehr brauchen, nur die neue, die alle Daten haben, die ich brauche.

Ich könnte .addAll () verwenden, aber die Leistung ist ein großes Problem, und ich kann es kaum erwarten zu kopieren, Referenzen hinzufügen, alles jedes Mal ..

Ich suche nach etwas wie wir normalerweise tun, wenn wir unsere eigene verknüpfte Liste erstellen, verbinden Sie einfach den letzten Knoten von einer mit der Faust von der zweiten. Gibt es eine Möglichkeit, das mit der LinkedList-Klasse aus der Java API zu tun?

Das Zusammenführen von Sammlungen ist ein anderer Fall, obwohl die Operation fast dasselbe bedeutet, mein Problem betrifft nur die Leistung und nur für LinkedLists, die normalerweise tun können, was ich brauche. Auch "Verschmelzen" ist eine Art mehrdeutiger Begriff, was ich will ist einfach nur zusammen zu setzen, egal in welcher Reihenfolge sie sind, mit Leistung im Hinterkopf. Ich schaue nicht, ob es möglich ist zu verschmelzen ...

Eine andere Sache, meine Frage bezieht sich nur auf die API, ich bin nicht auf der Suche nach meinem eigenen Code (Chef Anforderung) und deshalb unterscheidet sich von diesem: Mischen Sie zwei Listen in konstanter Zeit in Java - nicht nützliche Antworten dort entweder ..

    
Victor 27.08.2013, 14:39
quelle

7 Antworten

3

Wenn Sie LinkedList verwenden, sind Sie höchstwahrscheinlich nicht an indiziertem Zugriff interessiert (da indizierter Zugriff langsam ist ... aber bedenken Sie, dass eine Liste nur Referenzen speichert, also für sehr große Listen mit wenigen Einfüge- / Löschvorgängen Sie werden mit einem ArrayList effizienter arbeiten, da nicht alle Knoten im Heap zugeordnet werden müssen.

Was du eigentlich willst, ist etwas, das dir den größten Teil des List -Vertrags gibt ... oder vielleicht nicht einmal das.

Es könnte gut sein, dass alles, was du willst, etwas ist, das dir Iterable<String> gibt ... wenn das der Fall ist, hast du ein sehr einfaches Leben:

%Vor%

Dies ist eine grundlegende Implementierung, die Ihnen eine gemischte Ansicht vieler Listen bietet. Wenn Sie mehr von dem Vertrag von List erhalten möchten, können Sie die gleichen Tricks nur mit einer besseren Implementierung von ListIterator wiederholen, was viel von dem bekommen wird, was Sie wahrscheinlich wollen, oder schließlich durch das Erweitern von AbstractList und das Überschreiben der geeignete Methoden mit Ihrer neuen ListIterator -Implementierung

    
Stephen Connolly 27.08.2013, 15:46
quelle
3

Wenn Sie nur über die neue Liste iterieren möchten und List durch Iterable ersetzen können, können Sie Guavas Iterable.concat wie hier beschrieben verwenden:

Mehrere Sammlungen zu einer einzigen logischen Sammlung kombinieren?

    
phlogratos 27.08.2013 15:38
quelle
2

Ich fürchte, die Antwort ist nein. Die interne Entry -Klasse, die von LinkedList verwendet wird, ist privat, und alle öffentlichen Methoden, die von LinkedList verfügbar gemacht werden, arbeiten mit allgemeinen Sammlungen.

Ihr Anwendungsfall erscheint mir vernünftig, aber diese Implementierung unterstützt ihn nicht.

    
pamphlet 27.08.2013 14:52
quelle
2

Ich befürchte, dass der einzige Weg dazu besteht, Reflexionen zu verwenden ... Wenn Sie sich den Quellcode von LinkedList ansehen , können Sie sehen, dass die Unterklasse Entry<E> privat ist, was a ist Problem, wenn Sie die ersten und letzten Einträge mit anderen Einträgen verbinden möchten, um die Liste zusammenzuführen.

Update: Selbst Reflektionen sind nicht sicher (außer Sie fügen Prüfungen hinzu), weil Oracle hat den Namen der Unterklasse Entry in Node geändert und die Reihenfolge der Argumente des Konstruktors geändert! in JDK 7, das ist dumm IMHO.

Schmutzige Lösung: Fügen Sie eine ganze Kopie des Quellcodes ein und ändern Sie die private -Schlüsselwörter in public . Ich bin mir jedoch nicht sicher, ob dies von Oracle erlaubt ist. Überprüfen Sie ihre Lizenz.

    
Martijn Courteaux 27.08.2013 14:52
quelle
1

Eine Möglichkeit, dies zu tun, ist die Verwendung von getLast () um das letzte Element aus der Liste zu entfernen und dann addFirst () auf der anderen, um es an die Front hinzuzufügen.

Wie bereits erwähnt, addAll () würde nichts kopieren und könnte genauso einfach verwendet werden.

Wenn Ihr Problem bei der tatsächlichen Instanziierung von Knotenobjekten in der LinkedList auftritt, müssen Sie möglicherweise eine eigene Version implementieren, die mehr Implementierungsmechanismen in der API verfügbar macht.

    
Surveon 27.08.2013 14:41
quelle
1

Warum nicht eine Wrapper / Proxy-Klasse erstellen, die List implementiert und Referenzen auf die 2 Unterlisten enthält, dann implementieren Sie die List-Methoden (oder zumindest diejenigen, die Sie downstream benötigen) - ein wenig Arbeit, aber beim Kopieren einer der Listen ist wirklich das Problem klingt wie es sich lohnt.

    
Jay 27.08.2013 15:40
quelle
0

importieren Sie java.util.LinkedList;

public class MergeLinkedList {

%Vor%

}

O / P [A, B, C, D]

Sie müssen addall ();

verwenden     
Amal 27.08.2013 15:30
quelle

Tags und Links