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

to pytanie ma już odpowiedzi tutaj : Jak przekonwertować Arraylistę zawierającą liczby całkowite do prymitywnej tablicy int? (18 odpowiedzi) Zamknięty 2 lata temu.

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-06

16 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).
 235
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();
//OR
//int[] array = list.stream().mapToInt(Integer::intValue).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 zamiast wrappera Integer, ponieważ jego metoda toArray najprawdopodobniej zwróci również int[] array (returning coś innego jak Object[] lub nawet pudełko Integer[] byłoby tutaj nienaturalne). I na szczęście Java 8 ma taki strumień który jest 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. Proszę.Stream#mapToInt(ToIntFunction<? super T> mapper) metoda przychodzi na ratunek. Wszystko, co musimy zrobić, to przekazać do niego mapowanie z Integer do int. Możemy użyć czegoś w rodzaju Integer#intValue, które zwraca int Jak :

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

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

Ale podobny kod można wygenerować 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)

Również od Integer Wpisz w (Integer i) można wywnioskować przez kompilator, ponieważ List<Integer>#stream() zwraca Stream<Integer> możemy również pominąć, co pozostawia nam z

    mapToInt(i -> i)
 792
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
2020-12-03 16:40:16

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.

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

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

 67
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
2018-11-07 05:55:51
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)

 55
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

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

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

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

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.

 7
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

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 []

 5
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
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

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

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

 2
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

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

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