整数を含むArrayListをプリミティブint配列に変換する方法は?


297

次のコードを使用して、Integerオブジェクトを含むArrayListをプリミティブint []に変換しようとしていますが、コンパイル時にエラーが発生します。Javaで変換することは可能ですか?

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

10
その質問の
正確な

1
はい、これはArrayListであり、「複製」は通常の配列に関するものです。
スコットマッキンタイア

3
あなたは原始的なint型を必要としない場合は、使用することができます: List<Integer> x = new ArrayList<Integer>(); Integer[] n = x.toArray(new Integer[0]);
Evorlor

回答:


219

変換することはできますが、自動的に変換する機能が組み込まれているとは思いません。

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またはその中のいずれかの要素がである場合、これはNullPointerExceptionをスローすることに注意してくださいnull。)

編集:コメントに従って、リスト反復子を使用して、次のようなリストの厄介なコストを回避することができます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
アクセスがO(1)ではないリストでのパフォーマンスヒットを回避するために、リストの反復子(for eachを使用)を使用して反復する方が良い場合があります。
マシューウィリス

@マシュー:はい、おそらく-代替としてそれを与えるために編集します。
Jon Skeet、2011

1
ArrayListがIterableを(コレクションの継承によって)実装するという事実を利用して、次のことを行うこともできます。for(int n:integer){ret [counter ++] = n; } ...そして初期化int counter = 0;
gardarh

8
Java8ではるかに簡単になりました:integers.stream().mapToInt(Integer::valueOf).toArray
Manish Patel

241

使用している場合 これを行う別の方法もあります。

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

それは何ですか:

  • Stream<Integer>リストから取得
  • IntStreamアンボクシング、自体(恒等関数)に各要素をマッピングすることにより、intそれぞれが値ホールドをIntegerオブジェクト(Java 5のために自動的に行われます)
  • int呼び出して配列を取得するtoArray

intValueメソッド参照を介して明示的に呼び出すこともできます。

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

リストに参照があるNullPointerException場合は、を取得できることにも言及する価値がありますnull。これは、次のようにストリームパイプラインにフィルタリング条件を追加することで簡単に回避できます。

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

例:

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]

これはdouble型に使用できると思います。floatタイプに相当するものはありませんか?
code_dredd 2017

入念な説明でJava 8の利点を見ました。
ユージーン

そして、これがJava 8+ Stream APIが美しい理由です。
Pranav A.

67

Googleグアバ

Google Guavaはを呼び出すことでこれを行うためのきちんとした方法を提供しますInts.toArray

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

6
これが私の答えになると思います-私はいつでもコピーアンドペースト機能よりもライブラリを利用します。この回答が今後さらに多くの賛成票と認知度を得ることを願っています。
Sean Connolly

61

Apache CommonsにはArrayUtilsクラスがあり、これはまさにこれを行うメソッドtoPrimitive()を持っています。

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

ただし、Jonが示したように、外部ライブラリを使用する代わりに、自分でこれを行うのはかなり簡単です。


2
このアプローチでは、シーケンスの2つの完全なコピーが作成されることに注意してください。1つはtoArrayによって作成されたInteger []で、もう1つはtoPrimitive内で作成されたint []です。Jonからのもう1つの答えは、1つの配列のみを作成して埋めます。リストが大きく、パフォーマンスが重要な場合に考慮すべきこと。
パラコート、

ArrayUtilsと純粋なJavaを使用してパフォーマンスを測定し、小さなリスト(<25要素)で純粋なJavaを100倍以上高速化しました。3k要素の場合、純粋なJavaは依然としてほぼ2倍高速です...(ArrayList <Integer>-> int [])
Oskar Lund

@paraquatとOskar Lundは実際には正しくありません。はい、提供されたコードは2つの配列を作成しますが、このアプローチでは作成されません。このコードの問題は、長さ0の配列を引数として使用することです。ArrayList.toArrayソースコードの内容が収まる場合、元の配列が使用されることを示しています。公平に比較​​すると、この方法は効率がよく(それ以上ではないにしても)、維持するコードが少ないことがわかります。
Sean Connolly


1
新しい整数の目的は何ですか[0]?
Adam Hughes

41

list.get(i)リストの実装によってはパフォーマンスが低下する可能性があるため、リストのイテレーターを使用して反復することをお勧めします。

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

ドルの使用は非常に簡単です:

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

中間toArray()通話を削除するためにDSLを改善する予定です


1
ちょっと、私は前にドルを見たことがなかったと言いたかっただけですが、私は間違いなく次のプロジェクトでそれを試してみています。それはあなたがそこに行ってきた気の利いた小さなapiです、良い仕事を続けてください:)
Bart Vandendriessche

4

これは私にとってはうまくいきます:)

で発見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

Apache Commonsのような完全に優れた、よく使われているライブラリで問題がすでに解決されているときはいつでも、1回限りのカスタムメソッドを推奨することに戸惑います。ばかげていないとしても、解決策は取るに足らないものですが、長期的なメンテナンスとアクセスのしやすさから、このような振る舞いを奨励するのは無責任です。

ただ、一緒に行くのApache Commonsの


7
以前のコメントに同意します。Apache Commonsでドラッグするだけでなく、ドラッグする必要がある推移的な依存関係の大きなセットに簡単に変換できます。最近、1行のコードを置き換えることで依存関係の驚くべき数を削除できました:-(依存関係はコストが高く、このような基本的なコードを書くことは良い習慣です
Peter Kriens

1
@PeterKriensに同意しました。どちらかと言えば、標準データ型でこのような単純な変換をサポートしていないことがJavaの障害です
Adam Hughes

3

あなたが使用している場合はEclipseのコレクションを、あなたが使用することができcollectInt()、プリミティブintコンテナにオブジェクトコンテナからスイッチに方法を。

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

あなたが変換することができた場合ArrayListFastListは、アダプターを取り除くことができます。

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

注:私は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));

出力:

プリミティブ整数の配列:[7、9、13]

アレイに対して同じ作品longまたはdoubleではなく、アレイのためにbooleancharbyteshortまたはfloat。非常に大きなリストがparallelSetAllある場合は、代わりに使用できる方法もあります。

私にとってこれは十分に優れており、外部ライブラリを取得したり、ストリームを使用したりしたくありません。

ドキュメントリンク: Arrays.setAll(int[], IntUnaryOperator)


1

あなたは単にそれを配列にコピーすることができます:

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

派手すぎない。しかし、ちょっと、それはうまくいきます...


1

非常にシンプルな1行のソリューションは次のとおりです。

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

0

このコードセグメントは私のために働いています、これを試してください:

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

ArrayListは次のように宣言する必要があります。

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

5
こんにちは、OPがObject配列ではなくプリミティブ配列を必要としていることを穏やかに思い出させてください。
OLIVER.KOO 2017

3
プリミティブintはラッパー整数ではありません!
Bartzilla、2018

-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
この答えは機能しません。複数の要素ではなく単一の要素を持つ配列を返します。
Mysticial 2013年

StringBufferを使用する理由 なぜIntegerをStringに変換してからIntegerに変換し、次にintに変換してから、もう一度Integerに変換するのですか?単一の要素を含む配列を使用するのはなぜですか。また、要素が1つだけ含まれている場合に、その単一要素の配列をループするのはなぜですか。なぜ外側のループで整数をオブジェクトにキャストするのですか?ここには非常に多くの質問があります。@CodeMadnessは単なるトロールアカウントですか?
Victor Zamanian 2016

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

arr通常通りのアクセスint[]


5
これは質問の答えにはなりません。質問はプリミティブ型(int)への変換に関するものでした
Asaf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.