短いと甘い生成する方法があるList<Integer>
、または多分 Integer[]
またはint[]
、いくつかの連続した値でstart
の値end
値は?
つまり、次のものよりも短いが1に相当するものです。
void List<Integer> makeSequence(int begin, int end) {
List<Integer> ret = new ArrayList<>(end - begin + 1);
for (int i=begin; i<=end; i++) {
ret.add(i);
}
return ret;
}
グアバの使用は問題ありません。
更新:
パフォーマンス分析
この質問は、ネイティブJava 8とサードパーティのライブラリの両方を使用して、いくつかの良い答えを受け取ったので、すべてのソリューションのパフォーマンスをテストすると思いました。
最初のテスト[1..10]
は、次のメソッドを使用して、10要素のリストの作成をテストするだけです。
- classicArrayList:私の質問で上記のコード(そして基本的にはadarshrの回答と同じ)。
- eclipseCollections:Eclipseコレクション8.0を使用して、以下のドナルドの回答で提供されるコード。
- guavaRange:以下のdavebの回答で与えられたコード。技術的には、これはaを作成するの
List<Integer>
ではなく、aを作成します。ただし、順序どおりにContiguousSet<Integer>
実装さIterable<Integer>
れるため、ほとんどの場合私の目的で機能します。 - intStreamRange:以下のVladimirの回答に記載されているコードを使用
IntStream.rangeClosed()
します。これはJava 8で導入されました。 - streamIterate:Java 8で導入された機能も使用する、以下のCatalinの回答に示されているコード
IntStream
上記のすべてのサイズ10のリストについて、1秒あたりのキロオペレーションの結果を次に示します(数値が大きいほど優れています)。
...そしてサイズが10,000のリストの場合:
その最後のチャートは正しいです-EclipseとGuava以外のソリューションは遅すぎて、1ピクセルのバーを取得することさえできません!高速ソリューションは、他のソリューションよりも10,000〜20,000 倍高速です。
もちろん、ここで起こっているのは、guavaとeclipseのソリューションが実際には10,000要素のリストの種類を具体化しないことです。これらは、開始と終了の周りの固定サイズのラッパーにすぎません。各要素は、反復中に必要に応じて作成されます。このテストでは実際には反復しないため、コストは延期されます。他のすべてのソリューションは、実際に完全なリストをメモリに具体化し、作成のみのベンチマークで高額を支払います。
もう少し現実的なことをして、すべての整数を繰り返して合計します。したがって、IntStream.rangeClosed
バリアントの場合、ベンチマークは次のようになります。
@Benchmark
public int intStreamRange() {
List<Integer> ret = IntStream.rangeClosed(begin, end).boxed().collect(Collectors.toList());
int total = 0;
for (int i : ret) {
total += i;
}
return total;
}
ここでは、非実体化ソリューションが最速ですが、写真は大きく変わります。これがlength = 10です:
...および長さ= 10,000:
多くの要素での長い反復により、多くのことを均等化しますが、日食とグアバは、10,000要素のテストでも2倍以上の速さを保ちます。
したがって、本当にList<Integer>
、eclipseコレクションが必要な場合は、最良の選択のように見えますが、もちろん、よりネイティブな方法でストリームを使用する場合(たとえば、.boxed()
プリミティブドメインを忘れて削減を行う場合)、おそらくこれらすべてよりも速くなります。バリアント。
1おそらく、エラー処理を除いて、たとえばend
<の場合begin
、またはサイズが実装またはJVMの制限(たとえば、より大きい配列)を超えている場合2^31-1
。