Как получить случайный выбор элементов с помощью потоков

#java #java-stream

Вопрос:

Есть ли способ получить случайный выбор элементов (без повторов) из потока, если вы даете ему случайный поток ввода?

Например, у меня есть список из тысячи виджетов, и я хочу случайным образом выбрать 25 виджетов из этого списка. Могу ли я сделать это, создав случайный поток int (с числами от 0 до 999) и используя его против потока виджетов?

Комментарии:

1. Я не уверен, что понимаю ваш вопрос. Какие предметы? из какого ручья? вы даете ему средства.. отдать чему? откуда (из какого источника) вы хотите получить случайный выбор?.. вы говорите о перетасовке чисел из коллекции? пожалуйста, будьте более конкретны.

2. Я полагаю , вы имеете в виду java.util.Random.ints() , в отличие от несуществующего ( java.util. ) Random.IntStream() .

3. Я также думаю, что вы имеете в виду, что случайный выбор должен выполняться из содержимого другого потока.

4. Что менее ясно, так это (i) ищете ли вы изменение порядка выбранных объектов, в отличие от простого принятия одних и отклонения других; (ii) почему важно, чтобы вы получали псевдослучайные числа из потока, а не непосредственно из a Random .

5. Мне жаль, что у вас был такой опыт, @GuyFawkes, но, похоже, вы зашли слишком далеко. То, что вы на самом деле ищете, неясно из того, что вы написали.

Ответ №1:

Вы можете сделать это следующим образом:

  • создайте экземпляр Random
  • создайте поток значений от 0 до widgetList.size()-1 включительно.
  • убедитесь, что они не повторяются (не исчезают).
  • ограничение до 25
  • возьмите виджет по этому индексу
  • храните в списке.
 List<Widget> widgetList;  // your populated Widget list
Random r = new Random();        
List<Widget> slice =     
    r.ints(0,1000).distinct().limit(25).mapToObj(widgetList::get).toList();
 

Это должно сработать. Но если верхняя граница списка (в данном случае 1000) меньше предела (25), он никогда не закончится.

Вы также можете просто перетасовать список и выбрать первые 25.

 Collections.shuffle(widgetList);