Bagaimana cara melewatkan ArrayList ke parameter metode varargs?

236

Pada dasarnya saya memiliki ArrayList lokasi:

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

di bawah ini saya sebut metode berikut:

.getMap();

parameter dalam metode getMap () adalah:

getMap(WorldLocation... locations)

Masalah yang saya alami adalah saya tidak yakin bagaimana cara memasukkan dalam daftar SELURUH locationske dalam metode itu.

Saya sudah mencoba

.getMap(locations.toArray())

tetapi getMap tidak menerimanya karena tidak menerima Objek [].

Sekarang jika saya gunakan

.getMap(locations.get(0));

ini akan bekerja dengan sempurna ... tapi saya harus melewati SEMUA lokasi ... saya tentu saja bisa membuat terus menambahkan locations.get(1), locations.get(2)dll tetapi ukuran array bervariasi. Saya hanya tidak menggunakan seluruh konsep dariArrayList

Apa cara termudah untuk melakukannya? Saya merasa seperti saya tidak berpikir jernih saat ini.

MJ93
sumber

Jawaban:

340

Sumber artikel: Melewati daftar sebagai argumen ke metode vararg


Gunakan toArray(T[] arr)metodenya.

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

( toArray(new WorldLocation[0])juga berfungsi, tetapi Anda akan mengalokasikan array panjang nol tanpa alasan.)


Ini contoh lengkapnya:

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
sumber
1
Seberapa mahal operasi ini dalam hal memori & kecepatan?
mindreader
Ini tidak akan berfungsi tanpa peringatan jika ada template lebih lanjut yang terlibat. Misalnya someMethod(someList.toArray(new ArrayList<Something>[someList.size()]))akan memberi Anda peringatan yang sangat menjengkelkan jika fungsinya lebih dari beberapa baris (karena Anda bisa menekannya untuk seluruh fungsi atau Anda harus membuat array dalam langkah tambahan dan menekan peringatan pada variabel yang Anda simpan
Qw3ry
23
Rupanya pendekatan tercepat adalah memberikan ukuran nol daripada ukuran array. Singkatnya, itu karena konstanta waktu kompilasi memungkinkan penggunaan metode yang dioptimalkan. shipilev.net/blog/2016/arrays-wisdom-ancients
geg
2
@ Josh. Jawa membutuhkan banyak hal. ;) Saya juga (berasal dari latar belakang C #) kehilangan operator indeks. Bekerja dengan kamus jauh lebih lancar di C # daripada bekerja dengan HashMaps di Jawa.
Per Lundberg
@ PerLundberg - Sepenuhnya setuju. Juga pengembang C # utama saat ini bekerja dengan Java8. Mungkin 10/11 akan lebih baik. :-P
Josh M.
42

Di Jawa 8:

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

.getMap(locations.stream().toArray(WorldLocation[]::new));
jmhostalet
sumber
2
ini java voodoo, tapi java (8) voodoo lebih baik .. terima kasih!
granadaCoder
locations.toArray(WorldLocations[]::new)juga tampaknya berfungsi sejak java 11 (Tanpa .stream())
Eran Medan
12

Versi pendek dari jawaban yang diterima menggunakan Guava:

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

dapat dipersingkat lebih lanjut dengan mengimpor secara statis ke Array:

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

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

Anda dapat melakukan:

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

atau

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

atau

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

@SuppressWarnings("unchecked") diperlukan untuk menghapus ide peringatan.

Imar
sumber
1
Solusi 2 lebih baik!
gaurav