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.


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()]));
    //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...

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

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

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.


1
Solusi 2 lebih baik!
gaurav
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.