Wie verbinde ich zwei Listen in Java?


749

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

5
Wenn Sie dies ausschließlich für Iterationszwecke tun, sehen Sie eine andere Frage - es gibt Google Guava und Java 8-Lösungen stackoverflow.com/questions/4896662/…
Boris Treukhov

Java 8-Lösung mit Dienstprogrammmethode: stackoverflow.com/a/37386846/1216775
akhil_mittal

Nachdem ich einige der Antworten gelesen habe, tut es mir leid, dass ich gefragt habe.
Anthony Rutledge

Antworten:


591

In Java 8:

List<String> newList = Stream.concat(listOne.stream(), listTwo.stream())
                             .collect(Collectors.toList());

82
Gawd, ist das eine Sache in Java 8? Technisch gesehen gewinnt man wohl, aber das ist eine verdammt lange Schlange :-)
Robert Atkins

4
Für den Gelegenheitsleser ist hier eine kürzere Lösung, die auch Java _ Streams verwendet: stackoverflow.com/a/34090554/363573
Stephan

7
Es ist hässlich, aber zumindest fließend und kann ohne mehrzeilige Lambdas verwendet werden. Ich wünschte wirklich, es gäbe ein fließendes AddAll, das die verkettete Liste zurückgibt.
Usman Ismail

6
Ich denke, es ist erwähnenswert, dass es wirklich einfach ist, eine eindeutige Liste daraus zu machen, wie folgt:List<String> newList = Stream.concat(listOne.stream(), listTwo.stream()).distinct().collect(Collectors.toList());
Roger

1
Alternative zu concat: Stream von StreamsStream.of(listOne, listTwo).flatMap(Collection::stream).collect(Collectors.toList())
Peter Walser

569

Auf den ersten Blick kann ich es um eine Zeile kürzen:

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);

156
Während Sie technisch korrekt sind, haben Sie es um eine Zeile gekürzt, die Asymmetrie dieser nervt mich. Genug, dass ich glücklicher bin, die zusätzliche Leitung "auszugeben".
Robert Atkins

13
Gibt es hier kein Problem, bei dem das interne Array der newList auf die Größe von listOne initialisiert wird und dann möglicherweise erweitert werden muss, wenn alle Elemente aus listTwo hinzugefügt werden? Wäre es besser, die Größe jeder Liste zu verwenden, um die Größe des neuen Arrays zu bestimmen?
Eric

2
Dies war die Lösung, die für mich am besten funktioniert hat. Ich habe einen Vergleich über die Leistung verschiedener Lösungen angestellt, die als Sieger hervorgingen, zusammen mit der Erstellung der leeren Liste und dann addAll()von beiden. Ich habe alle ausprobiert, die vorschlagen, die Listen nicht zu kopieren, und sie haben viel Overhead, den wir diesmal nicht brauchten.
Manuelvigarcia

schön, aber Sie können es sogar kürzer machen: List list = new ArrayList <> (list1) .addAll (list2);
Geschwindigkeit

1
@velocity: nein, das wird nicht funktionieren. addAll(Collection)gibt a zurück boolean.
Stijn Van Bael

306

Sie können die Apache Commons-Collections- Bibliothek verwenden:

List<String> newList = ListUtils.union(list1, list2);

52
Schön, erfordert aber Apache Commons. Er hat 'keine externen Bibliotheken' angegeben
Quantum7

101
@ Quantum7, immer noch nützlich für andere Leute;) Ist Apache Commons überhaupt eine externe Bibliothek? Ich fange nichts ohne an!
Tster

28
@Platinum Nein, laut den Dokumenten entspricht ListUtils.union genau dem Code von OP. Aber vielleicht ist es irreführend, eine SET-Operation ("Union") in einem Listenkontext zu verwenden. Ich kann sehen, wie Sie erwarten könnten, dass dadurch Duplikate oder ähnliches entfernt werden, aber es scheint, dass die Methode dies nicht tut.
Quantum7

24
Vermeiden Sie Apache Commons-Sammlungen. Es ist nicht typsicher, es gibt keine Generika. Großartig, wenn Sie Java 1.4 verwenden, aber für Java 5 und höher würde ich Google Guava bevorzugen.
Michael Piefel

11
@MichaelPiefel Die neuesten Apache Commons Collections 4 sind typsicher. Mit der Java 8-Methodenreferenz werden diese statischen Dienstprogramme sehr wichtig.
Mingfai

93

Eine Ihrer Anforderungen ist es, die ursprünglichen Listen beizubehalten. Wenn Sie eine neue Liste erstellen und verwendenaddAll() , 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:

public class CompositeUnmodifiableList<E> extends AbstractList<E> {

    private final List<E> list1;
    private final List<E> list2;

    public CompositeUnmodifiableList(List<E> list1, List<E> list2) {
        this.list1 = list1;
        this.list2 = list2;
    }

    @Override
    public E get(int index) {
        if (index < list1.size()) {
            return list1.get(index);
        }
        return list2.get(index-list1.size());
    }

    @Override
    public int size() {
        return list1.size() + list2.size();
    }
}

Verwendungszweck:

List<String> newList = new CompositeUnmodifiableList<String>(listOne,listTwo);

15
Dies ist die eigentliche Antwort auf diese Frage.
Wouter Lievens

9
Dies ist eine praktikable Lösung. Beachten Sie jedoch, dass sich der Inhalt dieser Liste ändert, wenn sich die zugrunde liegenden Listenobjekte ändern (Liste1, Liste2). Möglicherweise können Sie eine Instanz der CompositeUnmodizableList selbst nicht ändern. Wenn Sie jedoch einen Verweis auf die ursprünglichen Listen erhalten, können Sie dies tun. Auch für Unbekannte: Der letzte Modifikator wirkt sich nur auf die Referenz aus auf das Listenobjekt selbst aus. Er kann sich nicht ändern, aber der Inhalt der Liste kann sich trotzdem ändern!
JWJ

3
@jwj alle sehr guten Punkte, danke. Der Klassenname verdient wahrscheinlich eine Erklärung. Ich sehe, dass diese Klasse etwas sehr Ähnliches wie die Collections.unmodifiableList()Methode macht, die eine Liste umschließt, um sie unveränderbar zu machen. CompositeUnmodifiableListmacht dasselbe, außer dass es zwei Listen umschließt und eine verkettete Ansicht bietet. Alle Punkte, über die Sie sprechenCompositeUnmodifiableList sprechen gelten auch Collections.unmodifiableList().
Kevin K

2
Der Konstruktor kann nehmen List<? extends E>
Patrick Parker

84

Wahrscheinlich nicht einfacher, aber faszinierend und hässlich:

List<String> newList = new ArrayList<String>() { { addAll(listOne); addAll(listTwo); } };

Verwenden Sie es nicht im Produktionscode ...;)


44
Hässlich und böse, genau wie fast jede Verwendung der Doppelklammerinitialisierung. Es ist jedoch kürzer;)
Jorn

4
@MarnixKlooster: Eclipse weiß, dass Sie es nicht verwenden sollten und macht es unangenehm zu verwenden ;-)
Joachim Sauer

20
Obwohl es sich physisch um eine Zeile handelt, halte ich dies nicht für einen "Einzeiler".
Splungebob

11
Warum hassen Menschen anonyme
Blockinitialisierer

18
@NimChimpsky Ich denke, das liegt hauptsächlich daran, dass es sich nicht nur um einen anonymen Blockinitialisierer handelt, sondern dass Sie tatsächlich eine anonyme Unterklasse von ArrayList erstellen. Wenn Sie jedoch den Ergebnissen dieser Double Brace Initilization-Frage vertrauen , scheint es, als ob der Hass auf DBI hauptsächlich eine Frage des stilistischen Geschmacks und der Mikrooptimierung ist. Soweit ich das beurteilen kann, gibt es dafür keine größeren Strafen. Der hinterhältige Nachteil wäre, wenn Sie jemals versuchen würden, seine Klasse zu vergleichen, da es sich nicht um ArrayList handelt.
Patrick

75

Ein weiterer Java 8 Einzeiler:

List<String> newList = Stream.of(listOne, listTwo)
                            .flatMap(Collection::stream)
                            .collect(Collectors.toList());

Als Bonus Stream.of()können Sie beliebig viele Listen verketten , da dies variabel ist.

List<String> newList = Stream.of(listOne, listTwo, listThree)
                            .flatMap(Collection::stream)
                            .collect(Collectors.toList());

35
x -> x.stream()könnte durch ersetzt werden Collection::stream.
Martin

10
... oder sogar mit List::stream.
MC Emperor

73

Nicht einfacher, aber ohne Größenänderung:

List<String> newList = new ArrayList<>(listOne.size() + listTwo.size());
newList.addAll(listOne);
newList.addAll(listTwo);

55

Ich habe diese Frage gefunden, um eine beliebige Anzahl von Listen zu verketten, ohne Rücksicht auf externe Bibliotheken. Vielleicht hilft es jemand anderem:

com.google.common.collect.Iterables#concat()

Nützlich, wenn Sie dieselbe Logik auf mehrere verschiedene Sammlungen in einer for () anwenden möchten.


9
Zum Beispiel: Lists.newArrayList (Iterables.concat (list1, list2));
meilechh

Sie sollten rufen com.google.common.collect.Iterators#concat(java.util.Iterator<? extends java.util.Iterator<? extends T>>)statt Iterables#concat(); weil die später noch elemente in temp link kopieren!
Bob

45

Java 8 ( Stream.ofund Stream.concat)

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:

List<String> result1 = Stream.concat(Stream.concat(list1.stream(),list2.stream()),list3.stream()).collect(Collectors.toList());
List<String> result2 = Stream.of(list1,list2,list3).flatMap(Collection::stream).collect(Collectors.toList());

Stream.concatNimmt 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:

public static <T> List<T> concatenateLists(List<T>... collections) {
        return Arrays.stream(collections).flatMap(Collection::stream).collect(Collectors.toList()); 
}

Dann können wir diese Methode wie folgt anwenden:

List<String> result3 = Utils.concatenateLists(list1,list2,list3);

Sie sind wahrscheinlich bereit zu sagen, List <String> result1 = Stream.concat (Stream.concat (list1.stream (), list2.stream ()), list3.stream ()). Collect (Collectors.toList ()); in Ihrem ersten Operator. Bitte repariere es.
WebComer

44

Hier ist eine Java 8-Lösung mit zwei Zeilen:

List<Object> newList = new ArrayList<>();
Stream.of(list1, list2).forEach(newList::addAll);

Beachten Sie, dass diese Methode nicht verwendet werden sollte, wenn

  • Der Ursprung von newListist nicht bekannt und kann bereits mit anderen Threads geteilt werden
  • Der Stream, der geändert newListwird , ist ein paralleler Stream und der Zugriff auf newListist nicht synchronisiert oder threadsicher

aufgrund 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.


12
Wenn ich mich nicht irre, wird dies eigentlich nicht empfohlen - docs.oracle.com/javase/8/docs/api/java/util/stream/… Bitte lesen Sie den Abschnitt über Nebenwirkungen. > Nebenwirkungen von Verhaltensparametern bei Stream-Vorgängen werden im Allgemeinen nicht empfohlen, da sie häufig zu unbeabsichtigten Verstößen gegen die Anforderungen an die Staatenlosigkeit sowie zu anderen Sicherheitsrisiken für Threads führen können. In diesem Fall ist es besser, Collectors.toList ()
Anton Balaniuc

@AntonBalaniuc Frage ist, ob dies wirklich eine Nebenwirkung ist. Zu diesem Zeitpunkt newListist von keinem anderen Thread zu beobachten. Aber Sie haben Recht, dass dies wahrscheinlich nicht getan werden sollte, wenn nicht bekannt ist, woher der Wert von newListstammt (zum Beispiel, wenn er newListals Parameter übergeben wurde.
SpaceTrucker

2
Ich bin neugierig; warum .forEach(newList::addAll);statt .collect(Collectors.toList());?
11684

4
@ 11684 weil der Sammler a sammeln würde List<List<Object>>. Was Sie vielleicht im Sinn haben, ist ungefähr
SpaceTrucker

@ SpaceTrucker Ups, das habe ich übersehen. Vielen Dank, dass Sie meine Verwirrung beseitigt haben. Ja, ich hätte darüber nachdenken sollen flatMap.
11684

34

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?

Collections.addAll(listOne, listTwo.toArray());

11
Das Nichtmodifizieren der ursprünglichen Listen war eines der Kriterien, aber dies ist nützlich, um hier als Beispiel für Situationen zu dienen, in denen dies keine Einschränkung darstellt.
Robert Atkins

1
Danke oder noch einfacher listOne.addAll (listTwo)
Jay

27

Etwas einfacher:

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);

Würde dies zu doppelten Strings führen? Bedeutet dies, dass eine Zeichenfolge, die in beiden Listen vorhanden ist, in der resultierenden Liste zweimal vorhanden ist?
AgentKnopf

4
@ Zainodis Ja, es könnte Duplikate geben. Die ListStruktur unterwirft keine Eindeutigkeitsbeschränkungen. Sie können Dupes entfernen, indem Sie dasselbe mit Sets tun. Set<String> newSet = new HashSet<>(setOne); newSet.addAll(setTwo);
Patrick

20

Ein bisschen kürzer wäre:

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);

17

Sie können Ihre generische Java 8- Dienstprogrammmethode erstellen, um eine beliebige Anzahl von Listen zu verknüpfen .

@SafeVarargs
public static <T> List<T> concat(List<T>... lists) {
    return Stream.of(lists).flatMap(List::stream).collect(Collectors.toList());
}

13

Sie können einen Oneliner erstellen, wenn die Zielliste vordeklariert ist.

(newList = new ArrayList<String>(list1)).addAll(list2);


9

Eine andere Einzeiler-Lösung mit Java8Stream, da die flatMapLösung bereits veröffentlicht ist, ist hier eine Lösung ohneflatMap

List<E> li = lol.stream().collect(ArrayList::new, List::addAll, List::addAll);

oder

List<E> ints = Stream.of(list1, list2).collect(ArrayList::new, List::addAll, List::addAll);

Code

    List<List<Integer>> lol = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
    List<Integer> li = lol.stream().collect(ArrayList::new, List::addAll, List::addAll);
    System.out.println(lol);
    System.out.println(li);

Ausgabe

[[1, 2, 3], [4, 5, 6]]
[1, 2, 3, 4, 5, 6]

1
Ich würde hinzufügen, dass diese Lösung wahrscheinlich leistungsfähiger ist als die verwendete flatMap, da die Listen nur einmal wiederholt werden, wenn sie gesammelt werden
Stefan Haberl

7

Das klügste meiner Meinung nach:

/**
 * @param smallLists
 * @return one big list containing all elements of the small ones, in the same order.
 */
public static <E> List<E> concatenate (final List<E> ... smallLists)
{
    final ArrayList<E> bigList = new ArrayList<E>();
    for (final List<E> list: smallLists)
    {
        bigList.addAll(list);
    }
    return bigList;
}

3
Vergiss das nicht @SafeVarargs!
Radon Rosborough

6

Sie können dies mit einem statischen Import und einer Hilfsklasse tun

nb Die Generierung dieser Klasse könnte wahrscheinlich verbessert werden

public class Lists {

   private Lists() { } // can't be instantiated

   public static List<T> join(List<T>... lists) {
      List<T> result = new ArrayList<T>();
      for(List<T> list : lists) {
         result.addAll(list);
      }
      return results;
   }

}

Dann können Sie Dinge wie tun

import static Lists.join;
List<T> result = join(list1, list2, list3, list4);

Wie ist der statische Import oder die Hilfsklasse relevant?
Shmosel

6

Java 8-Version mit Unterstützung für das Verbinden nach Objektschlüssel:

public List<SomeClass> mergeLists(final List<SomeClass> left, final List<SomeClass> right, String primaryKey) {
    final Map<Object, SomeClass> mergedList = new LinkedHashMap<>();

    Stream.concat(left.stream(), right.stream())
        .map(someObject -> new Pair<Object, SomeClass>(someObject.getSomeKey(), someObject))
        .forEach(pair-> mergedList.put(pair.getKey(), pair.getValue()));

    return new ArrayList<>(mergedList.values());
}

4
public static <T> List<T> merge(List<T>... args) {
    final List<T> result = new ArrayList<>();

    for (List<T> list : args) {
        result.addAll(list);
    }

    return result;
}

4

Verwenden Sie eine Helferklasse.

Ich schlage vor:

public static <E> Collection<E> addAll(Collection<E> dest, Collection<? extends E>... src) {
    for(Collection<? extends E> c : src) {
        dest.addAll(c);
    }

    return dest;
}

public static void main(String[] args) {
    System.out.println(addAll(new ArrayList<Object>(), Arrays.asList(1,2,3), Arrays.asList("a", "b", "c")));

    // does not compile
    // System.out.println(addAll(new ArrayList<Integer>(), Arrays.asList(1,2,3), Arrays.asList("a", "b", "c")));

    System.out.println(addAll(new ArrayList<Integer>(), Arrays.asList(1,2,3), Arrays.asList(4, 5, 6)));
}

3
public static <T> List<T> merge(@Nonnull final List<T>... list) {
    // calculate length first
    int mergedLength = 0;
    for (List<T> ts : list) {
      mergedLength += ts.size();
    }

    final List<T> mergedList = new ArrayList<>(mergedLength);

    for (List<T> ts : list) {
      mergedList.addAll(ts);
    }

    return mergedList;
  }

2

Wir können 2 Listen mit Java8 mit 2 Ansätzen verbinden.

    List<String> list1 = Arrays.asList("S", "T");
    List<String> list2 = Arrays.asList("U", "V");

1) Verwenden von concat:

    List<String> collect2 = Stream.concat(list1.stream(), list2.stream()).collect(toList());
    System.out.println("collect2 = " + collect2); // collect2 = [S, T, U, V]

2) Verwenden von flatMap:

    List<String> collect3 = Stream.of(list1, list2).flatMap(Collection::stream).collect(toList());
    System.out.println("collect3 = " + collect3); // collect3 = [S, T, U, V]

1
Wenn Sie eine elf Jahre alte Frage mit dreißig anderen Antworten beantworten, müssen Sie unbedingt darauf hinweisen, welche neuen Aspekte der Frage Ihre Antwort anspricht, und feststellen, ob diese Techniken zum Zeitpunkt der Beantwortung der Frage funktioniert hätten oder ob sie von den vorhandenen Funktionen abhängen im Laufe der Jahre eingeführt.
Jason Aller

2

Fast alle Antworten schlagen vor, eine ArrayList zu verwenden.

List<String> newList = new LinkedList<>(listOne);
newList.addAll(listTwo);

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


0

Ich behaupte nicht, dass es einfach ist, aber Sie haben den Bonus für Einzeiler erwähnt ;-)

Collection mergedList = Collections.list(new sun.misc.CompoundEnumeration(new Enumeration[] {
    new Vector(list1).elements(),
    new Vector(list2).elements(),
    ...
}))

warum sollte jemand diese niemals benutzen?
David

5
@ David, weil es darauf abzielte, intern in JDK verwendet zu werden. Wenn Sie dies in Ihrem Code verwendet haben, wird Ihr Code höchstwahrscheinlich nicht auf JDK / JRE ausgeführt, das nicht von Sun (oder jetzt von Oracle) stammt.
Adrian Shum

@AdrianShum Gibt es andere JDKs / JREs als Oracle? Das würde mich überraschen. Selbst wenn es auf die gängigsten API-Funktionen beschränkt wäre, würde das Wiederherstellen des gesamten
Egor Hans

1
Es gibt ziemlich viel JVM. Am häufigsten in der Unternehmenswelt gesehen wird die IBM, die iirc mit Websphere gebündelt ist
Adrian Shum

0

Kein Weg in die Nähe von Einzeiler, aber ich denke, das ist das einfachste:

List<String> newList = new ArrayList<String>(l1);
newList.addAll(l2);

for(String w:newList)
        System.out.printf("%s ", w);

0

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.

public static void main(String[] args) {
    List<String> list2 = new ArrayList<>();
    List<Pair<Integer, String>> list1 = new ArrayList<>();

    list2.add("asd");
    list2.add("asdaf");
    list1.add(new Pair<>(1, "werwe"));
    list1.add(new Pair<>(2, "tyutyu"));

    Stream stream = Stream.concat(list1.stream(), list2.stream());

    List<Pair<Integer, String>> res = (List<Pair<Integer, String>>) stream
            .map(item -> {
                if (item instanceof String) {
                    return new Pair<>(0, item);
                }
                else {
                    return new Pair<>(((Pair<Integer, String>)item).getKey(), ((Pair<Integer, String>)item).getValue());
                }
            })
            .collect(Collectors.toList());
}

0

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, Bund dann in einer ALLListe verknüpft .

public static final EnumSet<MyType> CATEGORY_A = EnumSet.of(A_1, A_2);
public static final EnumSet<MyType> CATEGORY_B = EnumSet.of(B_1, B_2, B_3);

public static final List<MyType> ALL = 
              Collections.unmodifiableList(
                  new ArrayList<MyType>(CATEGORY_A.size() + CATEGORY_B.size())
                  {{
                      addAll(CATEGORY_A);
                      addAll(CATEGORY_B);
                  }}
              );

Dies würde eine neue anonyme Klasse erstellen. Nicht empfohlener Ansatz!
Kravemir

-3
import java.util.AbstractList;
import java.util.List;


/**
 * The {@code ConcatList} is a lightweight view of two {@code List}s.
 * <p>
 * This implementation is <em>not</em> thread-safe even though the underlying lists can be.
 * 
 * @param <E>
 *            the type of elements in this list
 */
public class ConcatList<E> extends AbstractList<E> {

    /** The first underlying list. */
    private final List<E> list1;
    /** The second underlying list. */
    private final List<E> list2;

    /**
     * Constructs a new {@code ConcatList} from the given two lists.
     * 
     * @param list1
     *            the first list
     * @param list2
     *            the second list
     */
    public ConcatList(final List<E> list1, final List<E> list2) {
        this.list1 = list1;
        this.list2 = list2;
    }

    @Override
    public E get(final int index) {
        return getList(index).get(getListIndex(index));
    }

    @Override
    public E set(final int index, final E element) {
        return getList(index).set(getListIndex(index), element);
    }

    @Override
    public void add(final int index, final E element) {
        getList(index).add(getListIndex(index), element);
    }

    @Override
    public E remove(final int index) {
        return getList(index).remove(getListIndex(index));
    }

    @Override
    public int size() {
        return list1.size() + list2.size();
    }

    @Override
    public boolean contains(final Object o) {
        return list1.contains(o) || list2.contains(o);
    }

    @Override
    public void clear() {
        list1.clear();
        list2.clear();
    }

    /**
     * Returns the index within the corresponding list related to the given index.
     * 
     * @param index
     *            the index in this list
     * 
     * @return the index of the underlying list
     */
    private int getListIndex(final int index) {
        final int size1 = list1.size();
        return index >= size1 ? index - size1 : index;
    }

    /**
     * Returns the list that corresponds to the given index.
     * 
     * @param index
     *            the index in this list
     * 
     * @return the underlying list that corresponds to that index
     */
    private List<E> getList(final int index) {
        return index >= list1.size() ? list2 : list1;
    }

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.