У меня есть поток Java 8, из которого я хочу (равномерно) случайным образом выбрать элемент. Поток может содержать от нуля до десятков тысяч элементов.
Я реализовал алгоритм, который выбирает один, используя шаблон, похожий на MapReduce, но для очень маленьких потоков, вероятно, было бы более эффективно собирать элементы в список и возвращать один со случайным индексом. Тем не менее, я должен их сосчитать. У потоков есть метод count(), но это все их число, я действительно не заинтересован в фактическом счете, все, о чем я забочусь, заключается в том, содержит ли он больше, чем определенное число. Кто-нибудь знает, существует ли такой метод? Я не могу найти его, но может быть что-то, что я упускаю из виду, или какой-нибудь умный трюк, чтобы найти его в любом случае.
P.S.: Я знаю, что иногда не нужно оптимизировать код; но я хотел бы попробовать это, тем не менее, только для опыта. Я студент.
P.P.S.: Я скопировал свой алгоритм здесь, в случае, если кто-то заинтересован (или хочет искать ошибки, я еще не тестировал его;)
stream
.parallel()
.map(t -> new Pair<T, Integer>(t, 1))
.reduce((Pair<T, Integer> t, Pair<T, Integer> u) -> {
if (rand.nextDouble() <= (t.getValue1() / (double) (t.getValue1() + u.getValue1()))) {
return new Pair<>(t.getValue0(), t.getValue1() + u.getValue1());
} else {
return new Pair<>(u.getValue0(), t.getValue1() + u.getValue1());
}
})
.map(t -> t.getValue0());
(пары из org.javatuples, теперь, когда Java поддерживает функциональные программируемые интерфейсы, отсутствие кортежей становится немного болезненным).