Wie bekomme ich ein Array-Slice von ArrayList
in Java? Konkret möchte ich so etwas machen:
ArrayList<Integer> inputA = input.subList(0, input.size()/2);
// where 'input' is a prepouplated ArrayList<Integer>
Ich habe erwartet, dass dies funktioniert, aber Java gibt a zurück List
- es ist also nicht kompatibel. Und wenn ich versuche, es zu besetzen, lässt mich Java nicht. Ich brauche ein ArrayList
- was kann ich tun?
ArrayList
? Ich denke , man kann ein wenig Verständnis fehlt , wie Schnittstellen arbeiten , weilList
undArrayList
nicht „unvereinbar“ -ArrayList
GeräteList
, undList
wahrscheinlich enthält alle notwendigen Methoden , die Sie benötigen.ArrayList
weil er dann eine Methode damit aufrufen muss, die eine akzeptiertArrayList
. Wahrscheinlich ist eine solche Methode schlecht konzipiert und sollteList
stattdessen akzeptiert werden, aber solche Situationen können nicht nur in Interviewfragen auftreten, sondern auch in Code, der von anderen geschrieben wurde und den man nicht einfach ändern kann. Mitarbeiter und Bibliotheken sind nicht immer perfekt.Antworten:
In Java empfiehlt es sich, in APIs eher Schnittstellentypen als konkrete Klassen zu verwenden.
Ihr Problem ist, dass Sie
ArrayList
(wahrscheinlich an vielen Orten) verwenden, wo Sie wirklich verwenden solltenList
. Infolgedessen haben Sie Probleme mit einer unnötigen Einschränkung erstellt, dass die Liste eine istArrayList
.So sollte Ihr Code aussehen:
List input = new ArrayList(...); public void doSomething(List input) { List inputA = input.subList(0, input.size()/2); ... } this.doSomething(input);
Ihre vorgeschlagene "Lösung" für das Problem war / ist:
new ArrayList(input.subList(0, input.size()/2))
Das funktioniert, indem eine Kopie der Unterliste erstellt wird. Es ist keine Scheibe im normalen Sinne. Wenn die Unterliste groß ist, ist das Erstellen der Kopie außerdem teuer.
Wenn Sie durch APIs eingeschränkt sind , dass Sie nicht ändern können , so dass Sie zu haben , zu erklären ,
inputA
wie einArrayList
, können Sie möglicherweise eine benutzerdefinierte Unterklasse von implementieren ,ArrayList
in dem dassubList
Verfahren eine Unterklasse von zurückgibtArrayList
. Jedoch:ArrayList
Klasse.ArrayList
Instanzen erstellen, um stattdessen Instanzen Ihrer Unterklasse zu erstellen.Die Lösung "Copy the Array" ist praktischer ... wenn man bedenkt, dass dies keine echten Slices sind.
quelle
new ArrayList(input.subList(0, input.size()/2))
Ich habe einen Weg gefunden, wenn Sie startIndex und endIndex der Elemente kennen, die aus ArrayList entfernt werden müssen
Lassen Sie
al
werden das Original und ArrayliststartIndex
,endIndex
werden Start- und End - Index jeweils aus dem Array entfernt werden:al.subList(startIndex, endIndex + 1).clear();
quelle
Wenn es keine Methode gibt, können Sie von 0 bis iterieren
input.size()/2
, indem Sie jedes aufeinanderfolgende Element nehmen und an eine neue ArrayList anhängen.EDIT : Eigentlich denke ich, dass Sie diese Liste verwenden können, um eine neue ArrayList mit einem der ArrayList-Konstruktoren zu instanziieren .
quelle
Obwohl dieser Beitrag sehr alt ist. Für den Fall, dass jemand danach sucht ..
Guava erleichtert die Aufteilung der Liste in Unterlisten einer bestimmten Größe
List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); List<List<Integer>> subSets = Lists.partition(intList, 3);
quelle
So habe ich es gelöst. Ich habe vergessen, dass die Unterliste ein direkter Verweis auf die Elemente in der ursprünglichen Liste ist, daher ist es sinnvoll, warum es nicht funktioniert.
ArrayList<Integer> inputA = new ArrayList<Integer>(input.subList(0, input.size()/2));
quelle