我有一个具有不同复杂性(进程持续时间)的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()
的内容?
您的错误是使用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。 您能想出一种方法在流中包含第一个条件而不使其变得更加复杂吗?