Java8流-链中的每一步都针对整个输入进行评估,还是传递项目?

Java8流-链中的每一步都针对整个输入进行评估,还是传递项目?,java,java-8,java-stream,Java,Java 8,Java Stream,如果我有这个琐碎的程序 List<String> input = Arrays.asList("1", "2", "3"); List<String> result = input.stream() .map(x -> x + " " + x) .filter(y -> !y.startsWith("1")) .collect(Collectors.toList());

如果我有这个琐碎的程序

    List<String> input = Arrays.asList("1", "2", "3");
    List<String> result = input.stream()
            .map(x -> x + " " + x)
            .filter(y -> !y.startsWith("1"))
            .collect(Collectors.toList());
B


它的工作原理与选项B类似,不一定是按照那个确切的顺序,但更重要的是它一次对一个元素执行每个操作

这背后的原因是变量只传递流一次,因此当您现在拥有该元素时,您需要执行所有操作,因为元素一旦传递,它就会永远消失(从流的角度来看)

在线性设置中,您的代码大致相当于以下代码,这是一个非常简化的版本,但我希望您能理解:

Collection<String> input = Arrays.asList("1", "2", "3");
Function<String, String> mapper = x -> x + " " + x;
Predicate<String> filter = y -> !y.startsWith("1");
Collector<String, ?, List<String>> toList = Collectors.toList();

List<String> list = ((Supplier<List<String>>)toList.supplier()).get();
for (String in : input) {
    in = mapper.apply(in);
    if (filter.test(in)) {
        ((BiConsumer<List<String>, String>)toList.accumulator()).accept(list, in);
    }
}
Collection input=Arrays.asList(“1”、“2”、“3”);
函数映射器=x->x+“”+x;
谓词过滤器=y->!y、 以“1”开头;
收集器toList=收集器。toList();
列表=((供应商)toList.Supplier()).get();
for(字符串输入:输入){
in=映射器。应用(in);
if(过滤器测试(in)){
((双消费者)toList.acculator()).accept(列表,in);
}
}
你在这里看到的是:

  • 作为
    集合的输入
    ,您的输入
  • 映射()匹配的
    函数
  • A
    prediate
    匹配您的
    filter()
  • 与您的
    collect()
    匹配的
    收集器
    ,这是一个对
    字符串类型的元素进行操作的收集器,使用中间存储
    ,并提供一个
    列表
然后它所做的是:

  • 从催收员的供应商(类型:
    supplier
    )处获取新列表
  • 循环输入的每个元素,在
    上操作时在内部完成,我在这里使用
    集合
    来明确说明,这样我们仍然可以连接到旧的Java 7世界
  • 应用映射函数
  • 测试过滤器谓词
  • 获取
    toList
    收集器的累加器(类型:
    BiConsumer
    ),这是二进制使用者,它将其已有的
    列表
    和要添加的
    字符串
    作为参数
  • 列表
    中的
    输入累加器

请非常小心地注意,真正的实现要先进得多,因为操作可以以任何顺序发生,也可以发生多个操作,等等。

流的好处之一是。这意味着,当执行终端操作时,
collect()
(本例中为
collect()
),它会从上一个中间操作中请求一个元素-
filter()
,然后从
map()
中获取元素,而后者又对
list.stream()
中的第一个元素进行操作。所有元素遵循相同的流程。是的,执行更像是选项B


另外,由于
Collectors.toList()
返回的收集器是有序的,因此保证元素按顺序执行。在某些情况下,当为收集器设置CharacterEristic时,计算可能会出现顺序错误。

Wild guess:一次一个;但是您可以很容易地检查,通过在lambdasThanks中打印语句,我知道真正的实现要高级得多,但是你的解释通常就是我想要的。是否有任何可能的方法来获取谓词意味着用户定义的startsWith或包含什么,或者定义了什么条件。请注意,“方法B”行为允许流操作,如
findFirst()
findAny()
和其他“短路终端操作”要快。请注意,有状态的中间操作,如
sorted()
行为不同。谢谢,简单地说!
map
  "1" + " " + "1"
filter
  "1 1" does not begin with "1"? = false
map
  "2" + " " + "2"
filter
  "2 2" does not begin with "1"? = true
collect
  add "2 2" to list
map
  "3" + " " + "3"
filter
  "3 3" does not begin with "1"? = true
collect
  add "3 3" to list
result = List("2 2", "3 3")
Collection<String> input = Arrays.asList("1", "2", "3");
Function<String, String> mapper = x -> x + " " + x;
Predicate<String> filter = y -> !y.startsWith("1");
Collector<String, ?, List<String>> toList = Collectors.toList();

List<String> list = ((Supplier<List<String>>)toList.supplier()).get();
for (String in : input) {
    in = mapper.apply(in);
    if (filter.test(in)) {
        ((BiConsumer<List<String>, String>)toList.accumulator()).accept(list, in);
    }
}