Как преобразовать List <Integer> в int [] в Java?

Это похоже на этот вопрос: Как преобразовать int [] в Integer [] в Java?

Я новичок в Java. Как преобразовать List<Integer> в int[] в Java? Я запутался, потому что List.toArray() фактически возвращает Object[], который может быть отброшен в nether Integer[] или int[].

Сейчас я использую цикл для этого:

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

Я уверен, что есть лучший способ сделать это.

Ответ 1

К сожалению, я не верю, что действительно лучший способ сделать это из-за характера обработки Java примитивных типов, бокса, массивов и дженериков. В частности:

  • List<T>.toArray не будет работать, потому что нет преобразования от Integer до int
  • Вы не можете использовать int как аргумент типа для дженериков, поэтому он должен был быть int -специфическим методом (или тем, который использовал отражение, чтобы делать неприятные обманки).

Я считаю, что есть библиотеки, у которых есть автогенерированные версии этого типа метода для всех примитивных типов (т.е. есть шаблон, который копируется для каждого типа). Это уродливо, но так, как я боюсь: (

Несмотря на то, что класс Arrays вышел до того, как дженерики прибыли на Java, все равно пришлось бы включать все ужасные перегрузки, если бы это было (предполагается, что вы хотите использовать примитивные массивы).

Ответ 2

Никто еще не упомянул потоки, добавленные в Java 8, так что вот так:

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

Процесс мышления:

  • simple Stream#toArray возвращает Object[], поэтому это не то, что мы хотим. Также Stream#toArray(IntFunction<A[]> generator) не делает то, что мы хотим, потому что универсальный тип A не может представлять примитив int
  • поэтому было бы неплохо иметь некоторый поток, который мог бы обрабатывать примитивный тип int вместо оболочки Integer, потому что его метод toArray, скорее всего, также будет возвращать массив int[] (возвращая что-то еще, например Object[] или даже в штучной упаковке) Integer[] было бы неестественно здесь). И, к счастью, в Java 8 есть такой поток, который IntStream
  • так что теперь единственное, что нам нужно выяснить, - это как преобразовать наш Stream<Integer> (который будет возвращен из list.stream()) в этот блестящий IntStream. Здесь Stream#mapToInt(ToIntFunction<? super T> mapper) метод приходит на помощь. Все, что нам нужно сделать, это перейти к отображению с Integer на int. Мы могли бы использовать что-то вроде Integer#getValue, которое возвращает int, например:

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

    (или если кто-то предпочитает mapToInt(Integer::intValue))

    но подобный код может быть сгенерирован с использованием распаковки, так как компилятор знает, что результатом этой лямбды должен быть int (лямбда в mapToInt - это реализация интерфейса ToIntFunction, который ожидает тело для метода int applyAsInt(T value), который, как ожидается, вернет int ]).

    Таким образом, мы можем просто написать

    mapToInt((Integer i)->i)
    

    Также, поскольку тип Integer в (Integer i) может быть выведен компилятором, поскольку List<Integer>#stream() возвращает Stream<Integer>, мы можем также пропустить его, что оставляет нас с

    mapToInt(i -> i)
    

Ответ 3

В дополнение к Commons Lang вы можете сделать это с помощью Guava method Ints.toArray(Collection<Integer> collection):

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

Это избавляет вас от необходимости делать промежуточное преобразование массива, которое требует эквивалент Commons Lang.

Ответ 4

Самый простой способ сделать это - использовать Apache Commons Lang. У этого есть удобный класс ArrayUtils, который может делать то, что Вы хотите. Используйте метод toPrimitive с перегрузкой для массива Integer s.

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

Таким образом, вы не изобретаете велосипед. В Commons Lang есть много полезных вещей, которые Java забыл. Выше я решил создать список целых чисел нужного размера. Вы также можете использовать статический целочисленный массив длиной 0 строк и позволить Java выделять массив нужного размера:

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

Ответ 5

Java 8 дала нам простой способ сделать это с помощью потоков...

Используя функцию collection stream(), а затем сопоставляя ее с int, вы получите IntStream. С помощью IntStream мы можем вызвать toArray(), который дает нам int []

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

к int []

в IntStream

Ответ 6

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

Незначительное изменение кода, чтобы избежать дорогостоящей индексации списка (поскольку список не обязательно является ArrayList, но может быть связанным списком, для которого случайный доступ дорог)

Ответ 7

Вот Java 8 однострочный код для этого

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

Ответ 8

Я брошу еще один здесь. Я заметил несколько применений для циклов, но вам даже не нужно ничего внутри цикла. Я упоминаю об этом только потому, что исходный вопрос пытался найти менее подробный код.

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

Если Java допускает множественные объявления в цикле for, как это делает С++, мы могли бы сделать еще один шаг и сделать для (int я = 0, Iterator it...

В конце концов, хотя (эта часть - только мое мнение), если у вас будет функция помощи или метод, чтобы что-то сделать для вас, просто установите ее и забудьте об этом. Это может быть один лайнер или десять; если вы никогда не посмотрите на это снова, вы не узнаете разницу.

Ответ 9

Если вы просто сопоставляете Integer с int вам следует рассмотреть возможность использования параллелизма, поскольку ваша логика отображения не полагается на какие-либо переменные за пределами ее области.

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

Просто знайте об этом

Обратите внимание, что параллелизм не выполняется автоматически быстрее, чем выполнение операций поочередно, хотя это может быть, если у вас достаточно данных и процессорных ядер. Хотя агрегированные операции позволяют вам более легко реализовать параллелизм, вы по-прежнему несете ответственность за определение того, подходит ли ваше приложение для параллелизма.


Существует два способа сопоставления целых чисел с их примитивной формой:

  1. Через функцию ToIntFunction.

    mapToInt(Integer::intValue)
    
  2. С помощью явного unboxing с выражением лямбда.

    mapToInt(i -> i.intValue())
    
  3. Через неявный (auto-) unboxing с выражением лямбда.

    mapToInt(i -> i)
    

Учитывая список с null значением

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

Вот три параметра для обработки null:

  1. Отфильтруйте null значения перед отображением.

    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
  2. Сопоставьте null значения со значением по умолчанию.

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. Обработать null внутри выражения лямбда.

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

Ответ 10

Этот простой цикл всегда правильный! нет ошибок

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

Ответ 11

Нет никакого способа "однострочного" того, что вы пытаетесь сделать, потому что toArray возвращает объект [], и вы не можете отбрасывать из Object [] в int [] или Integer [] в int []

Ответ 12

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

Ответ 14

С Eclipse Collections вы можете сделать следующее, если у вас есть список типов 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);

Если у вас уже есть тип Eclipse Collections, например MutableList, вы можете сделать следующее:

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

Примечание: я являюсь коммиттером для коллекций Eclipse

Ответ 15

Я бы порекомендовал вам использовать List<?> скелетную реализацию из API-интерфейсов java, в этом конкретном случае он весьма полезен:

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

Остерегайтесь недостатков бокса/распаковки

Ответ 16

Используя лямбда, вы можете сделать это (компилируется в 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);
    }

Ответ 17

@Override
public int findArray(int[] array, int[] subArray) {

    Map<Integer, Integer> map = new LinkedHashMap();
    int index = -1;
    boolean flag = false;
    for (int i = 0; i < subArray.length; i++) {
        flag=false;
        for (int j = 0; j < array.length; j++) {
            if (subArray[i]==array[j]) {
                map.put(subArray[i], j);
                flag = true;
            }   
        }
    }
    if (flag) {
        Map.Entry<Integer, Integer> entry = map.entrySet().iterator().next();
        index = entry.getValue();
    }

    return index;
}