使用Java 8 Streams API对整数列表进行随机播放

我尝试使用Streams API将以下Scala行转换为Java 8:

// Scala util.Random.shuffle((1 to 24).toList) 

要在Java中编写等效项,我创建了一系列整数:

 IntStream.range(1, 25) 

我怀疑在流API中找到了一个toList方法,但是IntStream只知道奇怪的方法:

 collect( Supplier supplier, ObjIntConsumer accumulator, BiConsumer combiner) 

如何使用Java 8 Streams API对列表进行混洗?

干得好:

 List integers = IntStream.range(1, 10) // <-- creates a stream of ints .boxed() // <-- converts them to Integers .collect(Collectors.toList()); // <-- collects the values to a list Collections.shuffle(integers); System.out.println(integers); 

打印:

 [8, 1, 5, 3, 4, 2, 6, 9, 7] 

您可能会发现以下toShuffledList()方法很有用。

 private static final Collector SHUFFLER = Collectors.collectingAndThen( Collectors.toList(), list -> { Collections.shuffle(list); return list; } ); @SuppressWarnings("unchecked") public static  Collector> toShuffledList() { return (Collector>) SHUFFLER; } 

这使得以下类型的单线:

 IntStream.rangeClosed('A', 'Z') .mapToObj(a -> (char) a) .collect(toShuffledList()) .forEach(System.out::print); 

输出示例:

 AVBFYXIMUDENOTHCRJKWGQZSPL 

您可以使用自定义比较器按随机值“排序”值:

 public final class RandomComparator implements Comparator { private final Map map = new IdentityHashMap<>(); private final Random random; public RandomComparator() { this(new Random()); } public RandomComparator(Random random) { this.random = random; } @Override public int compare(T t1, T t2) { return Integer.compare(valueFor(t1), valueFor(t2)); } private int valueFor(T t) { synchronized (map) { return map.computeIfAbsent(t, ignore -> random.nextInt()); } } } 

流中的每个对象(懒惰地)关联一个随机整数值,我们对其进行排序。 地图上的同步是处理并行流。

然后你就可以这样使用它:

 IntStream.rangeClosed(0, 24).boxed() .sorted(new RandomComparator<>()) .collect(Collectors.toList()); 

该解决方案的优点是它集成在流管道中。

要有效地执行shuffle,您需要提前获取所有值。 将流转换为类似于Scala中的列表后,可以使用Collections.shuffle()。

如果你正在寻找一个“仅限流媒体”的解决方案和一个确定性的解决方案,只需“偶然”排序而不是“随机”排序就足够了,你总是可以用一个哈希值对你的int排序:

 List xs=IntStream.range(0, 10) .boxed() .sorted( (a, b) -> a.hashCode() - b.hashCode() ) .collect(Collectors.toList()); 

如果您想要一个int[]不是List ,那么您可以在之后将它们取消装箱。 不幸的是,你已经通过拳击步骤来应用自定义Comparator ,所以没有消除这部分过程。

 List ys=IntStream.range(0, 10) .boxed() .sorted( (a, b) -> a.hashCode() - b.hashCode() ) .mapToInt( a -> a.intValue()) .toArray(); 

这是我的一线解决方案:我选择一种随机颜色:

 colourRepository.findAll().stream().sorted((o1,o2)-> RandomUtils.nextInt(-1,1)).findFirst().get()