Як передати ArrayList параметру методу varargs?


236

В основному у мене є ArrayList місць розташування:

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

нижче цього я називаю наступний метод:

.getMap();

Параметри методу getMap ():

getMap(WorldLocation... locations)

Проблема, яка у мене є, я не впевнений, як перейти у цілий список locationsцього методу.

Я намагався

.getMap(locations.toArray())

але getMap не приймає цього, оскільки він не приймає об'єкти [].

Тепер, якщо я користуюся

.getMap(locations.get(0));

він буде працювати ідеально ... але мені потрібно якось пройти у ВСІХ локаціях ... Я, звичайно, можу зробити додавання locations.get(1), locations.get(2)тощо, але розмір масиву змінюється. Я просто не використовую цілу концепціюArrayList

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


Відповіді:


340

Стаття джерела: передача списку як аргумент методу 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()]));
    //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...

1
Наскільки дорогою буде ця операція з точки зору пам'яті та швидкості?
mindreader

Це не спрацює без попередження, якщо будуть задіяні додаткові шаблони. Наприклад someMethod(someList.toArray(new ArrayList<Something>[someList.size()])), ви отримаєте попередження, яке дуже дратує, якщо функція довга декількох рядків (оскільки ви можете або придушити її для всієї функції, або вам доведеться створити масив на додатковому кроці і придушити попередження про змінну, яку ви зберігайте його
Qw3ry

23
Мабуть, найшвидший підхід - це розмір нуля, а не розмір масиву. Словом, це тому, що константа часу компіляції дозволяє використовувати оптимізований метод. shipilev.net/blog/2016/arrays-wisdom-ancients
geg

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

2
це java voodoo, але краще java (8) voodoo .. дякую!
granadaCoder

locations.toArray(WorldLocations[]::new)також, здається, працює з java 11 (Без цього .stream())
Еран Медан

12

Коротка версія прийнятої відповіді за допомогою Guava:

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

можна додатково скоротити статичним імпортом до Array:

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

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

1

Ви можете зробити:

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

або

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

або

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

@SuppressWarnings("unchecked") потрібно зняти ідею попередження.


1
2-е рішення краще!
гаурав
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.