次のコードで、Integerオブジェクトを含むArrayListをプリミティブint []に変換しようとしていますが、コンパイル時エラーが発生しています。 Javaで変換することは可能ですか?
List<Integer> x = new ArrayList<Integer>();
int[] n = (int[])x.toArray(int[x.size()]);
あなたは変換することができますが、私はそれを自動的に行うために組み込まれた何かがあるとは思わない:
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
またはその中の任意の要素がnull
である場合、これはNullPointerExceptionをスローします。)
編集:コメントによると、あなたは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;
}
もしあなたが Java-8 を使っているなら、これを行う別の方法もあります。
int[] arr = list.stream().mapToInt(i -> i).toArray();
それは何ですか:
Stream<Integer>
を取得するIntStream
を取得し(identity関数)、各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]
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が示したように、外部ライブラリを使用するのではなく、自分でこれを実行するのはかなり簡単です。
Google Guava は Ints.toArray
を呼び出すことでこれを実行するためのきちんとした方法を提供します。
List<Integer> list = ...;
int[] values = Ints.toArray(list);
Listの実装によってはlist.get(i)
のパフォーマンスが悪くなる可能性があるため、Listの反復子を使用して反復処理するほうが良い考えです。
private int[] buildIntArray(List<Integer> integers) {
int[] ints = new int[integers.size()];
int i = 0;
for (Integer n : integers) {
ints[i++] = n;
}
return ints;
}
ドル を使うのはとても簡単です。
List<Integer> list = $(5).toList(); // the list 0, 1, 2, 3, 4
int[] array = $($(list).toArray()).toIntArray();
私は中間のtoArray()
呼び出しを削除するためにDSLを改善することを計画しています
Eclipse Collections を使っているなら、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());
ArrayList
をFastList
に変換できれば、アダプタを取り除くことができます。
Assert.assertArrayEquals(
new int[]{1, 2, 3, 4, 5},
Lists.mutable.with(1, 2, 3, 4, 5)
.collectInt(i -> i).toArray());
注:私はEclipseコレクションのコミッターです。
Apache Commonsのような完全によく使われているライブラリがすでに問題を解決しているときはいつでも、1回限りのカスタムメソッドを推奨することは私を困惑させます。解決策はばかげていないにしても些細なことですが、長期的なメンテナンスとアクセシビリティのためにそのような行動を奨励することは無責任です。
とにかく Apache Commons
単純にそれを配列にコピーすることができます:
int[] arr = new int[list.size()];
for(int i = 0; i < list.size(); i++) {
arr[i] = list.get(i);
}
派手すぎない。しかし、それはうまくいきます...
このコードセグメントは私のために働いています、これを試してください:
Integer[] arr = x.toArray(new Integer[x.size()]);
ArrayListは次のように宣言する必要があります。
ArrayList<Integer> list = new ArrayList<>();