Як перетворити int [] у Список <Integer> на Java?


382

Як перетворити int[]на List<Integer>Java?

Звичайно, мене цікавить будь-яка інша відповідь, ніж це робити в циклі, пункт за пунктом. Але якщо іншої відповіді немає, я виберу цю як найкращу, щоб показати той факт, що ця функціональність не є частиною Java.


Ми можемо скористатись IntStream.Of (array) .collect (Collectors.toList)
Saroj Kumar Sahoo

Відповіді:


259

Не існує ярлика для переходу int[]на, List<Integer>оскільки Arrays.asListне займається боксом, а просто створить, List<int[]>що не є тим, що ви хочете. Ви повинні зробити корисний метод.

int[] ints = {1, 2, 3};
List<Integer> intList = new ArrayList<Integer>(ints.length);
for (int i : ints)
{
    intList.add(i);
}

32
Найкраще ініціалізувати список за розміром масиву
Девід Рабіновіц

110
для (int i: ints) intList.add (i);
Стівен Денне

18
@willcodejavaforfood - Девід означає, що це краще: новий ArrayList <Integer> (ints.length);
Стівен Денне

12
@willcodejavaforfood: оголошення розміру ArrayList під час його створення буде перешкоджати внутрішньому розміру після додавання певної суми. Не впевнений, чи користь невелика, але виразно є користь.
Grundlefleck

10
new ArrayList<Integer>() {{ for (int i : ints) add(i); }}
saka1029

350

Потоки

У Java 8 ви можете це зробити

int[] ints = {1,2,3};
List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());

21
Еквівалентно: Arrays.stream (ints) .boxed (). Collection (Collectors.toList ());
njfrost

4
@njfrost Ви маєте рацію, а IntStream.of просто дзвонить у Arrays.stream, тому я покращив відповідь за вашою пропозицією
mikeyreilly

Чомусь це, здається, не повертає очікуваного типу результату на Android Studio (працює на затемнення). У ньому йдеться про очікуваний список <Integer> знайдений Список <Object>.
Євгеніо Лопес

Це виглядає чисто і лаконічно, але коли я використовував це на відміну від основного рішення, яке надає @willcodejavaforfood на leetcode, продуктивність програми знизилася як з точки зору пам’яті, так і часу виконання
chitresh sirohi

@chitreshsirohi, це тому, що лямбда-функції, які використовуються всередині потоків, призводять до того, що Java створює деякі анонімні класи.
Ашвін Шарма

175

Також із бібліотек guava ... com.google.common.primitive.Ints:

List<Integer> Ints.asList(int...)

11
Це має бути правильною відповіддю. Дивіться друге речення запитання: "Звичайно, мене цікавить будь-яка інша відповідь, ніж це робити в циклі, пункт за пунктом".
джоскетрес

Дякую, дякую, дякую! Також працює для Longs.asList (довгий ...).
craastad

2
Тут є кілька тонкощів. Повернений список використовує наданий масив як резервне зберігання, тому вам не слід мутувати масив. Список також не гарантує ідентичність об'єктів Integer, що містяться. Тобто, результат list.get (0) == list.get (0) не вказаний.
pburka

1
Слідкуйте за підрахунком методу для Android при додаванні бібліотек. Хоча хороша знахідка.
milosmns

95

Arrays.asList не працюватиме, як очікують деякі інші відповіді.

Цей код не створить список з 10 цілих чисел. Він надрукує 1 , а не 10 :

int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List lst = Arrays.asList(arr);
System.out.println(lst.size());

Це створить список цілих чисел:

List<Integer> lst = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

Якщо у вас вже є масив ints, не існує швидкого способу перетворення, вам краще скористатися циклом.

З іншого боку, якщо у вашому масиві є об'єкти, а не примітиви, Arrays.asList буде працювати:

String str[] = { "Homer", "Marge", "Bart", "Lisa", "Maggie" };
List<String> lst = Arrays.asList(str);

2
Зауважте, що цей список незмінний
Даніельсон,

51

Я додам ще одну відповідь іншим методом; не цикл, а анонімний клас, який використовуватиме функції автобоксингу:

public List<Integer> asList(final int[] is)
{
    return new AbstractList<Integer>() {
            public Integer get(int i) { return is[i]; }
            public int size() { return is.length; }
    };
}

1
+1 це коротше, ніж у мене, але шахта працює для всіх примітивів
dfa

5
Хоча швидше і використовується менше пам'яті, ніж створення ArrayList, компроміс List.add (), а List.remove () не працює.
Стівен Денне

3
Мені дуже подобається це рішення для великих масивів із обмеженими шаблонами доступу, але для елементів, які часто отримують доступ, це призведе до багатьох непотрібних інстанцій Integer (наприклад, якщо ви зверталися до одного і того ж елемента 100 разів). Також вам потрібно буде визначити Iterator та обернути повернене значення у Collections.unmodifiableList.
Адамські

@Christoffer дякую. Я додав setметод, і тепер я навіть можу сортувати масив ...
freedev

39

Найменший шматок коду буде:

public List<Integer> myWork(int[] array) {
    return Arrays.asList(ArrayUtils.toObject(array));
}

звідки ArrayUtils походить від commons-lang :)


9
Зауважте ArrayUtilsлише, що це відносно велика бібліотека для програми для Android
msysmilu

Тут описано зворотну операцію: ключ є stackoverflow.com/a/960507/1333157 ArrayUtils.toPrimitive(...) .
ZeroOne

26

У Java 8 із потоком:

int[] ints = {1, 2, 3};
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, Arrays.stream(ints).boxed().toArray(Integer[]::new));

або з колекціонерами

List<Integer> list =  Arrays.stream(ints).boxed().collect(Collectors.toList());

3
Чому б просто не використовувати колектор?
Ассілія


16

Якщо ви використовуєте java 8, ми можемо використовувати API потоку для перетворення його у список.

List<Integer> list = Arrays.stream(arr)     // IntStream 
                                .boxed()        // Stream<Integer>
                                .collect(Collectors.toList());

Ви також можете використовувати IntStream для конвертації.

List<Integer> list = IntStream.of(arr) // return Intstream
                                    .boxed()        // Stream<Integer>
                                    .collect(Collectors.toList());

Є й інші зовнішні бібліотеки, такі як guava та apache commons.

ура.


11

Також варто перевірити цей звіт про помилку , закритий причиною "Не дефект" та наступним текстом:

"Автобоксинг цілих масивів не є визначеною поведінкою з поважної причини. Це може бути надзвичайно дорогим для великих масивів."


7

спробуйте цей клас:

class PrimitiveWrapper<T> extends AbstractList<T> {

    private final T[] data;

    private PrimitiveWrapper(T[] data) {
        this.data = data; // you can clone this array for preventing aliasing
    }

    public static <T> List<T> ofIntegers(int... data) {
        return new PrimitiveWrapper(toBoxedArray(Integer.class, data));
    }

    public static <T> List<T> ofCharacters(char... data) {
        return new PrimitiveWrapper(toBoxedArray(Character.class, data));
    }

    public static <T> List<T> ofDoubles(double... data) {
        return new PrimitiveWrapper(toBoxedArray(Double.class, data));
    }  

    // ditto for byte, float, boolean, long

    private static <T> T[] toBoxedArray(Class<T> boxClass, Object components) {
        final int length = Array.getLength(components);
        Object res = Array.newInstance(boxClass, length);

        for (int i = 0; i < length; i++) {
            Array.set(res, i, Array.get(components, i));
        }

        return (T[]) res;
    }

    @Override
    public T get(int index) {
        return data[index];
    }

    @Override
    public int size() {
        return data.length;
    }
}

перевірка:

List<Integer> ints = PrimitiveWrapper.ofIntegers(10, 20);
List<Double> doubles = PrimitiveWrapper.ofDoubles(10, 20);
// etc

5

Найкращий знімок:

**
 * Integer modifiable fix length list of an int array or many int's.
 *
 * @author Daniel De Leon.
 */
public class IntegerListWrap extends AbstractList<Integer> {

    int[] data;

    public IntegerListWrap(int... data) {
        this.data = data;
    }

    @Override
    public Integer get(int index) {
        return data[index];
    }

    @Override
    public Integer set(int index, Integer element) {
        int r = data[index];
        data[index] = element;
        return r;
    }

    @Override
    public int size() {
        return data.length;
    }
}
  • Підтримка та отримання.
  • Немає дублювання даних пам'яті.
  • Не витрачайте часу на петлі.

Приклади:

int[] intArray = new int[]{1, 2, 3};
List<Integer> integerListWrap = new IntegerListWrap(intArray);
List<Integer> integerListWrap1 = new IntegerListWrap(1, 2, 3);

Мені це подобається найбільше. Але я все-таки використовую гуаву, щоб мати пряме рішення :)
dantuch


1
   /* Integer[] to List<Integer> */



        Integer[] intArr = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
        List<Integer> arrList = new ArrayList<>();
        arrList.addAll(Arrays.asList(intArr));
        System.out.println(arrList);


/* Integer[] to Collection<Integer> */


    Integer[] intArr = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
    Collection<Integer> c = Arrays.asList(intArr);


1

Ось рішення:

int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

Integer[] iArray = Arrays.stream(array).boxed().toArray(Integer[]::new);
System.out.println(Arrays.toString(iArray));

List<Integer> list = new ArrayList<>();
Collections.addAll(list, iArray);
System.out.println(list);

Вихід:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1

Ось ще одна можливість знову з Java 8 Streams:

void intArrayToListOfIntegers(int[] arr, List<Integer> list) {
    IntStream.range(0, arr.length).forEach(i -> list.add(arr[i]));
}

0

Ось загальний спосіб перетворення масиву в ArrayList

<T> ArrayList<T> toArrayList(Object o, Class<T> type){
    ArrayList<T> objects = new ArrayList<>();
    for (int i = 0; i < Array.getLength(o); i++) {
        //noinspection unchecked
        objects.add((T) Array.get(o, i));
    }
    return objects;
}

Використання

ArrayList<Integer> list = toArrayList(new int[]{1,2,3}, Integer.class);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.