@Bohemian shuffle , , , , Collector, :
public static <T> Collector<T, ?, Optional<T>> random() {
class Rnd {
T val;
int cnt;
void add(T t) {
cnt++;
if (ThreadLocalRandom.current().nextInt(cnt) == 0) {
val = t;
}
}
Rnd merge(Rnd other) {
cnt += other.cnt;
if (ThreadLocalRandom.current().nextInt(cnt) < other.cnt) {
val = other.val;
}
return this;
}
Optional<T> finish() {
return cnt == 0 ? Optional.empty() : Optional.of(val);
}
}
return Collector.of(Rnd::new, Rnd::add, Rnd::merge, Rnd::finish);
}
, x, - :
int largestX = list.stream().mapToInt(t -> t.x).max()
.getAsInt(); // or throw if list is empty
Tuple<Integer, String> randomLargestTuple = list.stream()
.filter(t -> largestX == t.x)
.collect(random())
.get();