web-dev-qa-db-ja.com

JavaでList <Integer>をint []に変換するにはどうすればいいですか?

これはこの質問に似ています: 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;
}

もっと良い方法があると確信しています。

514
unknown

残念ながら、これを行うためのより良い方法は、Javaがプリミティブ型、ボクシング、配列、および総称を処理するという性質のために、本当にisがあるとは思わない。特に:

  • Integerからintへの変換がないため、List<T>.toArrayは機能しません
  • intを総称の型引数として使用することはできません。そのため、haveint特有のメソッド(または、厄介なトリックを行うためにリフレクションを使用するメソッド)にすることができます。

私は、すべてのプリミティブ型に対してこの種のメソッドの自動生成バージョンを持つライブラリがあると思います(すなわち、それぞれの型に対してコピーされるテンプレートがあります)。それは醜いです、しかしそれは私が恐れている方法です:(

Arrays クラスがジェネリックがJavaに到着する前に出てきたとしても、それが今日導入されたならそれはまだすべての恐ろしいオーバーロードを含まなければならないでしょう(あなたがプリミティブ配列を使いたいと仮定して)。

195
Jon Skeet

誰もまだJava 8で追加されたストリームについて言及していないので、ここでそれは行きます:

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

思考プロセス:

  • simple Stream#toArrayObject[]を返すので、それは私たちが望むものではありません。ジェネリック型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)

472
Pshemo

Commons Langに加えて、 Guava のメソッド Ints.toArray(Collection<Integer> collection) でこれを行うことができます。

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

これにより、Commons Langと同等のものに必要な中間配列変換を行う必要がなくなります。

189
ColinD

これを行う最も簡単な方法は 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));
168
Eddie
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である必要はありませんが、ランダムアクセスが高価なリンクリストである可能性があるため)コードのわずかな変更を行うことで、リストのインデックス処理が高価になるのを避けます

49
Mike

Java 8 はストリームでこれを行う簡単な方法を提供してくれます...

コレクションのstream()関数を使用してからintにマッピングすると、IntStreamが得られます。 IntStreamを使えば、toArray()を呼び出すことができ、int []が得られます。

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

からint []

へIntStreamへ

43
Pumphouse

これは Java 8 これの単一行コードです。

public int[] toIntArray(List<Integer> intList){
       return intList.stream().mapToInt(Integer::intValue).toArray();
}
12
Noor Nawaz

この単純なループは常に正しいです。バグなし

  int[] integers = new int[myList.size()];
  for (int i = 0; i < integers.length; i++) {
      integers[i] = myList.get(i);
  }
6
THANN Phearum

単にIntegerintにマッピングするのであれば、マッピングロジックはその範囲外の変数に依存しないため、 parallelismを使用して を検討する必要があります。

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

これに気をつけて

十分なデータコアとプロセッサコアがある場合は、並列処理のほうが自動的に速くなるわけではありません。集約操作を使用すると並列処理をより簡単に実装できますが、アプリケーションが並列処理に適しているかどうかを判断するのはユーザーの責任です。


整数をそれらの原始形式にマッピングするには2つの方法があります。

  1. ToIntFunctionを介して。

    mapToInt(Integer::intValue)
    
  2. 明示的に ボックス化解除 を使用してラムダ式。

    mapToInt(i -> i.intValue())
    
  3. ラムダ式による暗黙的な(自動)アンボックス化を介して。

    mapToInt(i -> i)
    

nullの値を持つリストが与えられた

List<Integer> list = Arrays.asList(1, 2, null, 4, 5);

nullを処理するための3つのオプションがあります。

  1. マッピングする前にnull値を除外してください。

    int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
    
  2. null値をデフォルト値にマップします。

    int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
    
  3. ラムダ式の中でnullを処理します。

    int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
    
6
Mr. Polywhirl

もう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にすることができます。二度と見ないと違いがわかりません。

6
Loduwijk

ToArrayはObject []を返し、Object []からint []、またはInteger []からint []にキャストすることはできないため、実際に行おうとしていることを「一行」にする方法はありません。

5
neesh
int[] ret = new int[list.size()];       
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {       
    ret[i] = iter.next();                
}                                        
return ret;                              
4
gerardw

ドルこのリビジョンをチェックしてください ):

import static com.humaorie.dollar.Dollar.*
...

List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
3
dfa

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コレクションのコミッターです

2
Donald Raab

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

ボクシング/ボクシング解除の欠点に注意してください

1
DennisTemper

ラムダを使用してこれを行うことができます(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);
    }
0
NimChimpsky