Tamsayılar içeren bir ArrayList ilkel int dizisine nasıl dönüştürülür?


297

Aşağıdaki kod parçası ile ilkel int [] tamsayı nesneleri içeren bir ArrayList dönüştürmek çalışıyorum, ama derleme zaman hatası atıyor. Java ile dönüştürmek mümkün mü?

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

10
Bu sorunun tam bir kopyası değil (çok da uzak olmasa da)
Jonik

1
Evet, bu bir ArrayList, "yinelenen" normal bir dizi ile ilgilidir.
Scott McIntyre

3
İlkel List<Integer> x = new ArrayList<Integer>(); Integer[] n = x.toArray(new Integer[0]);
girişlere

Yanıtlar:


219

Dönüştürebilirsiniz, ancak bunu otomatik olarak yapmak için yerleşik bir şey olduğunu düşünmüyorum:

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

( integersİçinde herhangi bir öğe varsa, bunun bir NullPointerException oluşturacağını unutmayın null.)

DÜZENLEME: Yorumlara göre, aşağıdaki gibi listelerle kötü maliyetlerden kaçınmak için liste yineleyicisini kullanmak isteyebilirsiniz 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
Erişimi O (1) olmayan listelerde performans isabetlerinden kaçınmak için Liste yineleyicisini kullanarak (her biri için) yineleme yapmak daha iyi olabilir.
Matthew Willis

@Matthew: Evet, muhtemelen - bunu alternatif olarak vermek için düzenleyecek.
Jon Skeet

1
ArrayList'in Yinelenebilir (Koleksiyon devralma yoluyla) uyguladığı gerçeğini de kullanabilir ve şunları yapabilirsiniz: for (int n: integer) {ret [counter ++] = n; } ... ve int sayacını başlat = 0;
gardarh

8
Java8'de artık çok daha kolay:integers.stream().mapToInt(Integer::valueOf).toArray
Manish Patel

241

Kullanıyorsanız bunu yapmanın başka bir yolu daha var.

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

Yaptığı şey:

  • Stream<Integer>listeden a almak
  • Bir elde IntStreamkutusu açma, tek başına (bir kimlik fonksiyonu) her elemanın eşleyerek inther birinin değeri tutma Integernesnesi (Java 5 itibaren otomatik olarak yapılır)
  • intarayarak dizi almaktoArray

Ayrıca intValuebir yöntem başvurusu aracılığıyla açıkça çağrı yapabilirsiniz , yani:

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

Listede NullPointerExceptionherhangi bir nullreferansınız varsa , alabileceğinizi de belirtmek gerekir . Akış boru hattına aşağıdaki gibi bir filtreleme koşulu eklenerek bu kolayca önlenebilir:

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

Misal:

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]

Bunun doubletürler için kullanılabileceğini görüyorum ; floattipler için eşdeğeri yok mu?
code_dredd

Ayrıntılı bir açıklama yaparak Java 8'in avantajlarını gördünüz.
Eugene

İşte bu yüzden Java 8+ Stream API'sı çok güzel.
Pranav A.19

67

Google Guava

Google Guava , bunu arayarak temiz bir yol sağlar Ints.toArray.

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

6
Sanırım bu benim için bir cevap olacak - her gün bir kopyala yapıştır fonksiyonu üzerine bir kütüphane alacağım .. özellikle iyi bir projenin muhtemelen kullandığı bir kütüphane Umarım bu cevap gelecekte daha fazla oy ve görünürlük elde eder.
Sean Connolly

61

Apache Commons, tam olarak bunu yapan birPrimitive () yöntemine sahip bir ArrayUtils sınıfına sahiptir.

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

Ancak, Jon'un gösterdiği gibi, bunu harici kütüphaneler kullanmak yerine kendiniz yapmak oldukça kolaydır.


2
Bu yaklaşımın dizinin iki tam kopyasını oluşturacağına dikkat edin: biri toArray tarafından oluşturulan bir Tamsayı [] ve toPrimitive içinde oluşturulan bir int []. Jon'un diğer yanıtı sadece bir dizi oluşturur ve doldurur. Büyük listeleriniz ve performansınız varsa dikkate alınması gereken bir şey.
paraquatı

Performansı ArrayUtils ile saf java kullanarak ölçtüm ve küçük listelerde (<25 öğe) saf java 100 kattan daha hızlı. 3k elementler için saf java hala neredeyse 2 kat daha hızlı ... (ArrayList <Integer> -> int [])
Oskar Lund

@paraquat & Oskar Lund aslında doğru değil. Evet, sağlanan kod iki dizi oluşturacak, ancak bu yaklaşım oluşturmuyor . Bu koddaki sorun, argüman olarak sıfır uzunluklu bir dizinin kullanılmasıdır. ArrayList.toArray kaynak kodu içeriği uyacak eğer orijinal dizi kullanılacak olduğu gösterilmektedir. Adil bir karşılaştırma, bu yöntemi (daha fazla değilse) verimli ve tabii ki, korumak için daha az kod bulacaksınız düşünüyorum.
Sean Connolly


1
Waht yeni Tamsayı'nın [0] amacı mı?
Adam Hughes

41

list.get(i)List uygulamasına bağlı olarak düşük performans gösterebileceğinden, List'in yineleyicisini kullanarak yinelemenin daha iyi bir fikir olduğuna inanıyorum :

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

Dolar kullanmak oldukça basit olmalı:

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

Ara toArray()çağrıyı kaldırmak için DSL'yi geliştirmeyi planlıyorum


1
Hey, daha önce Dolar görmediğimi söylemek istedim, ama kesinlikle bir sonraki projemde deniyorum. Oraya gideceğiniz şık küçük bir api, iyi çalışmaya devam edin :)
Bart Vandendriessche

4

Bu benim için iyi çalışıyor :)

Https://www.techiedelight.com/convert-list-integer-array-int/ adresinde bulundu

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

Apache Commons gibi mükemmel, iyi kullanılmış bir kütüphane sorunu zaten çözdüğünde, bir kereye mahsus özel yöntemleri teşvik ettiğimizi şaşırtıyor. Çözüm saçma olmasa bile önemsiz olsa da, uzun süreli bakım ve erişilebilirlik nedeniyle böyle bir davranışı teşvik etmek sorumsuzdur.

Sadece Apache Commons ile git


8
Önceki yorumcuyu kabul ediyorum. Sadece Apache Commons'ta sürüklemekle kalmaz, aynı zamanda sürüklenmesi gereken geniş bir geçişli bağımlılık kümesine kolayca dönüşür. Son zamanlarda bir kod satırını değiştirerek inanılmaz bir bağımlılık sayısını kaldırabilirim :-( Bağımlılıklar pahalıdır ve böyle temel kod yazmak iyi bir uygulamadır
Peter Kriens

1
@PeterKriens ile aynı fikirde. Herhangi bir şey varsa, hata standart veri türlerinde böyle basit dönüşümleri desteklemediği için
Adam Hughes

3

Eğer kullanıyorsanız Eclipse Koleksiyonlar , kullanabileceğiniz collectInt()ilkel int kaba bir nesne kaptan anahtara yöntemi.

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

İstemiyorsun, mutfakta annene dönüştürebilirsiniz Eğer ArrayListbir etmek FastList, bağdaştırıcı kurtulabilirsiniz.

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

Not: Eclipse koleksiyonları için bir komisyoncuyum.


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

Çıktı:

İlkel int dizisi: [7, 9, 13]

Bir dizi için aynı işleri longveya doubledeğil diziler için boolean, char, byte, shortveya float. Gerçekten çok büyük bir listeniz parallelSetAllvarsa, bunun yerine kullanabileceğiniz bir yöntem bile vardır .

Bana göre bu, harici bir kütüphane almak ya da bunun için akış kullanmak istemeyeceğim kadar iyi ve elverişlidir.

Dokümantasyon bağlantısı: Arrays.setAll(int[], IntUnaryOperator)


1

Basitçe bir diziye kopyalayabilirsiniz:

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

Çok süslü değil; ama, hey, işe yarıyor ...


1

Çok basit bir tek satırlık çözüm:

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

0

Bu kod segmenti benim için çalışıyor, şunu deneyin:

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

Bahsetmeye değer ArrayList şöyle beyan edilmelidir:

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

5
Merhaba OP'nin bir Object dizisi değil, ilkel bir dizi istediği nazik bir hatırlatma.
OLIVER.KOO

3
İlkel int sarıcı değil Tamsayı!
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
Bu yanıt işe yaramıyor, birden çok öğe yerine tek bir öğeye sahip bir dizi döndürüyor.
Gizemli

Neden StringBuffer kullanılır? Neden bir tamsayı bir dize ve sonra bir tamsayı sonra bir int ve sonra bir tamsayı dönüştürmek? Neden içinde tek bir öğe bulunan bir dizi kullanıyorsunuz ve neden yalnızca bir öğe içerdiğinde o tek öğe dizisi üzerinde döngü yapıyorsunuz? Tamsayıları neden dış döngüde Nesnelere atalım? Burada çok fazla soru var. @CodeMadness sadece bir troll hesabı mıdır?
Victor Zamanian

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

arrnormal erişim int[].


5
bu soruya cevap vermiyor, soru ilkel tipe (int) dönüştürmekle ilgiliydi
Asaf
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.