Подтвердить что ты не робот

Эффективный способ преобразования List <Integer> в int [] (массив) без итерации

  public static int[] convertListToArray(List<Integer> listResult) {
        int[] result = new int[listResult.size()];
        int i= 0;
        for (int num : listResult) {
            result[i++] = num;
        }
        return result;
    }

Есть ли эффективный способ преобразования списка в массив без итерации списка явно? Возможно, это возможно с помощью таких методов, как:

Arrays.copyOf(int [] origin , int newLength );
System.arraycopy(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                    int length);

Я знаю, что здесь описано решение . Однако мне особенно интересен эффективный способ преобразования List<Integer> в int[]

4b9b3361

Ответ 1

Учитывая необходимость конвертировать из Integer в int, я не думаю, что вы найдете что-то более эффективное, чем то, что у вас есть, если я предполагаю, что вы говорите об эффективности выполнения.

Вы могли находить преобразование в Integer[], а затем цикл может быть более эффективным (ниже), но вы можете не. Вам придется протестировать его в своем конкретном сценарии и посмотреть.

Вот пример:

int size = listResult.size();
int[] result = new int[size];
Integer[] temp = listResult.toArray(new Integer[size]);
for (int n = 0; n < size; ++n) {
    result[n] = temp[n];
}

Ответ 2

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

public static int[] convertListToArray(List<Integer> listResult) {
    int size = listResult.size();
    int[] result = new int[size];
    if (listResult instanceof RandomAccess)
    {
        for (int i = 0; i < size; i++)
        {
            result[i] = listResult.get(i);
        }
    }
    else
    {
        int i = 0;
        for (int num : listResult) {
            result[i++] = num;
        }
    }
    return result;
}

Если вы используете Java 8 и хотите писать меньше кода, вы можете использовать библиотеку Streams.

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int[] array = list.stream().mapToInt(i -> i).toArray();

Если вы открыты для использования сторонней библиотеки, вы можете Eclipse Collections следующим образом.

MutableList<Integer> list = Lists.mutable.with(1, 2, 3, 4, 5);
int[] array = list.collectInt(i -> i).toArray();

Ниже приведен немного больше кода, но это наиболее эффективное решение, которое я мог бы использовать с помощью Eclipse Collections.

MutableList<Integer> list = Lists.mutable.with(1, 2, 3, 4, 5);
int[] array = new int[list.size()];
list.forEachWithIndex((each, index) -> array[index] = each);

Если вам нужно использовать интерфейс java.util.List, из коллекций Eclipse Collections можно использовать ListIterate.

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int[] array = new int[list.size()];
ListIterate.forEachWithIndex(list, (each, index) -> array[index] = each);

Утилита ListIterate будет использовать другой код итерации для списков RandomAccess и не RandomAccess.

Наиболее эффективной задачей было бы изменить List<Integer> на MutableIntList в коллекциях Eclipse или в другой библиотеке, поддерживающей для примитивных коллекций.

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

Ответ 3

В Java 8:

int[] anArray = list.stream()
                    .filter(Objects::nonNull)
                    .mapToInt(Integer::intValue)
                    .toArray();