Java 流生成直到限制,但仅匹配谓词

Java 流生成直到限制,但仅匹配谓词,java,java-stream,Java,Java Stream,如何使用100个元素的流生成列表。但是列表中的所有元素都应该匹配一个谓词 测试代码: import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.function.Predicate; import java.util.stream.Stream; public class Main { // My predicate public static

如何使用100个元素的流生成列表。但是列表中的所有元素都应该匹配一个谓词

测试代码:



import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Predicate;
import java.util.stream.Stream;


public class Main {
    // My predicate
    public static Predicate<Integer> isBig() {
        return p -> p > 10;
    }

    public static void main(String args[]) {
        List<Integer> list = new ArrayList<>();

        Stream.generate(new Random()::nextInt)
                .limit(100)
                //???????
                .forEach(a -> list.add(a));

        // Always needs to be 100
        System.out.println(list.size());
    }
}
如何做到这一点?

像这样:

List<Integer> list = Stream.generate(new Random()::nextInt)
                .filter(p -> p > 10)
                .limit(100).collect(Collectors.toList());
或者像这样:

public class Main {

    private static boolean isBig(Integer input) {
        return input > 10;
    }

    public static void main(String args[]) {
        List<Integer> list = Stream.generate(new Random()::nextInt)
                .filter(Main::isBig)
                .limit(100).collect(Collectors.toList());
    }
}
编辑:

如果您可以做任何您想做的事情,请不要对具有伪随机数源的流使用filter方法

如果你这样做了,你将在最好的情况下运行性能下降,在最坏的情况下进入挂起程序

这是因为如果你只是随机数和过滤他们,你很可能会产生更多的数字比你需要的。 例如,如果您想要100个偶数随机数,您平均需要生成200个随机数

最坏的情况是,如果PRNG有一个坏种子,并且只通过与谓词不匹配的数字循环,因此您永远无法收集所需数量的数字

总结:如果你需要n个满足某个谓词的随机数,例如正数,如果可能,只需创建n个随机数,并将与谓词不匹配的随机数映射到匹配的随机数,例如,将负数的绝对值设为只有正数

原始答案

如果要过滤流,只需使用方法过滤器: 像

随机r=新随机; 列表=Stream.generate->r.nextInt .filtern->n>0//过滤正数 .filtern->n%2==0//对偶数进行筛选 有限公司 .toList; 但是你应该小心你的流源。如果使用PRNG,则应尽量限制生成的数字范围

例如,上面的例子可以通过

Random r = new Random();
List<Integer> list = Stream.generate(() -> r.nextInt(Integer.MAX_VALUE/2) * 2)
    .limit(10)
    .collect(Collectors.toList());
并且是首选,因为第一个示例可能会遇到一个伪随机数循环,而这些伪随机数永远不会满足要求


所以一般来说。如果您处理的是随机源,请尝试从输入中创建所需的数字,而不要过滤随机输入。

将过滤器置于限制之前。您对流中元素的具体偏好是什么?您试图根据什么进行筛选?stream.filterpredicate::test.limit100.collectCollectors.toList;或者类似的。仅显示@Slaw引用的代码示例。@BeUndead使用筛选器不会使列表大小始终为100。正确。不过,使用我也包含的“限制”也可以。我使用了您的代码,但使用筛选器时列表的大小不是100。大小必须始终为100。所以它需要不断填充匹配的整数,直到它达到100。这是因为我使用10作为限制值,就像一个例子。只需将极限方法的参数更改为你想要的任何一个。@奥尼尔也请阅读整个答案。我非常不喜欢使用随机数源结合后面的随机数过滤。@ O-NIEL,您也可以考虑使用,虽然该方法返回一个ItSt流而不是流。我使用了您的代码,但是使用过滤器时列表的大小不是100。大小必须始终为100。所以它需要不断填充匹配的整数,直到它达到100。我刚刚运行了它,它正好是100。我的错,我在过滤器之前设置了限制。
Random r = new Random();
List<Integer> list = Stream.generate(() -> r.nextInt(Integer.MAX_VALUE/2) * 2)
    .limit(10)
    .collect(Collectors.toList());