使用Java8流API从列表中获取随机元素的最有效方法是什么?
Arrays.asList(new Obj1(), new Obj2(), new Obj3());
Run Code Online (Sandbox Code Playgroud)
谢谢.
Jea*_*nès 18
为什么有溪流?您只需要从0到列表大小的随机数,然后调用get此索引:
Random r = new Random();
ElementType e = list.get(r.nextInt(list.size()));
Run Code Online (Sandbox Code Playgroud)
Stream会在这里给你带来任何有趣的东西,但你可以尝试:
Random r = new Random();
ElementType e = list.stream().skip(r.nextInt(list.size()-1)).findFirst().get();
Run Code Online (Sandbox Code Playgroud)
想法是跳过任意数量的元素(但不是最后一个元素!),然后获取第一个元素(如果它存在).结果你将得到一个Optional<ElementType>非空的,然后用它提取它的值get.跳过后你有很多选择.
在这里使用流是非常低效的......
注意:这些解决方案都不考虑空列表,但问题是在非空列表中定义的.
小智 7
虽然所有给出的答案都有效,但有一个简单的单行代码可以做到这一点,而不必先检查列表是否为空:
List<String> list = List.of("a", "b", "c");
list.stream().skip((int) (list.size() * Math.random())).findAny();
Run Code Online (Sandbox Code Playgroud)
对于空列表,这将返回一个Optional.empty.
有很多更有效的方法,但是如果必须使用Stream,最简单的方法是创建自己的Comparator,它返回随机结果(-1、0、1)并对流进行排序:
List<String> strings = Arrays.asList("a", "b", "c", "d", "e", "f");
String randomString = strings
.stream()
.sorted((o1, o2) -> ThreadLocalRandom.current().nextInt(-1, 2))
.findAny()
.get();
Run Code Online (Sandbox Code Playgroud)
ThreadLocalRandom已准备好“开箱即用”的方法来获取比较器所需范围内的随机数。
上次我需要做类似的事情时,我这样做了:
List<String> list = Arrays.asList("a", "b", "c");
Collections.shuffle(list);
String letter = list.stream().findAny().orElse(null);
System.out.println(letter);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10408 次 |
| 最近记录: |