Как передать ArrayList в параметр метода varargs?

237

В основном у меня есть ArrayList мест:

ArrayList<WorldLocation> locations = new ArrayList<WorldLocation>();

ниже этого я называю следующий метод:

.getMap();

параметры в методе getMap ():

getMap(WorldLocation... locations)

У меня проблема в том, что я не уверен, как перейти из ВСЕГО списка locationsв этот метод.

я пробовал

.getMap(locations.toArray())

но getMap не принимает это, потому что не принимает Objects [].

Теперь, если я использую

.getMap(locations.get(0));

это будет работать отлично ... но мне нужно как-то передать ВСЕ места ... Я, конечно, мог бы продолжать добавлять locations.get(1), locations.get(2)и т.д., но размер массива варьируется. Я просто не пользуюсь всей концепциейArrayList

Какой самый простой способ это сделать? Я чувствую, что сейчас не думаю прямо.

MJ93
источник

Ответы:

341

Исходная статья: Передача списка в качестве аргумента методу vararg


Используйте toArray(T[] arr)метод.

.getMap(locations.toArray(new WorldLocation[locations.size()]))

( toArray(new WorldLocation[0])также работает, но вы бы выделяли массив нулевой длины без причины.)


Вот полный пример:

public static void method(String... strs) {
    for (String s : strs)
        System.out.println(s);
}

...
    List<String> strs = new ArrayList<String>();
    strs.add("hello");
    strs.add("wordld");

    method(strs.toArray(new String[strs.size()]));
    //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
aioobe
источник
1
Насколько дорогой будет эта операция с точки зрения памяти и скорости?
читатель разума
Это не будет работать без предупреждения, если есть дополнительные шаблоны. Например someMethod(someList.toArray(new ArrayList<Something>[someList.size()])), вы получите предупреждение, которое очень раздражает, если функция имеет длину более нескольких строк (потому что вы можете либо подавить ее для всей функции, либо вам нужно создать массив на дополнительном шаге и отключить предупреждение для переменной, которую вы сохраните его
Qw3ry
23
По-видимому, самый быстрый подход - дать размер нуля, а не размер массива. Короче говоря, это потому, что константа времени компиляции позволяет использовать оптимизированный метод. shipilev.net/blog/2016/arrays-wisdom-ancients
ГЕГ
2
@JoshM. Яве нужно много вещей. ;) Я также (исходя из фона C #) скучаю по операторам индекса. Работать со словарями в C # гораздо проще, чем с HashMaps в Java.
За Лундберг
@PerLundberg - Полностью согласен. Также в основном разработчик C # в настоящее время работает с Java8. Может быть, 10/11 будет лучше. :-P
Джош М.
42

В Java 8:

List<WorldLocation> locations = new ArrayList<>();

.getMap(locations.stream().toArray(WorldLocation[]::new));
jmhostalet
источник
2
это ява вуду, но лучше ява (8) вуду .. спасибо!
granadaCoder
locations.toArray(WorldLocations[]::new)также, кажется, работает, так как Java 11 (без .stream())
Эран Медан
12

Укороченная версия принятого ответа с использованием гуавы:

.getMap(Iterables.toArray(locations, WorldLocation.class));

можно укоротить дальше, статически импортируя toArray:

import static com.google.common.collect.toArray;
// ...

    .getMap(toArray(locations, WorldLocation.class));
tkruse
источник
1

Ты можешь сделать:

getMap(locations.toArray(new WorldLocation[locations.size()]));

или

getMap(locations.toArray(new WorldLocation[0]));

или

getMap(new WorldLocation[locations.size()]);

@SuppressWarnings("unchecked") необходимо для удаления предупреждения ide.

Imar
источник
1
2-е решение лучше!
Гаурав