Jak przekazać ArrayList do parametru metody varargs?

236

Zasadniczo mam ArrayList lokalizacji:

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

poniżej nazywam następującą metodę:

.getMap();

parametry w metodzie getMap () to:

getMap(WorldLocation... locations)

Problem, który mam, polega na tym, że nie jestem pewien, jak przekazać CAŁĄ listę locationsdo tej metody.

próbowałem

.getMap(locations.toArray())

ale getMap tego nie akceptuje, ponieważ nie akceptuje Objects [].

Teraz jeśli użyję

.getMap(locations.get(0));

będzie działał idealnie ... ale muszę jakoś przekazać WSZYSTKIE lokalizacje ... Oczywiście mógłbym nadal dodawać locations.get(1), locations.get(2)itd., ale rozmiar tablicy jest różny. Po prostu nie jestem przyzwyczajony do całej koncepcjiArrayList

Jaki byłby najłatwiejszy sposób na to? Czuję, że po prostu nie myślę teraz.

MJ93
źródło

Odpowiedzi:

340

Artykuł źródłowy: Przekazywanie listy jako argumentu do metody vararg


Skorzystaj z toArray(T[] arr)metody

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

( toArray(new WorldLocation[0])działa również, ale bez powodu przydzielisz tablicę o zerowej długości).


Oto kompletny przykład:

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
źródło
1
Jak kosztowna byłaby ta operacja pod względem pamięci i szybkości?
mindreader
To nie zadziała bez ostrzeżenia, jeśli w grę wchodzą kolejne szablony. Np. Wyświetli someMethod(someList.toArray(new ArrayList<Something>[someList.size()]))ostrzeżenie, które jest bardzo irytujące, jeśli funkcja ma więcej niż kilka wierszy (ponieważ możesz albo ją wyłączyć dla całej funkcji, albo musisz utworzyć tablicę w dodatkowym kroku i wyłączyć ostrzeżenie dla zmiennej przechowuj
Qw3ry,
23
Najwyraźniej najszybszym podejściem jest podanie rozmiaru zero zamiast rozmiaru tablicy. Krótko mówiąc, ponieważ stała czasowa kompilacji umożliwia stosowanie zoptymalizowanej metody. shipilev.net/blog/2016/arrays-wisdom-ancients
geg
2
@JoshM. Java potrzebuje wielu rzeczy. ;) Ja także (pochodząc z języka C #) brakuje operatorów indeksu. Praca ze słownikami jest znacznie płynniejsza w C # niż praca z HashMaps w Javie.
Per Lundberg,
@PerLundberg - Całkowicie się zgadzam. Również przede wszystkim programista C # obecnie pracujący w / Java8. Może 10/11 będzie lepiej. :-P
Josh M.
42

W Javie 8:

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

.getMap(locations.stream().toArray(WorldLocation[]::new));
jmhostalet
źródło
2
to jest java voodoo, ale lepiej java (8) voodoo .. dzięki!
granadaCoder,
locations.toArray(WorldLocations[]::new)wydaje się również działać od czasu wydania java 11 (bez .stream())
Eran Medan
12

Krótsza wersja zaakceptowanej odpowiedzi przy użyciu Guava:

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

można dodatkowo skrócić, importując statycznie do Array:

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

    .getMap(toArray(locations, WorldLocation.class));
tkruse
źródło
1

Możesz to zrobić:

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

lub

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

lub

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

@SuppressWarnings("unchecked") jest potrzebny do usunięcia ostrzeżenia ide.

Imar
źródło
1
Drugie rozwiązanie jest lepsze!
gaurav