我有一组从共享类型继承的域对象(即grouprecord extends record
、requestrecord extends record
)。子类型具有特定的属性(即GroupRecord::GetCumulativeTime
、RequestRecord::GetResponseTime
)。
此外,作为解析日志文件的结果,我有一个包含混合子类型的记录列表。
List<Record> records = parseLog(...);
为了计算日志记录上的统计信息,我想只在匹配特定子类型的记录子集上应用数学函数,即只在grouprecord
s上应用数学函数。因此,我希望有一个特定子类型的过滤流。我知道可以使用以下方法将筛选
和映射
应用到子类型
records.stream()
.filter(GroupRecord.class::isInstance)
.map(GroupRecord.class::cast)
.collect(...
在流上多次应用这个filter&cast(特别是在对同一子类型进行多次不同计算时)不仅很麻烦,而且会产生大量重复。
class TypeFilter<T>{
private final Class<T> type;
public TypeFilter(final Class<T> type) {
this.type = type;
}
public Stream<T> filter(Stream<?> inStream) {
return inStream.filter(type::isInstance).map(type::cast);
}
}
TypeFilter<GroupRecord> groupFilter = new TypeFilter(GroupRecord.class);
SomeStatsResult stats1 = groupFilter.filter(records.stream())
.collect(...)
SomeStatsResult stats2 = groupFilter.filter(records.stream())
.collect(...)
这是可行的,但我发现这种方法对于这样一个简单的任务来说有点太多了。因此,我想知道,有没有更好的方法,或者是什么是最好的方法,以简洁和可读的方式使用流和函数来使这种行为可重用?
这要看你发现什么“更简洁、更可读”。我自己认为,你已经实现的方式是好的,因为它是。
但是,确实有一种方法可以做到这一点,即使用stream.flatmap
,从您使用它的地方来看,这种方法稍微短一点:
static <E, T> Function<E, Stream<T>> onlyTypes(Class<T> cls) {
return el -> cls.isInstance(el) ? Stream.of((T) el) : Stream.empty();
}
它要做的是将每个原始流元素转换为一个元素的stream
(如果元素具有预期的类型),或者转换为空的stream
(如果元素没有预期的类型)。
其用途是:
records.stream()
.flatMap(onlyTypes(GroupRecord.class))
.forEach(...);
这种方法有明显的权衡:
onlytypes
更好的名称。stream
对象相对重量级,创建如此多的对象可能会导致性能下降。但您不应该相信我的话,在重载下对这两个变体进行配置。static <E, R> Function<E, Stream<R>> filterAndMap(Predicate<? super E> filter, Function<? super E, R> mapper) {
return e -> filter.test(e) ? Stream.of(mapper.apply(e)) : Stream.empty();
}
原来的onlytypes
实现现在变为:
static <E, R> Function<E, Stream<R>> onlyTypes(Class<T> cls) {
return filterAndMap(cls::isInstance, cls::cast);
}
但是,还有一个折衷:生成的平面映射器函数现在将保存捕获的两个对象(谓词和映射器),而不是上面实现中的单个class
对象。这也可能是一种过度抽象的情况,但这取决于您需要代码的地方和原因。
,和在Python 2中完美工作。这里有一个例子: 但是在Python 3中,我收到以下输出: 如果有人能向我解释这是为什么,我将不胜感激。 为进一步清晰起见,代码截图:
我有以下代码: 有可能是。 有没有一种有效的方法可以避免出现NPE?
对于Java流,有没有理由使用而不是和的组合? 例如使用: 或
我有一个具有不同复杂性(进程持续时间)的txntype列表。 我想从列表中找到匹配的。 我试图通过混合流的并行处理和短路过滤功能来实现它。 但我注意到它们没有混合。 我编写了下面的示例。但注意到并行和短路的混合不能正常工作。 每次运行都显示并行处理在工作,但在找到项目时没有终止!!! 通过多次运行,我发现处理没有尽快终止,并等待处理所有这些!!!! 是否存在类似的内容?
我从对象和对象数组中更改了一个对象两次,这样在第一次迭代中,我过滤掉了几个对象,在第二次迭代中,我使用map更改了每个过滤后的对象。我能用减速机或更好的吗?
我有一个简单的流如下: 但Intellij建议我: “filter()”和“map()”可以互换。检查信息:报告流API调用链可以简化。它允许在遍历集合时避免创建冗余的临时对象。例如 collection.stream()→collection.for每个() collection.stream()。 Intellij给出的例子很容易理解,但我不明白为什么它建议我使用。 我查看了的来源,但没有找到