Jak przekonwertować listę do int [] w Javie?

To jest podobne do tego pytania: Jak przekonwertować int [] na Integer [] w Javie?

Jestem nowy w Javie. Jak mogę przekonwertować List<Integer> na int[] w Javie? Jestem zdezorientowany, ponieważ List.toArray() w rzeczywistości zwraca Object[], które można rzucić do nether Integer[] lub int[].

W tej chwili używam do tego pętli:

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;
}
Na pewno jest na to lepszy sposób.
Author: Community, 2009-06-07

17 answers

Niestety, nie wierzę, że naprawdę jest lepszym sposobem na zrobienie tego ze względu na naturę obsługi prymitywnych typów, boksu, tablic i generyków w Javie. W szczególności:

  • List<T>.toArray nie zadziała, ponieważ nie ma konwersji z Integer na int
  • nie możesz używać int jako argumentu typu dla generyków, więc ma być metodą specyficzną dla int (lub taką, która używała refleksji do wykonywania paskudnych sztuczek).

Wierzę, że są biblioteki, które mają autogenerowane wersje tego rodzaju metody dla wszystkich typów prymitywnych (tzn. istnieje szablon, który jest kopiowany dla każdego typu). Jest brzydki, ale tak jest niestety: (

/ Align = "left" / Arrays klasa wyszła przed pojawieniem się generyków w Javie, nadal musiałaby zawierać wszystkie straszne przeciążenia, gdyby została wprowadzona dzisiaj (zakładając, że chcesz używać prymitywnych tablic).
 176
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-06 20:28:18

Nikt jeszcze nie wspomniał o streamach dodanych w Javie 8 więc zaczyna się:

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

Proces myślowy:

  • proste Stream#toArray zwraca Object[], więc nie jest to to, czego chcemy. Również Stream#toArray(IntFunction<A[]> generator) nie robi tego, co chcemy, ponieważ Typ generyczny A nie może reprezentować prymitywnego int
  • więc byłoby miło mieć jakiś strumień, który mógłby obsłużyć prymitywny typ int, ponieważ jego metoda toArray najprawdopodobniej zwróci również int[] array (zwracając coś innego jak Object[] lub nawet boxed Integer[] byłoby tu nienaturalne). A na szczęście Java 8 ma taki stream: IntStream
  • Więc teraz musimy tylko dowiedzieć się, jak przekształcić nasze Stream<Integer> (które zostaną zwrócone z list.stream()) do tego błyszczącego IntStream. Tutaj mapToInt metoda przychodzi na ratunek. Wszystko, co musimy zrobić, to dostarczyć kilka map z Integer do int. Możemy użyć czegoś w rodzaju Integer#getValue, które zwraca int:

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

    (lub jeśli ktoś woli mapToInt(Integer::intValue))

    Ale podobny kod może być generowane za pomocą unboxingu, ponieważ kompilator wie, że wynikiem tego lambda musi być int (lambda w mapToInt jest implementacją interfejsu ToIntFunction, który oczekuje body dla metody int applyAsInt(T value), która ma zwracać int).

    Więc możemy po prostu napisać

    mapToInt((Integer i)->i)

    Lub prostsze (ponieważ Typ Integer i można wywnioskować przez kompilator, ponieważ List<Integer>#stream() zwraca Stream<Integer>)

    mapToInt(i -> i)

 414
Author: Pshemo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-17 17:16:34

Oprócz Commons Lang można to zrobić za pomocą metody GuavaInts.toArray(Collection<Integer> collection):

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

Pozwala to uniknąć konieczności pośredniej konwersji tablicy, której wymaga odpowiednik Commons Lang.

 185
Author: ColinD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-17 05:35:01

Najprostszym sposobem na to jest użycie Apache Commons Lang . Ma poręczną klasę ArrayUtils, która może robić to, co chcesz. Użyj toPrimitive metoda z przeciążeniem dla tablicy Integer s.

List<Integer> myList;
 ... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));
W ten sposób nie odkryjesz koła na nowo. Commons Lang ma wiele przydatnych rzeczy, które Java pominęła. Powyżej wybrałem utworzenie listy całkowitej o odpowiednim rozmiarze. Można również użyć statycznej tablicy całkowitej o długości 0 i pozwolić Javie przydzielić tablicę z prawej rozmiar:
static final Integer[] NO_INTS = new Integer[0];
   ....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));
 166
Author: Eddie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-14 08:09:35
int[] toIntArray(List<Integer> list)  {
    int[] ret = new int[list.size()];
    int i = 0;
    for (Integer e : list)  
        ret[i++] = e;
    return ret;
}

Niewielka zmiana kodu, aby uniknąć kosztownego indeksowania listy (ponieważ lista niekoniecznie jest Arraylistą, ale może być listą połączoną, dla której dostęp losowy jest drogi)

 47
Author: Cheok Yan Cheng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-28 05:34:42

Java 8 dała nam łatwy sposób, aby to zrobić za pomocą strumieni...

Używając funkcji collections stream(), a następnie mapując do ints, otrzymasz strumień IntStream. Za pomocą IntStream możemy wywołać ToArray () co daje nam int []

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

Do int []

Do IntStream

 30
Author: Pumphouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-09 04:30:02

Oto Java 8 pojedynczy kod do tego

public int[] toIntArray(List<Integer> intList){
       return intList.stream().mapToInt(Integer::intValue).toArray();
}
 12
Author: Noor Nawaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-11 10:38:14

Dorzucę jeszcze jednego. Zauważyłem kilka zastosowań pętli for, ale nie potrzebujesz nawet niczego wewnątrz pętli. Wspominam o tym tylko dlatego, że oryginalne pytanie starało się znaleźć mniej gadatliwy kod.

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

Jeśli Java zezwala na wiele deklaracji w pętli for, tak jak robi to C++, możemy pójść o krok dalej i zrobić for (int i = 0, Iterator it...

W końcu jednak (ta część jest tylko moim zdaniem), jeśli masz zamiar mieć pomocną funkcję lub metodę, aby coś zrobić dla ciebie, po prostu ustaw to i zapomnij o tym. Może to być jednolinijkowy lub dziesięć; jeśli nigdy więcej na to nie spojrzysz, nie poznasz różnicy.

 6
Author: Loduwijk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-11 15:30:17

Ta prosta pętla jest zawsze poprawna! brak błędów

  int[] integers = new int[myList.size()];
  for (int i = 0; i < integers.length; i++) {
      integers[i] = myList.get(i);
  }
 6
Author: THANN Phearum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-31 08:04:25

Jeśli po prostu odwzorowujesz Integer na int, powinieneś rozważyć używając paralelizmu, ponieważ twoja logika mapowania nie opiera się na żadnych zmiennych spoza jej zakresu.

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

Bądź tego świadomy

Zauważ, że równoległość nie jest automatycznie szybsza niż wykonywanie operacji seryjnie, chociaż może być, jeśli masz wystarczającą ilość danych i rdzeni procesora. Podczas gdy operacje agregacyjne umożliwiają łatwiejsze wdrożenie równoległości, nadal jest to twoja odpowiedzialność za ustalenie, czy Twoja aplikacja jest odpowiednia do równoległości.


Istnieją dwa sposoby mapowania liczb całkowitych do ich prymitywnej formy:

  1. Przez ToIntFunction.

    mapToInt(Integer::intValue)
    
  2. Poprzez explicit unboxing z wyrażeniem lambda.

    mapToInt(i -> i.intValue())
    
  3. Poprzez implicit (auto-) unboxing z wyrażeniem lambda.

    mapToInt(i -> i)
    

Podano listę z null wartością

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

Oto trzy opcje do obsługi null:

  1. Filtruj null wartości przed mapowaniem.

    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
  2. Mapuj wartości null na wartość domyślną.

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. Uchwyt null wewnątrz wyrażenia lambda.

    int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
    
 5
Author: Mr. Polywhirl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-30 12:54:40
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
Author: gerardw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-03 19:08:23

Naprawdę nie ma możliwości "jednokierunkowego" tego, co próbujesz zrobić, ponieważ ToArray zwraca obiekt [] i nie możesz rzucić z obiektu[] do int [] lub Integer [] do int []

 3
Author: neesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-06 20:39:03

Spróbuj również Dolar (Sprawdź tę wersję):

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

List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
 3
Author: dfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-05 14:40:20

Z kolekcjami Eclipse , możesz wykonać następujące czynności, jeśli masz listę typu java.util.List<Integer>:

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

Jeśli masz już Kolekcje Eclipse typu MutableList, możesz wykonać następujące czynności:

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

Uwaga: jestem committerem Dla Kolekcji Eclipse

 2
Author: Donald Raab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-01 19:32:47

Począwszy od java 8 można to łatwo osiągnąć za pomocą Stream API

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

Jeśli chcesz uzyskać więcej informacji o tym, jak ten proces jest zakończony id Lubię przekierować cię do tego linku http://www.techiedelight.com/convert-stream-array-java/#2

 2
Author: Milad Masoodi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-16 10:07:49

Zalecałbym użycieList<?> szkieletowej implementacji z API kolekcji java, wydaje się to być bardzo pomocne w tym konkretnym przypadku:

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

Uwaga na wady boksu/unboxingu

 1
Author: DennisTemper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-09 10:03:56

Używając lambda możesz to zrobić (kompiluje w 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
Author: NimChimpsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-24 16:13:39