我尝试使用Streams API将以下Scala行转换为Java8:
// Scala
util.Random.shuffle((1 to 24).toList)
为了在 Java 中编写等效项,我创建了一个整数范围:
IntStream.range(1, 25)
我怀疑在流API中找到了一个toList
方法,但IntStream
只知道奇怪的方法:
collect(
Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)
如何使用Java 8 Streams API无序排列列表?
给你:
List<Integer> 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]
您可能会发现以下toSchffled List()
方法很有用。
private static final Collector<?, ?, ?> SHUFFLER = Collectors.collectingAndThen(
Collectors.toCollection(ArrayList::new),
list -> {
Collections.shuffle(list);
return list;
}
);
@SuppressWarnings("unchecked")
public static <T> Collector<T, ?, List<T>> toShuffledList() {
return (Collector<T, ?, List<T>>) SHUFFLER;
}
这将启用以下类型的单行:
IntStream.rangeClosed('A', 'Z')
.mapToObj(a -> (char) a)
.collect(toShuffledList())
.forEach(System.out::print);
示例输出:
AVBFYXIMUDENOTHCRJKWGQZSPL
您可以使用自定义比较器按随机值对值进行“排序”:
public final class RandomComparator<T> implements Comparator<T> {
private final Map<T, Integer> 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());
这个解决方案的优点是它集成在流管道中。