777 Stimmen

Wie kann ich in Java List<Integer> in int[] umwandeln?

Ich bin neu in Java. Wie kann ich eine List<Integer> à int[] in Java?

Ich bin verwirrt, weil List.toArray() gibt tatsächlich eine Object[] , die weder auf Integer[] noch int[] .

Im Moment verwende ich dazu eine Schleife:

int[] toIntArray(List<Integer> list) {
  int[] ret = new int[list.size()];
  for(int i = 0; i < ret.length; i++)
    ret[i] = list.get(i);
  return ret;
}

Gibt es einen besseren Weg, dies zu tun?

Dies ist vergleichbar mit der Frage <em><a href="https://stackoverflow.com/questions/880581/java-convert-int-to-integer">Wie kann ich int[] in Integer[] in Java konvertieren? </a></em>.

11 Stimmen

Sie können nur in Integer[] casten, indem Sie: Integer[] arr = (Integer[])list.toArray(new Integer[list.size]);

0 Stimmen

@ripper234, eddie's Lösung ist schlechter als die auf die Frage. eigentlich die ursprüngliche ist technisch die beste, solange die Liste ist RandomAccess impl (auch es wird ordnungsgemäß entrollt und die Bounds Check für Array entfernt werden)

1 Stimmen

@Hardcoded sollten Sie Ihren Kommentar bearbeiten, um die Methode list.size() zu verwenden und den unnötigen Cast wegzulassen.

1057voto

Pshemo Punkte 118094

Mit den in Java 8 hinzugefügten Streams können wir Code wie diesen schreiben:

int[] example1 = list.stream().mapToInt(i->i).toArray();
// OR
int[] example2 = list.stream().mapToInt(Integer::intValue).toArray();

Gedanklicher Prozess:

  • Die einfache Stream#toArray gibt eine Object[] Array, das ist also nicht das, was wir wollen. Auch, Stream#toArray(IntFunction<A[]> generator) tut nicht das, was wir wollen, weil der generische Typ A kann den primitiven Typ nicht repräsentieren int

  • Es wäre also schön, wenn es einen Stream gäbe, der den primitiven Typ int anstelle des Wrappers Integer weil seine toArray Methode wird höchstwahrscheinlich auch eine int[] Array (das etwas anderes zurückgibt wie Object[] oder sogar in einer Schachtel Integer[] wäre hier unnatürlich). Und glücklicherweise hat Java 8 einen solchen Stream, der IntStream

  • Jetzt müssen wir nur noch herausfinden, wie wir unsere Stream<Integer> (die von list.stream() ) zu diesem glänzenden IntStream .

    Schnelle Suche in der Dokumentation von Stream auf der Suche nach Methoden, die Folgendes zurückgeben IntStream führt uns zu unserer Lösung, die lautet mapToInt(ToIntFunction<? super T> mapper) Methode. Alles, was wir tun müssen, ist ein Mapping von Integer à int .

    Seit ToIntFunction es funktionale Schnittstelle können wir seine Instanz über lambda o Methodenreferenz .

    Um Integer in int zu konvertieren, können wir Folgendes verwenden Integer#intValue also im Inneren mapToInt können wir schreiben:

    mapToInt( (Integer i) -> i.intValue() )

    (oder manche mögen es vorziehen: mapToInt(Integer::intValue) .)

    Ein ähnlicher Code kann jedoch mit Unboxing erzeugt werden, da der Compiler weiß, dass das Ergebnis dieses Lambdas vom Typ sein muss int (das Lambda, das in mapToInt ist eine Implementierung des ToIntFunction Schnittstelle, die als Körper eine Methode des Typs erwartet: int applyAsInt(T value) die voraussichtlich eine int ).

    Wir können also einfach schreiben:

    mapToInt((Integer i)->i)

    Da auch die Integer eintippen (Integer i) kann vom Compiler abgeleitet werden, da List<Integer>#stream() gibt eine Stream<Integer> können wir auch weglassen, so dass wir mit

    mapToInt(i -> i)

7 Stimmen

Das ist eindeutig die beste Lösung. Schade, dass es an Erklärungen mangelt.

22 Stimmen

@PimpTrizkit Diese Antwort wurde ein wenig aktualisiert. Ich hoffe, sie ist jetzt klarer.

3 Stimmen

@Pshemo - Danke! Ich persönlich brauchte keine Erklärung. Aber ich hasse es, die perfekte Antwort ohne eine zu sehen! Wie auch immer, Ihre Erklärung hat mich aufgeklärt und war hilfreich. Ich frage mich, warum die mapTo... Funktionen erlauben keine null lambda.... wie sort does...., was dazu führt, dass es standardmäßig ein Standardverhalten gibt... in diesem Fall, i -> i wäre ein perfektes Standardverhalten.

263voto

Jon Skeet Punkte 1325502

Leider glaube ich nicht, dass es wirklich es ein besserer Weg, dies zu tun, aufgrund der Art von Javas Umgang mit primitiven Typen, Boxing, Arrays und Generika. Im Besonderen:

  • List<T>.toArray wird nicht funktionieren, weil es keine Konvertierung von Integer à int
  • Sie können nicht verwenden int als Typargument für Generika, so dass es ont zu sein int -spezifische Methode (oder eine, die Reflexion verwendet, um fiese Tricks zu machen).

Ich glaube, es gibt Bibliotheken, die automatisch generierte Versionen dieser Art von Methode für alle primitiven Typen haben (d.h. es gibt eine Vorlage, die für jeden Typ kopiert wird). Es ist hässlich, aber so ist es leider :(

Auch wenn die Arrays Klasse herauskam, bevor die Generika in Java Einzug hielten, müsste sie immer noch all die schrecklichen Überladungen enthalten, wenn sie heute eingeführt würde (vorausgesetzt, Sie wollen primitive Arrays verwenden).

33 Stimmen

Siehe auch die Antwort von ColinD über Ints.toArray(Collection<Integer>) von Guava.

9 Stimmen

@JonSkeet Sie meinen die schrecklichen Überladungen, die es bereits in der Klasse Arrays für binarySearch , copyOf , copyOfRange ...? Ich frage mich, warum sie nicht noch eine Reihe von schrecklichen Überlastungen einbauen konnten.

1 Stimmen

@ron ColinDs Antwort gibt nichts anderes als das, was der OP bereits hatte - eine for-Schleife, um ein primitives Array mit einem nicht-primitiven zu füllen.

222voto

ColinD Punkte 106101

Zusätzlich zu Commons Lang können Sie dies tun mit Guave Die Methode Ints.toArray(Collection<Integer> collection) :

List<Integer> list = ...
int[] ints = Ints.toArray(list);

Dadurch ersparen Sie sich die Umwandlung von Arrays, die für das Commons Lang-Äquivalent erforderlich ist.

4 Stimmen

Leider ist das Zwischenfeld in Guava versteckt: Object[] boxedArray = collection.toArray();

10 Stimmen

"Glücklicherweise ist das Zwischenfeld in Guava versteckt." - Ich habe das für Sie korrigiert. ;)

182voto

Eddie Punkte 52504

Am einfachsten ist es, wenn Sie die folgende Methode verwenden Apache Commons Lang . Es hat eine praktische ArrayUtils Klasse, die tun kann, was Sie wollen. Verwenden Sie die toPrimitive Methode mit der Überladung für ein Array von Integer s.

List<Integer> myList;
 ... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));

Auf diese Weise müssen Sie das Rad nicht neu erfinden. Commons Lang verfügt über viele nützliche Funktionen, die Java ausgelassen hat. Oben habe ich mich dafür entschieden, eine Integer-Liste mit der richtigen Größe zu erstellen. Sie können auch ein statisches Integer-Array der Länge 0 verwenden und Java ein Array der richtigen Größe zuweisen lassen:

static final Integer[] NO_INTS = new Integer[0];
   ....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));

0 Stimmen

El toPrimitive Link ist defekt.

0 Stimmen

Hier ist ein Link zu 2.6 Commons Lang API: toPrimitive

12 Stimmen

Beachten Sie, dass dies 2 Zuweisungen und Kopien nach sich ziehen wird: myList.toArray() wird eine Integer[] und bevölkern es, während ArrayUtils.toPrimitive() wird ein int[] und entpacken Sie die Eingabe.

85voto

Pumphouse Punkte 1933

Java 8 hat uns eine einfache Möglichkeit gegeben, dies über Streams zu tun...

Verwendung der Sammlungen stream() Funktion und anschließendem Mapping auf Ints, erhält man einen IntStream. Mit der IntStream können wir toArray() aufrufen, was uns Folgendes liefert int []

int [] ints = list.stream().mapToInt(Integer::intValue).toArray();

to int []

zu IntStream

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X