1. ホーム
  2. java

[解決済み] Javaで連続した整数のリストや配列を生成するにはどうすればよいですか?

2022-04-25 10:01:47

質問

を生成する簡単な方法はありますか? 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とサードパーティのライブラリの両方を使用した、いくつかの良い回答が寄せられているので、すべてのソリューションのパフォーマンスをテストしてみようと思いました。

最初のテストは、10個の要素からなるリストを作成するテストです。 [1..10] を使用しています。

  • classicArrayList : 私の質問で上にあげたコード(そして本質的にはadarshrの答えと同じです)。
  • eclipseCollections で指定されたコードは ドナルドの答え Eclipse Collections 8.0を使用しています。
  • グアバレンジ で指定されたコードは davebの回答 の下にあります。技術的には、これでは List<Integer> ではなく ContiguousSet<Integer> - を実装しているので Iterable<Integer> を順次追加していくことで、私の目的にはほぼ合致しています。
  • intStreamRange で指定されたコードです。 ウラジミール氏の回答 を使用しています。 IntStream.rangeClosed() - は、Java 8で導入された。
  • ストリームイテレート で指定されたコードです。 カタリンさんの回答 を使用しています。 IntStream の機能は、Java 8 で導入されました。

以下は、サイズ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。

多くの要素で長いイテレーションを行うと、状況は大きく変わりますが、1万要素のテストでもeclipseとguavaは2倍以上の速さを維持しています。

だから、もしあなたが 本当に が欲しい。 List<Integer> もちろん、ストリームをよりネイティブな方法で使用する場合(たとえば、"get "を忘れてしまうなど)、eclipse collectionsは最良の選択肢のように思われます。 .boxed() プリミティブドメインでリダクションを行うことで、おそらくこれらのすべてのバリエーションよりも高速になるはずです。


1 おそらく、エラー処理を除いて、例えば、もし end < begin を超える場合、あるいは、実装やJVMの制限を超える場合(例えば、配列が 2^31-1 .

解決方法は?

Java 8では、とてもシンプルなので、もう別のメソッドも必要ありません。

List<Integer> range = IntStream.rangeClosed(start, end)
    .boxed().collect(Collectors.toList());