2013-07-08 4 views
17

Widziałem pytanie: Create ArrayList from arrayJak utworzyć ArrayList (ArrayList <Integer>) z tablicy (int []) w Javie

Jednak gdy próbuję to rozwiązanie z następującego kodu, to nie dość pracy we wszystkich skrzynie:

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Collection; 
import java.util.List; 

public class ToArrayList { 

    public static void main(String[] args) { 
     // this works 
     String[] elements = new String[] { "Ryan", "Julie", "Bob" }; 
     List<String> list = new ArrayList<String>(Arrays.asList(elements)); 
     System.out.println(list); 

     // this works 
     List<Integer> intList = null; 
     intList = Arrays.asList(3, 5); 
     System.out.println(intList); 

     int[] intArray = new int[] { 0, 1 }; 
     // this doesn't work! 
     intList = new ArrayList<Integer>(Arrays.asList(intArray)); 
     System.out.println(intList); 
    } 
} 

Co ja tu robię źle? Czy kod intList = new ArrayList<Integer>(Arrays.asList(intArray)); nie powinien być kompilowany?

+0

Dzięki za wszystkie odpowiedzi. Znalazłem kilka przyczyn tego błędu kompilacji: 1. Java nie tworzy prymitywnych tablic autobox. 2. Varargs są skomplikowane w poprawnym użyciu - http://stackoverflow.com/questions/2925153/can-i-pass-an-array-as-arguments-to-a-method-with-variable-arguments-in-java/2926653 # 2926653 – tuxdna

+0

+1 To jest dobre pytanie. Polecam każdemu, kto czyta go, aby przeczytać wszystkie odpowiedzi, wszystkie dodają ważne informacje. – DaveM

Odpowiedz

21

Problemem

intList = new ArrayList<Integer>(Arrays.asList(intArray)); 

jest int[] jest uważane za jeden Object przykład od pierwotną Tablica rozciąga się od Object. To zadziała, jeśli masz Integer[] zamiast int[], ponieważ teraz wysyłasz tablicę z Object.

Integer[] intArray = new Integer[] { 0, 1 }; 
//now you're sending a Object array 
intList = new ArrayList<Integer>(Arrays.asList(intArray)); 

Z Twojego komentarza: jeśli chcesz nadal korzystać z int[] (lub inny typ pierwotny tablicę) jako główny danych, to trzeba utworzyć dodatkową tablicę z klasy otoki. Na tym przykładzie:

int[] intArray = new int[] { 0, 1 }; 
Integer[] integerArray = new Integer[intArray.length]; 
int i = 0; 
for(int intValue : intArray) { 
    integerArray[i++] = intValue; 
} 
intList = new ArrayList<Integer>(Arrays.asList(integerArray)); 

Ale skoro jesteś już przy użyciu for pętlę, ja nie miałbym nic przeciwko użyciu tablicę klasy otoki temp, wystarczy dodać swoje przedmioty bezpośrednio do listy:

int[] intArray = new int[] { 0, 1 }; 
intList = new ArrayList<Integer>(); 
for(int intValue : intArray) { 
    intList.add(intValue); 
} 
+0

Dzięki za odpowiedź. Jak mogę przekonwertować tablicę prymitywną na tablicę w ramce zamiast tworzyć nową (np. Nie używając pętli)? Czekam tylko na kompaktowy fragment kodu, którego mogę użyć. – tuxdna

7

To nie działa, ponieważ używasz int[] zamiast Integer[]. Wypróbuj to:

Integer[] intArray = new Integer[] { 0, 1 }; 
// this should work now 
intList = new ArrayList<Integer>(Arrays.asList(intArray)); 
3

Kolekcja chce Obiekty i prymitywy nie pochodzą z Object. więc Integer zezwala, ale int nie jest dozwolone.

Więc musisz użyć klasy opakowania Integer zamiast int, która jest typem pierwotnym.

Wystarczy przykład:

Integer[] intArray = new Integer[] { 0, 1 }; 
intList = new ArrayList<Integer>(Arrays.asList(intArray)); 
6

Problem jest o autoboxing. Java automatycznie konwertuje automatycznie int na Integer, ale nie konwertuje ona int[] na Integer[]. Stąd przyczyna.

public static <T> List<T> asList(T... a) 

jest zdefiniowany jak powyżej. Oczekuje on vararg typu T. tj. może przyjmować tablicę obiektów typu T. W twoim przypadku, ponieważ Java nie może przekonwertować int[] na Integer[], dlatego przyjmuje typ T jako int[] zamiast Integer zgodnie z potrzebami. Stąd otrzymujesz listę typu List<int[]. Będziesz musiał ręcznie przekształcić go w `Integer[] z int[]

Jest to doskonała pozycja w książce Effective Java przez Joshua Bloch gdzie wyjaśnia doły z varargs i to jest jeden z nich.

8

Z Java 8 można zrobić to w jednym wierszu:

   
int[] intArr = { 1, 1, 2, 3, 5, 8, 11}; 
List<Integer> list = Arrays.stream(intArr).boxed().collect(Collectors.toList()); 
list.forEach(System.out::println);