it-swarm.com.de

Wie konvertiere ich List <Integer> nach int [] in Java?

Dies ähnelt dieser Frage: Wie konvertiere ich int [] in Integer [] in Java?

Ich bin neu in Java. Wie kann ich einen List<Integer> in int[] in Java konvertieren? Ich bin verwirrt, weil List.toArray() tatsächlich einen Object[] zurückgibt, der in einen Integer[] oder int[] umgewandelt werden kann.

Im Moment benutze 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;
}

Ich bin sicher, es gibt einen besseren Weg, dies zu tun.

528
unknown

Leider glaube ich nicht, dass es wirklich eine bessere Möglichkeit gibt, dies zu tun, da Java primitive Typen, Boxen, Arrays und Generika behandelt. Speziell:

  • List<T>.toArray funktioniert nicht, da keine Konvertierung von Integer in int erfolgt.
  • Sie können int nicht als Typargument für Generika verwenden, daher müsste es sich bei um eine int-spezifische Methode handeln (oder um böse Tricks zu begehen).

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

Auch wenn die Klasse Arrays herauskam, bevor Generics in Java eintraf, müsste sie dennoch alle schrecklichen Überladungen enthalten, wenn sie heute eingeführt würde (vorausgesetzt, Sie möchten primitive Arrays verwenden).

202
Jon Skeet

Bisher hat noch niemand Streams erwähnt, die in Java 8 hinzugefügt wurden.

int[] array = list.stream().mapToInt(i->i).toArray();

Denkprozess:

  • simple Stream#toArray gibt Object[] zurück, es ist also nicht das, was wir wollen. Außerdem macht Stream#toArray(IntFunction<A[]> generator) nicht das, was wir wollen, weil der generische Typ A nicht das Primitive int darstellen kann.
  • es wäre also schön, einen Stream zu haben, der den primitiven Typ int anstelle des Wrappers Integer handhaben könnte, da seine Methode toArray höchstwahrscheinlich auch das Array int[] zurückgibt (etwas anderes wie Object[] oder sogar boxed Integer[] wäre hier unnatürlich). Und glücklicherweise hat Java 8 einen solchen Stream, der IntStream ist
  • jetzt müssen wir nur noch herausfinden, wie wir unseren Stream<Integer> (der von list.stream() zurückgegeben wird) in diesen glänzenden IntStream konvertieren. Hier kommt Stream#mapToInt(ToIntFunction<? super T> mapper) Methode zur Rettung. Alles, was wir tun müssen, ist die Zuordnung von Integer zu int. Wir könnten etwas wie Integer#getValue verwenden, das int zurückgibt, wie:

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

    (oder wenn jemand mapToInt(Integer::intValue) vorzieht)

    ein ähnlicher Code kann jedoch mit Unboxing generiert werden, da der Compiler weiß, dass das Ergebnis dieses Lambda int sein muss (Lambda in mapToInt ist die Implementierung der Schnittstelle ToIntFunction, die den Body für die Methode int applyAsInt(T value) erwartet, die int zurückgibt).

    Wir können also einfach schreiben

    mapToInt((Integer i)->i)
    

    Auch da Integer(Integer i) eingibt, kann der Compiler darauf schließen, dass List<Integer>#stream()Stream<Integer> zurückgibt

    mapToInt(i -> i)
    
516
Pshemo

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

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

Dies erspart Ihnen die Zwischen-Array-Konvertierung, die Sie für das Commons Lang-Äquivalent benötigen.

194
ColinD

Am einfachsten geht das mit Apache Commons Lang . Es gibt eine praktische ArrayUtils-Klasse, die alles kann, was Sie wollen. Verwenden Sie die Methode toPrimitive mit der Überladung für ein Array von Integers.

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

Auf diese Weise erfinden Sie das Rad nicht neu. Commons Lang hat sehr viele nützliche Dinge, die Java weggelassen haben. Oben habe ich eine Ganzzahlliste mit der richtigen Größe erstellt. Sie können auch ein statisches Ganzzahl-Array der Länge 0 verwenden und Java ein Array der richtigen Größe zuweisen:

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

Mit Java 8 haben wir eine einfache Möglichkeit, dies über Streams zu tun ...

Mit der Funktion collections stream() und dem anschließenden Zuordnen zu ints erhalten Sie einen IntStream. Mit dem IntStream können wir toArray () aufrufen, was uns int [] gibt.

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

bis int []

zu IntStream

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

Geringe Änderung des Codes, um eine teure Indexierung der Liste zu vermeiden (da eine Liste nicht unbedingt eine ArrayList ist, sondern eine verknüpfte Liste sein kann, für die der wahlfreie Zugriff teuer ist)

50
Mike

Hier ist Java 8 einzeiliger Code dafür

public int[] toIntArray(List<Integer> intList){
       return intList.stream().mapToInt(Integer::intValue).toArray();
}
12
Noor Nawaz

Wenn Sie einfach ein Integer einem int zuordnen, sollten Sie nter Verwendung von Parallelität in Betracht ziehen, da Ihre Zuordnungslogik sich nicht auf Variablen außerhalb ihres Gültigkeitsbereichs stützt.

int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();

Sei dir dessen einfach bewusst

Beachten Sie, dass die Parallelität nicht automatisch schneller ist als die serielle Ausführung von Vorgängen. Dies kann jedoch der Fall sein, wenn Sie über genügend Daten und Prozessorkerne verfügen. Während Sie mit Aggregatoperationen Parallelität einfacher implementieren können, liegt es immer noch in Ihrer Verantwortung, zu bestimmen, ob Ihre Anwendung für Parallelität geeignet ist.


Es gibt zwei Möglichkeiten, Ganzzahlen ihrer primitiven Form zuzuordnen:

  1. Über ein ToIntFunction.

    mapToInt(Integer::intValue)
    
  2. Über explizites nboxing mit Lambda-Ausdruck.

    mapToInt(i -> i.intValue())
    
  3. Über implizites (Auto-) Unboxing mit Lambda-Ausdruck.

    mapToInt(i -> i)
    

Gegeben eine Liste mit einem null Wert

List<Integer> list = Arrays.asList(1, 2, null, 4, 5);

Es gibt drei Möglichkeiten, mit null umzugehen:

  1. Filtern Sie die null Werte heraus, bevor Sie sie zuordnen.

    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
  2. Ordnen Sie die null Werte einem Standardwert zu.

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. Behandle null innerhalb des Lambda-Ausdrucks.

    int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
    
7
Mr. Polywhirl

Ich werfe noch einen hier rein. Ich habe mehrere Verwendungen von for-Schleifen bemerkt, aber Sie brauchen nicht einmal etwas in der Schleife. Ich erwähne dies nur, weil die ursprüngliche Frage versuchte, weniger ausführlichen Code zu finden.

int[] toArray(List<Integer> list) {
    int[] ret = new int[ list.size() ];
    int i = 0;
    for( Iterator<Integer> it = list.iterator(); 
         it.hasNext(); 
         ret[i++] = it.next() );
    return ret;
}

Wenn Java wie C++ mehrere Deklarationen in einer for-Schleife zulässt, könnten wir einen Schritt weiter gehen und für (int i = 0, Iterator it ...

Am Ende jedoch (dieser Teil ist nur meine Meinung), wenn Sie eine Hilfsfunktion oder -methode haben, um etwas für Sie zu tun, richten Sie es einfach ein und vergessen Sie es. Es kann ein Einzeiler oder zehn sein; Wenn du es nie wieder betrachtest, wirst du den Unterschied nicht erkennen.

7
Loduwijk

Diese einfache Schleife ist immer richtig! keine Bugs

  int[] integers = new int[myList.size()];
  for (int i = 0; i < integers.length; i++) {
      integers[i] = myList.get(i);
  }
6
THANN Phearum

Es gibt wirklich keine Möglichkeit, das, was Sie versuchen, in einer Zeile zusammenzufassen, da toArray ein Objekt [] zurückgibt und Sie nicht von Object [] nach int [] oder Integer [] nach int [] umwandeln können.

5
neesh
int[] ret = new int[list.size()];       
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {       
    ret[i] = iter.next();                
}                                        
return ret;                              
4
gerardw

versuchen Sie auch Dollar ( überprüfen Sie diese Revision ):

import static com.humaorie.dollar.Dollar.*
...

List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
3
dfa

Mit Eclipse Collections können Sie Folgendes tun, wenn Sie eine Liste vom Typ Java.util.List<Integer> haben:

List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();

Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);

Wenn Sie bereits einen Eclipse-Sammlungstyp wie MutableList haben, können Sie Folgendes tun:

MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = integers.asLazy().collectInt(i -> i).toArray();

Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);

Hinweis: Ich bin ein Committer für Eclipse-Sammlungen

2
Donald Raab

Ich würde Ihnen empfehlen, die Skelettimplementierung List<?> aus der Java -Sammlungs-API zu verwenden. Dies scheint in diesem speziellen Fall sehr hilfreich zu sein:

package mypackage;

import Java.util.AbstractList;
import Java.util.Arrays;
import Java.util.Collections;
import Java.util.List;

public class Test {

//Helper method to convert int arrays into Lists
static List<Integer> intArrayAsList(final int[] a) {
    if(a == null)
        throw new NullPointerException();
    return new AbstractList<Integer>() {

        @Override
        public Integer get(int i) {
            return a[i];//autoboxing
        }
        @Override
        public Integer set(int i, Integer val) {
            final int old = a[i];
            a[i] = val;//auto-unboxing
            return old;//autoboxing
        }
        @Override
        public int size() {
            return a.length;
        }
    };
}

public static void main(final String[] args) {
    int[] a = {1, 2, 3, 4, 5};
    Collections.reverse(intArrayAsList(a));
    System.out.println(Arrays.toString(a));
}
}

Hüten Sie sich vor Nachteilen beim Boxen und beim Auspacken

1
DennisTemper

Mit einem Lambda könnten Sie dies tun (kompiliert in JDK Lambda):

public static void main(String ars[]) {
        TransformService transformService = (inputs) -> {
            int[] ints = new int[inputs.size()];
            int i = 0;
            for (Integer element : inputs) {
                ints[ i++ ] = element;
            }
            return ints;
        };

        List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };

        int[] results = transformService.transform(inputs);
    }

    public interface TransformService {
        int[] transform(List<Integer> inputs);
    }
0
NimChimpsky