これはこの質問に似ています: Javaでint []をInteger []に変換するにはどうすればいいですか?
私はJavaが初めてです。 JavaでList<Integer>
をint[]
に変換する方法を教えてください。 List.toArray()
は実際にはObject[]
を返すので、私は混乱します。これは、他のInteger[]
またはint[]
にキャストすることができます。
今はループを使っています。
int[] toIntArray(List<Integer> list){
int[] ret = new int[list.size()];
for(int i = 0;i < ret.length;i++)
ret[i] = list.get(i);
return ret;
}
もっと良い方法があると確信しています。
残念ながら、これを行うためのより良い方法は、Javaがプリミティブ型、ボクシング、配列、および総称を処理するという性質のために、本当にisがあるとは思わない。特に:
Integer
からint
への変換がないため、List<T>.toArray
は機能しませんint
を総称の型引数として使用することはできません。そのため、haveをint
特有のメソッド(または、厄介なトリックを行うためにリフレクションを使用するメソッド)にすることができます。私は、すべてのプリミティブ型に対してこの種のメソッドの自動生成バージョンを持つライブラリがあると思います(すなわち、それぞれの型に対してコピーされるテンプレートがあります)。それは醜いです、しかしそれは私が恐れている方法です:(
Arrays
クラスがジェネリックがJavaに到着する前に出てきたとしても、それが今日導入されたならそれはまだすべての恐ろしいオーバーロードを含まなければならないでしょう(あなたがプリミティブ配列を使いたいと仮定して)。
誰もまだJava 8で追加されたストリームについて言及していないので、ここでそれは行きます:
int[] array = list.stream().mapToInt(i->i).toArray();
思考プロセス:
Stream#toArray
はObject[]
を返すので、それは私たちが望むものではありません。ジェネリック型A
はプリミティブint
を表すことができないため、Stream#toArray(IntFunction<A[]> generator)
は望んでいたことをしません。int
メソッドはおそらくint[]
配列も返すことになるので(ここではObject[]
のような何かを返すか、ボックス化されたInteger[]
さえ不自然になるので)、プリミティブ型toArray
を処理できるストリームを用意するといいでしょう。そして幸いなことに、Java 8はそのようなストリームを持っています:IntStream
それで、私たちが理解する必要があるのは、Stream<Integer>
(list.stream()
から返される)をその光沢のあるIntStream
に変換する方法だけです。ここでmapToInt
メソッドが助けになります。私たちがする必要があるのはInteger
からint
へのマッピングを提供することだけです。 int
を返すInteger#getValue
のようなものを使うことができます。
mapToInt( (Integer i) -> i.intValue())
(あるいは誰かがmapToInt(Integer::intValue)
を好む場合)
コンパイラはこのラムダの結果がint
でなければならないことをコンパイラが知っているので、同様のコードを生成することができます(mapToInt
のlambdaはToIntFunction
を返すと期待されるint applyAsInt(T value)
メソッドのbodyを期待するint
インタフェースの実装です)。
だから私たちは簡単に書くことができます
mapToInt((Integer i)->i)
またはより単純です(List<Integer>#stream()
はInteger i
を返すので、Stream<Integer>
型はコンパイラによって推測できるため)
mapToInt(i -> i)
Commons Langに加えて、 Guava のメソッド Ints.toArray(Collection<Integer> collection)
でこれを行うことができます。
List<Integer> list = ...
int[] ints = Ints.toArray(list);
これにより、Commons Langと同等のものに必要な中間配列変換を行う必要がなくなります。
これを行う最も簡単な方法は Apache Commons Lang を使用することです。それはあなたがやりたいことができる便利なArrayUtilsクラスを持っています。 toPrimitive
の配列には、 Integer
メソッドをオーバーロードとともに使用します。
List<Integer> myList;
... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));
このようにあなたは車輪を再発明しないでください。 Commons Langには、Javaが省いた便利なことがたくさんあります。上記では、適切なサイズの整数リストを作成することにしました。長さ0の静的整数配列を使用して、Javaに正しいサイズの配列を割り当てることもできます。
static final Integer[] NO_INTS = new Integer[0];
....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));
int[] toIntArray(List<Integer> list) {
int[] ret = new int[list.size()];
int i = 0;
for (Integer e : list)
ret[i++] = e;
return ret;
}
(Listは必ずしもArrayListである必要はありませんが、ランダムアクセスが高価なリンクリストである可能性があるため)コードのわずかな変更を行うことで、リストのインデックス処理が高価になるのを避けます
Java 8 はストリームでこれを行う簡単な方法を提供してくれます...
コレクションのstream()
関数を使用してからintにマッピングすると、IntStreamが得られます。 IntStream
を使えば、toArray()を呼び出すことができ、int []
が得られます。
int [] ints = list.stream().mapToInt(Integer::intValue).toArray();
これは Java 8 これの単一行コードです。
public int[] toIntArray(List<Integer> intList){
return intList.stream().mapToInt(Integer::intValue).toArray();
}
この単純なループは常に正しいです。バグなし
int[] integers = new int[myList.size()];
for (int i = 0; i < integers.length; i++) {
integers[i] = myList.get(i);
}
単にInteger
をint
にマッピングするのであれば、マッピングロジックはその範囲外の変数に依存しないため、 parallelismを使用して を検討する必要があります。
int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();
これに気をつけて
十分なデータコアとプロセッサコアがある場合は、並列処理のほうが自動的に速くなるわけではありません。集約操作を使用すると並列処理をより簡単に実装できますが、アプリケーションが並列処理に適しているかどうかを判断するのはユーザーの責任です。
整数をそれらの原始形式にマッピングするには2つの方法があります。
ToIntFunction
を介して。
mapToInt(Integer::intValue)
明示的に ボックス化解除 を使用してラムダ式。
mapToInt(i -> i.intValue())
ラムダ式による暗黙的な(自動)アンボックス化を介して。
mapToInt(i -> i)
null
の値を持つリストが与えられた
List<Integer> list = Arrays.asList(1, 2, null, 4, 5);
null
を処理するための3つのオプションがあります。
マッピングする前にnull
値を除外してください。
int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
null
値をデフォルト値にマップします。
int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
ラムダ式の中でnull
を処理します。
int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
もう1つここに投げます。 forループの使い方がいくつかありますが、ループの内側には何も必要ありません。これは、元の質問が冗長度の低いコードを見つけようとしていたためにのみ起こります。
int[] toArray(List<Integer> list) {
int[] ret = new int[ list.size() ];
int i = 0;
for( Iterator<Integer> it = list.iterator();
it.hasNext();
ret[i++] = it.next() );
return ret;
}
Javaがforループ内でC++のように複数の宣言を許可している場合は、さらに一歩進んでfor(int i = 0、Iterator it ...)を実行できます。
結局のところ(この部分は私の意見です)、あなたがあなたのために何かをするための支援機能や方法を持つつもりなら、それを設定してそれを忘れてください。それは1ライナーまたは10にすることができます。二度と見ないと違いがわかりません。
ToArrayはObject []を返し、Object []からint []、またはInteger []からint []にキャストすることはできないため、実際に行おうとしていることを「一行」にする方法はありません。
int[] ret = new int[list.size()];
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {
ret[i] = iter.next();
}
return ret;
ドル ( このリビジョンをチェックしてください ):
import static com.humaorie.dollar.Dollar.*
...
List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
Eclipse Collections を使用すると、タイプJava.util.List<Integer>
のリストがある場合は、次のことができます。
List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
MutableList
のようなEclipseコレクション型が既にある場合は、次のようにすることができます。
MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = integers.asLazy().collectInt(i -> i).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
注:私はEclipseコレクションのコミッターです
JavaコレクションAPIのList<?>
スケルトン実装を使用することをお勧めします。この特定のケースでは非常に役に立ちます。
package mypackage;
import Java.util.AbstractList;
import Java.util.Arrays;
import Java.util.Collections;
import Java.util.List;
public class Test {
//Helper method to convert int arrays into Lists
static List<Integer> intArrayAsList(final int[] a) {
if(a == null)
throw new NullPointerException();
return new AbstractList<Integer>() {
@Override
public Integer get(int i) {
return a[i];//autoboxing
}
@Override
public Integer set(int i, Integer val) {
final int old = a[i];
a[i] = val;//auto-unboxing
return old;//autoboxing
}
@Override
public int size() {
return a.length;
}
};
}
public static void main(final String[] args) {
int[] a = {1, 2, 3, 4, 5};
Collections.reverse(intArrayAsList(a));
System.out.println(Arrays.toString(a));
}
}
ボクシング/ボクシング解除の欠点に注意してください
ラムダを使用してこれを行うことができます(jdkラムダでコンパイル):
public static void main(String ars[]) {
TransformService transformService = (inputs) -> {
int[] ints = new int[inputs.size()];
int i = 0;
for (Integer element : inputs) {
ints[ i++ ] = element;
}
return ints;
};
List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };
int[] results = transformService.transform(inputs);
}
public interface TransformService {
int[] transform(List<Integer> inputs);
}