Java8ストリームAPIを使用したリストからランダムな要素を取得する最も効果的な方法は何ですか?ストリームAPIを使用してリストからランダムな要素を取得するにはどうすればよいですか?
Arrays.asList(new Obj1(), new Obj2(), new Obj3());
ありがとうございます。
Java8ストリームAPIを使用したリストからランダムな要素を取得する最も効果的な方法は何ですか?ストリームAPIを使用してリストからランダムな要素を取得するにはどうすればよいですか?
Arrays.asList(new Obj1(), new Obj2(), new Obj3());
ありがとうございます。
なぜストリームがありますか?あなただけのリストのサイズに0から乱数を取得し、このインデックスにget
を呼び出す必要があります:
Random r = new Random();
ElementType e = list.get(r.nextInt(list.size());
ストリームが面白いここであなたに何も与えないでしょうが、あなたが試すことができます:
Random r = new Random();
ElementType e = list.stream().skip(r.nextInt(list.size()-1).findFirst().get();
アイデアは、任意の数の要素をスキップします(最後の要素ではありません!)、最初の要素があれば取得します。その結果、Optional<ElementType
は空ではなく、get
でその値を抽出します。スキップした後、ここにはたくさんのオプションがあります。ここでストリームを使用すると、非常に非効率的である
...
注:これらのソリューションのいずれもアカウントの空のリストにかかりませんが、問題は非空のリストに定義されていること。あなたはストリームを使用するを持っている場合
は、私が仕事をして、非常に非効率的なコレクターはいえ、エレガントを書いた:
/**
* Returns a random item from the stream (or null in case of an empty stream).
* This operation can't be lazy and is inefficient, and therefore shouldn't
* be used on streams with a large number or items or in performance critical sections.
* @return a random item from the stream or null if the stream is empty.
*/
public static <T> Collector<T, List<T>, T> randomItem() {
final Random RANDOM = new Random();
return Collector.of(() -> (List<T>) new ArrayList<T>(),
(acc, elem) -> acc.add(elem),
(list1, list2) -> ListUtils.union(list1, list2), // Using a 3rd party for list union, could be done "purely"
list -> list.isEmpty() ? null : list.get(RANDOM.nextInt(list.size())));
}
使用法:それはリスト場合はNoSuchElementExceptionを生成します
@Test
public void standardRandomTest() {
assertThat(Stream.of(1, 2, 3, 4).collect(randomItem())).isBetween(1, 4);
}
空です。 – Andrew
@AndrewTobilko Okですが、空のリストからランダムな要素を抽出することは、常に定義されていません。あなたの解決策にも同じです... –
@ Jean-BaptisteYunés、感謝します、ありがとう。 – aekber