Konvertieren eines Arrays von Objekten in ein Array ihrer primitiven Typen


80

Wenn Sie ein Array von Java-Objekten haben, die einen primitiven Typ haben (z. B. Byte, Integer, Char usw.). Gibt es eine gute Möglichkeit, es in ein Array vom primitiven Typ umzuwandeln? Dies kann insbesondere erfolgen, ohne dass ein neues Array erstellt und der Inhalt durchlaufen werden muss.

So zum Beispiel gegeben

Integer[] array

Was ist der beste Weg, dies in umzuwandeln

int[] intArray

Leider müssen wir dies ziemlich häufig tun, wenn wir eine Schnittstelle zwischen Hibernate und einigen Bibliotheken von Drittanbietern herstellen, über die wir keine Kontrolle haben. Es scheint, dass dies eine recht häufige Operation ist, daher wäre ich überrascht, wenn es keine Abkürzung gibt.

Danke für Ihre Hilfe!

Antworten:


40

Leider gibt es auf der Java-Plattform nichts, was dies tut. Übrigens müssen Sie auch nullElemente im Integer[]Array explizit behandeln (was intwerden Sie für diese verwenden?).


6
Guter Punkt über die Nullen. Für meine Zwecke hätte ich akzeptiert, dass eine Ausnahme ausgelöst wird, wenn einer der Einträge null ist, genauso wie eine NullPointerException ausgelöst wird, wenn Sie ein Objekt entpacken.
Il-Bhima

2
Diese Antwort ist mit Java 8 nicht mehr korrekt, siehe Alex 'Antwort .
Robinst


69

Mit in Java 8 eingeführten Streams ist dies möglich:

int[] intArray = Arrays.stream(array).mapToInt(Integer::intValue).toArray();

Derzeit gibt es jedoch nur primitive Streams für int, longund double. Wenn Sie in einen anderen primitiven Typ konvertieren müssen, z. B. byteden kürzesten Weg ohne externe Bibliothek, ist dies:

byte[] byteArray = new byte[array.length];
for(int i = 0; i < array.length; i++) byteArray[i] = array[i];

Oder die for-Schleife kann durch einen Stream ersetzt werden, wenn Sie möchten:

IntStream.range(0, array.length).forEach(i -> byteArray[i] = array[i]);

Alle diese werden ein werfen, NullPointerExceptionwenn eines Ihrer Elemente sind null.


2
Stattdessen Integer::intValuekönnen Sie auch verwenden i -> i(was Unboxing verwendet).
Robinst

1
@robinst Und Unboxing fordert der Compiler Integer::intValuefür Sie auf. Warum also ein neues Lambda erstellen, wenn die Methode sofort verfügbar ist?
Andreas

@Andreas Nur eine andere Option aufzulisten, die Sie auswählen, ist eine Frage des Codestils / der persönlichen Präferenz. Ich habe die beiden Ansätze auch mit einem Mikrobenchmark versehen (unter Verwendung von JMH), und sie haben die gleiche Leistung.
Robinst

Bei Verwendung des ersten veröffentlichten Code-Snippets wurde der Fehler "Nicht statische Methode kann nicht im statischen Kontext verwendet werden" angezeigt. Ich habe stattdessen Folgendes getan: Ich int[] ints = Arrays.stream(objects).mapToInt(i -> Integer.parseInt(i.toString())).toArray(); hoffe, dies ist hilfreich für alle, die das gleiche Problem haben. Und wenn jemand einen besseren Weg kennt, lass es mich wissen.
Kartik Chugh

Dies sollte heutzutage die akzeptierte Antwort sein. Danke Alex.
Per Lundberg


3

Dies kann insbesondere erfolgen, ohne dass ein neues Array erstellt und der Inhalt durchlaufen werden muss.

Sie können ein Array von Integer in Java nicht in int konvertieren (dh Sie können den Typ der Elemente eines Arrays nicht ändern). Sie müssen also entweder ein neues int [] -Array erstellen und den Wert der Integer-Objekte in dieses Array kopieren, oder Sie können einen Adapter verwenden:

class IntAdapter {
    private Integer[] array;
    public IntAdapter (Integer[] array) { this.array = array; }
    public int get (int index) { return array[index].intValue(); }
}

Dies kann Ihren Code ein wenig lesbarer machen und das IntAdapter-Objekt belegt nur wenige Bytes Speicher. Der große Vorteil eines Adapters ist, dass Sie hier Sonderfälle behandeln können:

class IntAdapter {
    private Integer[] array;
    public int nullValue = 0;
    public IntAdapter (Integer[] array) { this.array = array; }
    public int get (int index) { 
        return array[index] == null ? nullValue : array[index].intValue();
    }
}

Eine andere Lösung ist die Verwendung von Commons Primitives, die viele vordefinierte Adapter enthalten. Schauen Sie sich in Ihrem Fall ListIntList an .


2

Oder mach es einfach, wenn du es nur einmal machst. Aber Sie haben nicht über Integer! = Null-Fall gesprochen.

    //array is the Integer array
    int[] array2 = new int[array.length];
    int i=0;
    for (Integer integer : array) {
        array2[i] = integer.intValue();
        i++;
    }

1

Die Verwendung von Dollar ist einfach wie folgt:

Integer[] array = ...;
int[] primitiveArray = $(array).toIntArray();

6
Dies scheint nicht Java zu sein, zumindest nicht Java 1.6 oder 1.7.
Lordalcol

2
@ LorDalCol Dollar ist eigentlich eine Java-Bibliothek
Jaroslav Záruba

1
Es ist möglich, eine Java-Methode zu benennen $! Ich glaube nicht, dass es ermutigt wird ...
Ole VV
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.