当前位置: 首页 > 知识库问答 >
问题:

如何使用流并行和filter及findFirst短路

沃学
2023-03-14

我有一个具有不同复杂性(进程持续时间)的txntype列表。
我想从列表中找到匹配的txntype
我试图通过混合流的并行处理和短路过滤功能来实现它。
但我注意到它们没有混合。
我编写了下面的示例。但注意到并行和短路的混合不能正常工作。
每次运行都显示并行处理在工作,但在找到项目时没有终止!!!

    class TxnType {
        public String id;   
        public TxnType(String id) {this.id = id;}
       
        public boolean match(String entry) {
            Date s = new Date();
            // simulate long processing match time TxnType
            if (id.equals("1")) {
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Date f = new Date();
            System.out.println("check id = " + id+ "  duration = "+(f.getTime()- s.getTime()));
    
            return id.equalsIgnoreCase(entry);
        }
    }

     private void test4() {
        // build list of available TxnTypes
        ArrayList<TxnType> lst = new ArrayList<>();
        lst.add(new TxnType("0"));
        lst.add(new TxnType("1"));  // long match processing time type
        lst.add(new TxnType("2"));
        lst.add(new TxnType("3"));
        lst.add(new TxnType("4"));

        String searchFor = "3";
        System.out.println("searchFor = " + searchFor);
        Date st, fi;

        st = new Date();
        Optional<TxnType> found2 =lst.stream().parallel().filter(txnType->txnType.match(searchFor)).findFirst();
            System.out.println("found.stream().count() = " + found2.stream().count());
            fi= new Date();
            System.out.println("dur="+ (fi.getTime()- st.getTime()));
    }

通过多次运行,我发现处理没有尽快终止,并等待处理所有这些!!!!

searchFor = 3
check id = 4  duration = 0
check id = 2  duration = 0
check id = 3  duration = 0
check id = 0  duration = 0
check id = 1  duration = 4005
found.stream().count() = 1
dur=4050

是否存在类似filterfindfirst()的内容?

共有1个答案

宗政元青
2023-03-14

您的错误是使用findfirst,而不是findany

请注意,1被排序在您期望找到的元素之前(3)。因此,它必须首先完成对1的检查,然后才能得出“3是第一个匹配谓词的元素”的结论,即使它们是并行执行的。如果它找到了3,并且还没有开始检查列表下面的内容,那么它就不会开始检查。这就是findfirst中的短路的含义。

另一方面,findany并不关心顺序。如果它发现任何满足谓词的元素,它就不再开始检查任何新的元素。

for (int i = 0 ; i < 100 ; i++) {
    lst.add(new TxnType("foo"));
}

...

Optional<TxnType> found2 = lst.parallelStream().filter(txnType -> txnType.match(searchFor)).findAny();

基本上,短路工作正常。只是

  • FindFirst不会像您希望的那样严重短路
  • 列表中的元素太少,而您的计算机有足够的核心来一次处理所有这些元素,因此确实如此。
 类似资料:
  • 我有一组从共享类型继承的域对象(即、)。子类型具有特定的属性(即、)。 此外,作为解析日志文件的结果,我有一个包含混合子类型的记录列表。 为了计算日志记录上的统计信息,我想只在匹配特定子类型的记录子集上应用数学函数,即只在s上应用数学函数。因此,我希望有一个特定子类型的过滤流。我知道可以使用以下方法将和应用到子类型 在流上多次应用这个filter&cast(特别是在对同一子类型进行多次不同计算时)

  • Java 8流#findFirst()是一种短路终端操作。这意味着一旦找到元素(通常与filter()操作一起使用),它将停止生成流。 但是,我想知道它是否会在平面图创建的流上短路。即它会短路在平面图操作中创建的流。 换句话说,哪种代码更有效(在流中生成的元素更少): 示例1(使用平面图): 示例2(无平面图):

  • 问题内容: 假设我有一个布尔值流,而我正在编写的reduce操作是||(OR)。我是否可以这样编写它:如果true遇到值,则放弃对至少某些元素的求值? 我正在寻找某种程度的优化(也许是并行流),不一定要完全优化,尽管后者会很棒。 问题答案: 我怀疑您想要这种构造。 你可以看一下 Stream.of(1, 2, 3, 4).peek(System.out::println).anyMatch(i -

  • ,和在Python 2中完美工作。这里有一个例子: 但是在Python 3中,我收到以下输出: 如果有人能向我解释这是为什么,我将不胜感激。 为进一步清晰起见,代码截图:

  • 在Java8中,可以设置一个定制的forkJoinPool供并行流使用,而不是公共池。 我的问题是它在技术上是如何发生的? 流以任何方式都不知道它被提交给了自定义的forkJoinpool并且没有直接访问它的权限。那么最终如何使用正确的线程来处理流的任务呢? 我试着看源代码,但没有用。我的最佳猜测是在提交时的某个点设置了某个threadLocal变量,然后在稍后由流使用。如果是这样的话,为什么语言

  • 例如,如果我有如下代码: 我想弄清楚如何删除条件块,并在一个流中这样做。 如果我只是在筛选结果上调用“.map”,如果它找到了匹配的条目,这就可以工作。如果不是,我会得到一个NoSuchelementException。 您能想出一种方法在流中包含第一个条件而不使其变得更加复杂吗?