Como passar um ArrayList para um parâmetro do método varargs?

236

Basicamente, eu tenho um ArrayList de locais:

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

abaixo disso eu chamo o seguinte método:

.getMap();

os parâmetros no método getMap () são:

getMap(WorldLocation... locations)

O problema que estou tendo é que não tenho certeza de como passar a lista INTEIRO locationspara esse método.

eu tentei

.getMap(locations.toArray())

mas o getMap não aceita isso porque não aceita Objetos [].

Agora se eu usar

.getMap(locations.get(0));

funcionará perfeitamente ... mas, de alguma forma, preciso passar por TODOS os locais ... É claro que eu poderia continuar adicionando locations.get(1), locations.get(2)etc., mas o tamanho da matriz varia. Só não estou acostumado a todo o conceito deArrayList

Qual seria a maneira mais fácil de fazer isso? Eu sinto que não estou pensando direito agora.

MJ93
fonte

Respostas:

340

Artigo de origem: Passando uma lista como argumento para um método vararg


Use o toArray(T[] arr)método

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

( toArray(new WorldLocation[0])também funciona, mas você alocaria uma matriz de comprimento zero sem motivo.)


Aqui está um exemplo 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()]));
    //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
aioobe
fonte
1
Qual seria o custo dessa operação em termos de memória e velocidade?
LeitorMental
Isso não funcionará sem um aviso se houver mais modelos envolvidos. Por exemplo someMethod(someList.toArray(new ArrayList<Something>[someList.size()])), você receberá um aviso muito irritante se a função tiver mais do que algumas linhas (porque você pode suprimi-la para toda a função ou precisa criar a matriz em uma etapa adicional e suprimir o aviso na variável que você armazená-lo.
Qw3ry
23
Aparentemente, a abordagem mais rápida é fornecer um tamanho zero em vez do tamanho da matriz. Em resumo, é porque a constante em tempo de compilação permite o uso de um método otimizado. shipilev.net/blog/2016/arrays-wisdom-ancients
geg
2
@JoshM. Java precisa de muitas coisas. ;) Eu também (vindo de um fundo C #) sinto falta de operadores de índice. Trabalhar com dicionários é muito mais fácil em C # do que trabalhar com HashMaps em Java.
Per Lundberg
@PerLundberg - Concordo totalmente. Também um desenvolvedor principalmente de C # atualmente trabalhando com Java8. Talvez 10/11 seja melhor. :-P
Josh M.
42

No Java 8:

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

.getMap(locations.stream().toArray(WorldLocation[]::new));
jmhostalet
fonte
2
isso é vodu em java, mas melhor vodu em java (8) .. obrigado!
usar o seguinte código
locations.toArray(WorldLocations[]::new)também parece funcionar desde java 11 (sem o .stream())
Eran Medan
12

Uma versão mais curta da resposta aceita usando o Guava:

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

pode ser reduzido ainda mais importando estaticamente para oArray:

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

    .getMap(toArray(locations, WorldLocation.class));
tkruse
fonte
1

Você pode fazer:

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

ou

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

ou

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

@SuppressWarnings("unchecked") é necessário para remover o aviso de ide.

Imar
fonte
1
Segunda solução é melhor!
gaurav 16/03