Come passare un ArrayList a un parametro del metodo varargs?


236

Fondamentalmente ho un ArrayList di posizioni:

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

sotto questo chiamo il seguente metodo:

.getMap();

i parametri nel metodo getMap () sono:

getMap(WorldLocation... locations)

Il problema che sto riscontrando è che non sono sicuro di come passare all'intero elenco di locations quel metodo.

ho provato

.getMap(locations.toArray())

ma getMap non lo accetta perché non accetta gli oggetti [].

Ora se uso

.getMap(locations.get(0));

funzionerà perfettamente ... ma devo in qualche modo passare in TUTTE le posizioni ... Potrei ovviamente continuare ad aggiungere locations.get(1), locations.get(2)ecc. ma le dimensioni dell'array variano. Non sono abituato all'intero concetto di anArrayList

Quale sarebbe il modo più semplice per farlo? Sento che non sto pensando proprio ora.


Risposte:


340

Articolo di origine: passaggio di un elenco come argomento a un metodo vararg


Usa il toArray(T[] arr)metodo

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

( toArray(new WorldLocation[0])funziona anche, ma assegneresti un array di lunghezza zero senza motivo.)


Ecco un esempio completo:

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
Quanto sarebbe costosa questa operazione in termini di memoria e velocità?
mindreader,

Questo non funzionerà senza un avviso se sono coinvolti ulteriori modelli. Ad esempio, someMethod(someList.toArray(new ArrayList<Something>[someList.size()]))ti darà un avviso che è molto fastidioso se la funzione è lunga più di alcune righe (perché puoi sopprimerla per l'intera funzione o devi creare l'array in un passaggio aggiuntivo e sopprimere l'avviso sulla variabile conservalo
Qw3ry

23
Apparentemente l'approccio più veloce è dare una dimensione pari a zero anziché la dimensione dell'array. In breve, è perché la costante di compilazione consente l'utilizzo di un metodo ottimizzato. shipilev.net/blog/2016/arrays-wisdom-ancients
geg

2
@JoshM. Java ha bisogno di molte cose. ;) Anche io (proveniente da uno sfondo C #) mi mancano gli operatori di indice. Lavorare con i dizionari è molto più semplice in C # che lavorare con HashMaps in Java.
Per Lundberg,

@PerLundberg - Totalmente d'accordo. Anche uno sviluppatore principalmente C # attualmente lavora con Java8. Forse l'11 / 10 sarà migliore. :-P
Josh M.

42

In Java 8:

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

.getMap(locations.stream().toArray(WorldLocation[]::new));

2
questo è java voodoo, ma meglio java (8) voodoo .. grazie!
granadaCoder

locations.toArray(WorldLocations[]::new)sembra funzionare anche da java 11 (senza il .stream())
Eran Medan

12

Una versione più breve della risposta accettata usando Guava:

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

può essere ulteriormente abbreviato importando staticamente in Array:

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

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

1

Tu puoi fare:

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

o

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

o

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

@SuppressWarnings("unchecked") è necessario per rimuovere l'avvertimento ide.


1
La seconda soluzione è migliore!
gaurav
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.