提问者:小点点

使用Java8 Streams API洗牌整数列表


我尝试使用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无序排列列表?


共3个答案

匿名用户

给你:

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());

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