Bagaimana cara mengubah ArrayList yang berisi Integer ke array int primitif?


297

Saya mencoba untuk mengkonversi ArrayList yang berisi objek Integer ke primitif int [] dengan potongan kode berikut, tetapi ia melemparkan kesalahan waktu kompilasi. Apakah mungkin mengkonversi di Jawa?

List<Integer> x =  new ArrayList<Integer>();
int[] n = (int[])x.toArray(int[x.size()]);

10
Bukan duplikat TEPAT dari pertanyaan itu (walaupun tidak terlalu jauh)
Jonik

1
Ya, ini adalah ArrayList, "duplikat" adalah tentang array normal.
Scott McIntyre

3
Jika Anda tidak memerlukan int primitif, Anda dapat menggunakan: List<Integer> x = new ArrayList<Integer>(); Integer[] n = x.toArray(new Integer[0]);
Evorlor

Jawaban:


219

Anda dapat mengonversi, tetapi saya rasa tidak ada yang dibangun untuk melakukannya secara otomatis:

public static int[] convertIntegers(List<Integer> integers)
{
    int[] ret = new int[integers.size()];
    for (int i=0; i < ret.length; i++)
    {
        ret[i] = integers.get(i).intValue();
    }
    return ret;
}

(Perhatikan bahwa ini akan melempar NullPointerException jika salah satu integersatau elemen di dalamnya null.)

Sunting: Sesuai komentar, Anda mungkin ingin menggunakan daftar iterator untuk menghindari biaya buruk dengan daftar seperti LinkedList:

public static int[] convertIntegers(List<Integer> integers)
{
    int[] ret = new int[integers.size()];
    Iterator<Integer> iterator = integers.iterator();
    for (int i = 0; i < ret.length; i++)
    {
        ret[i] = iterator.next().intValue();
    }
    return ret;
}

21
Mungkin lebih baik untuk beralih menggunakan iterator Daftar (dengan masing-masing) untuk menghindari hit kinerja pada daftar yang aksesnya bukan O (1).
Matthew Willis

@ Matius: Ya, mungkin - akan mengedit untuk memberikan itu sebagai alternatif.
Jon Skeet

1
Anda juga dapat memanfaatkan fakta bahwa ArrayList mengimplementasikan Iterable (melalui warisan Collection) dan melakukan: for (int n: integer) {ret [counter ++] = n; } ... dan inisialisasi penghitung int = 0;
gardarh

8
jauh lebih mudah sekarang di Java8:integers.stream().mapToInt(Integer::valueOf).toArray
Manish Patel

241

Jika Anda menggunakan ada juga cara lain untuk melakukan ini.

int[] arr = list.stream().mapToInt(i -> i).toArray();

Apa yang dilakukannya adalah:

  • dapatkan Stream<Integer>dari daftar
  • memperoleh IntStreamdengan memetakan setiap elemen ke dirinya sendiri (fungsi identitas), menghapus kotak intnilai yang disimpan oleh setiap Integerobjek (dilakukan secara otomatis sejak Java 5)
  • mendapatkan array intdengan menelepontoArray

Anda juga dapat secara eksplisit menelepon intValuemelalui referensi metode, yaitu:

int[] arr = list.stream().mapToInt(Integer::intValue).toArray();

Perlu juga disebutkan bahwa Anda bisa mendapatkan NullPointerExceptionjika Anda memiliki nullreferensi dalam daftar. Ini bisa dengan mudah dihindari dengan menambahkan kondisi penyaringan ke pipa aliran seperti ini:

                       //.filter(Objects::nonNull) also works
int[] arr = list.stream().filter(i -> i != null).mapToInt(i -> i).toArray();

Contoh:

List<Integer> list = Arrays.asList(1, 2, 3, 4);
int[] arr = list.stream().mapToInt(i -> i).toArray(); //[1, 2, 3, 4]

list.set(1, null); //[1, null, 3, 4]
arr = list.stream().filter(i -> i != null).mapToInt(i -> i).toArray(); //[1, 3, 4]

Saya melihat ini dapat digunakan untuk doubletipe; apakah tidak ada yang setara untuk floatjenis?
code_dredd

Melihat manfaat Java 8 oleh Anda penjelasan yang rumit.
Eugene

Dan inilah mengapa Java 8+ Stream API itu indah.
Pranav A.

67

Google Jambu

Google Guava menyediakan cara yang rapi untuk melakukan ini dengan menelepon Ints.toArray.

List<Integer> list = ...;
int[] values = Ints.toArray(list);

6
Saya pikir ini akan menjadi jawaban bagi saya - saya akan mengambil perpustakaan atas fungsi salin-tempel setiap hari .. terutama perpustakaan yang kemungkinan besar sudah menggunakan proyek berukuran layak. Saya harap jawaban ini mendapat lebih banyak suara dan visibilitas di masa depan.
Sean Connolly

61

Apache Commons memiliki kelas ArrayUtils, yang memiliki metode toPrimitive () yang melakukan hal ini.

import org.apache.commons.lang.ArrayUtils;
...
    List<Integer> list = new ArrayList<Integer>();
    list.add(new Integer(1));
    list.add(new Integer(2));
    int[] intArray = ArrayUtils.toPrimitive(list.toArray(new Integer[0]));

Namun, seperti yang ditunjukkan Jon, cukup mudah untuk melakukannya sendiri daripada menggunakan perpustakaan eksternal.


2
Perhatikan bahwa pendekatan ini akan membuat dua salinan lengkap dari urutan: satu Integer [] dibuat oleh toArray, dan satu int [] dibuat di dalam toPrimitive. Jawaban lain dari Jon hanya membuat dan mengisi satu array. Sesuatu untuk dipertimbangkan jika Anda memiliki daftar besar, dan kinerja itu penting.
paraquat

Saya mengukur kinerja menggunakan ArrayUtils vs java murni dan pada daftar kecil (<25 elemen) java murni lebih dari 100 kali lebih cepat. Untuk elemen 3k java murni masih hampir 2 kali lebih cepat ... (ArrayList <Integer> -> int [])
Oskar Lund

@paraquat & Oskar Lund yang sebenarnya tidak benar. Ya, kode yang diberikan akan membuat dua array, tetapi pendekatan ini tidak. Masalah dalam kode ini di sini adalah penggunaan array panjang nol sebagai argumen. The ArrayList.toArray kode sumber menunjukkan bahwa jika isi akan cocok, array asli akan digunakan. Saya pikir dalam perbandingan yang adil Anda akan menemukan metode ini seefisien (jika tidak lebih) dan, tentu saja, lebih sedikit kode untuk dipelihara.
Sean Connolly


1
Waht adalah tujuan Integer baru [0]?
Adam Hughes

41

Saya percaya iterasi menggunakan iterator Daftar adalah ide yang lebih baik, karena list.get(i)dapat memiliki kinerja yang buruk tergantung pada implementasi Daftar:

private int[] buildIntArray(List<Integer> integers) {
    int[] ints = new int[integers.size()];
    int i = 0;
    for (Integer n : integers) {
        ints[i++] = n;
    }
    return ints;
}

6

menggunakan Dollar seharusnya cukup sederhana:

List<Integer> list = $(5).toList(); // the list 0, 1, 2, 3, 4  
int[] array = $($(list).toArray()).toIntArray();

Saya berencana untuk meningkatkan DSL untuk menghapus toArray()panggilan menengah


1
Hei, hanya ingin mengatakan saya belum melihat Dollar sebelumnya, tapi saya pasti mencobanya di proyek saya berikutnya. Itu api kecil yang bagus yang telah kamu tuju, tetap bekerja dengan baik :)
Bart Vandendriessche

4

Ini berfungsi baik untuk saya :)

Ditemukan di https://www.techiedelight.com/convert-list-integer-array-int/

import java.util.Arrays;
import java.util.List;

class ListUtil
{
    // Program to convert list of integer to array of int in Java
    public static void main(String args[])
    {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

        int[] primitive = list.stream()
                            .mapToInt(Integer::intValue)
                            .toArray();

        System.out.println(Arrays.toString(primitive));
    }
}

3

Ini membingungkan saya bahwa kami mendorong metode kustom satu kali setiap kali perpustakaan yang sangat baik, digunakan dengan baik seperti Apache Commons telah memecahkan masalah. Meskipun solusinya sepele jika tidak absurd, itu tidak bertanggung jawab untuk mendorong perilaku seperti itu karena pemeliharaan jangka panjang dan aksesibilitas.

Pergilah dengan Apache Commons


7
Saya setuju dengan komentator sebelumnya. Anda tidak hanya menyeret di Apache Commons, tetapi juga dengan mudah diterjemahkan menjadi satu set besar dependensi transitif yang juga perlu diseret. Baru-baru ini saya bisa menghapus # dependensi yang menakjubkan dengan mengganti satu baris kode :-( Ketergantungan mahal dan menulis kode dasar seperti ini adalah praktik yang baik
Peter Kriens

1
Setuju dengan @PeterKriens. Jika ada, kesalahannya adalah di Jawa karena tidak mendukung konversi sederhana seperti ini dalam tipe data standar
Adam Hughes

3

Jika Anda menggunakan Koleksi Eclipse , Anda bisa menggunakan collectInt()metode ini untuk beralih dari wadah objek ke wadah int primitif.

List<Integer> integers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
MutableIntList intList =
  ListAdapter.adapt(integers).collectInt(i -> i);
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, intList.toArray());

Jika Anda dapat mengonversi ArrayListke FastList, Anda dapat menyingkirkan adaptor.

Assert.assertArrayEquals(
  new int[]{1, 2, 3, 4, 5},
  Lists.mutable.with(1, 2, 3, 4, 5)
    .collectInt(i -> i).toArray());

Catatan: Saya pengendara untuk koleksi Eclipse.


3

Java 8:

int[] intArr = Arrays.stream(integerList).mapToInt(i->i).toArray();

2

Arrays.setAll ()

    List<Integer> x = new ArrayList<>(Arrays.asList(7, 9, 13));
    int[] n = new int[x.size()];
    Arrays.setAll(n, x::get);

    System.out.println("Array of primitive ints: " + Arrays.toString(n));

Keluaran:

Array int primitif: [7, 9, 13]

Karya-karya yang sama untuk berbagai longatau double, tetapi tidak untuk array boolean, char, byte, shortatau float. Jika Anda memiliki daftar yang sangat besar, bahkan ada parallelSetAllmetode yang dapat Anda gunakan sebagai gantinya.

Bagi saya ini bagus dan cukup elgant sehingga saya tidak ingin mendapatkan perpustakaan eksternal atau menggunakan stream untuk itu.

Tautan dokumentasi: Arrays.setAll(int[], IntUnaryOperator)


1

Anda cukup menyalinnya ke sebuah array:

int[] arr = new int[list.size()];
for(int i = 0; i < list.size(); i++) {
    arr[i] = list.get(i);
}

Tidak terlalu mewah; tapi, hei, itu berhasil ...


1

Solusi satu garis yang sangat sederhana adalah:

Integer[] i = arrlist.stream().toArray(Integer[]::new);

0

Segmen kode ini berfungsi untuk saya, coba ini:

Integer[] arr = x.toArray(new Integer[x.size()]);

Layak untuk menyebutkan ArrayList harus dinyatakan seperti ini:

ArrayList<Integer> list = new ArrayList<>();

5
Halo hanya pengingat lembut bahwa OP ingin array primitif bukan array Object.
OLIVER.KOO

3
Primitive int bukan wrapper Integer!
Bartzilla

-4
   List<Integer> list = new ArrayList<Integer>();

    list.add(1);
    list.add(2);

    int[] result = null;
    StringBuffer strBuffer = new StringBuffer();
    for (Object o : list) {
        strBuffer.append(o);
        result = new int[] { Integer.parseInt(strBuffer.toString()) };
        for (Integer i : result) {
            System.out.println(i);
        }
        strBuffer.delete(0, strBuffer.length());
    }

1
Jawaban ini tidak berfungsi, ia mengembalikan array dengan elemen tunggal alih-alih beberapa elemen.
Mysticial

Mengapa menggunakan StringBuffer? Mengapa mengkonversi Integer ke String dan kemudian ke Integer dan kemudian ke int dan kemudian ke Integer lagi? Mengapa menggunakan array dengan elemen tunggal di dalamnya, dan mengapa mengulangi array elemen tunggal saat itu hanya mengandung satu elemen? Mengapa melemparkan Integer ke Objek di lingkaran luar? Ada banyak sekali pertanyaan di sini. Apakah @CodeMadness hanya akun troll?
Victor Zamanian

-5
Integer[] arr = (Integer[]) x.toArray(new Integer[x.size()]);

akses arrseperti biasa int[].


5
ini tidak menjawab pertanyaan, pertanyaannya adalah tentang mengubah ke tipe primitif (int)
Asaf
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.