[英]Java 8 streams intermediary map/collect to a stream with 2 values
想象一下,我有以下工作lambda表达式:
Map<Field, String> fields = Arrays.stream(resultClass.getDeclaredFields())
.filter(f -> f.isAnnotationPresent(Column.class))
.collect(toMap(f -> {
f.setAccessible(true);
return f;
}, f -> f.getAnnotation(Column.class).name()));
我想在filter语句之前创建一个具有2个值的流。 因此,我想进行映射,但仍然保留原始值。 我想实现以下目标:
this.fields = Arrays.stream(resultClass.getDeclaredFields())
//map to <Field, Annotation> stream
.filter((f, a) -> a != null)
.collect(toMap(f -> {
f.setAccessible(true);
return f;
}, f -> a.name()));
Java 8流是否可能? 我看过collect(groupingBy()),但仍然没有成功。
您需要类似Pair
东西,其中包含两个值。 您可以编写自己的代码,但这是一些重新利用AbstractMap.SimpleEntry
代码:
Map<Field, String> fields = Arrays.stream(resultClass.getDeclaredFields())
.map(f -> new AbstractMap.SimpleEntry<>(f, f.getAnnotation(Column.class)))
.filter(entry -> entry.getValue() != null)
.peek(entry -> entry.getKey().setAccessible(true))
.collect(toMap(Map.Entry::getKey, entry -> entry.getValue().name()));
您可以在collect
操作期间一次性完成整个操作,而无需配对类型:
Map<Field, String> fields = Arrays.stream(resultClass.getDeclaredFields())
.collect(HashMap::new, (m,f) -> {
Column c=f.getAnnotation(Column.class);
if(c!=null) {
f.setAccessible(true);
m.put(f, c.name());
}
}, Map::putAll);
不过,对我来说,将不会合并的两个操作分开看起来更干净:
Map<Field, String> fields = Arrays.stream(resultClass.getDeclaredFields())
.collect(HashMap::new, (m,f) -> {
Column c=f.getAnnotation(Column.class);
if(c!=null) m.put(f,c.name());
}, Map::putAll);
AccessibleObject.setAccessible(
fields.keySet().stream().toArray(AccessibleObject[]::new), true);
此解决方案对具有批注的字段进行两次迭代,但是由于此方法仅执行一次安全检查,而不是对每个字段进行一次检查,因此它可能仍然胜过所有其他解决方案。
通常,除非确实存在性能问题,否则您不应该尝试进行优化;如果这样做,则应该进行度量,而不要猜测运营成本。 结果可能令人惊讶,并且对数据集进行多次迭代不一定很糟糕。
@Peter Lawrey:我尝试了使用中间地图的建议。 它现在可以工作,但不是很漂亮。
this.fields = Arrays.stream(resultClass.getDeclaredFields())
.collect(HashMap<Field, Column>::new, (map, f) -> map.put(f, f.getAnnotation(Column.class)), HashMap::putAll)
.entrySet().stream()
.filter(entry -> entry.getValue() != null)
.peek(entry -> entry.getKey().setAccessible(true))
.collect(toMap(Map.Entry::getKey, entry -> entry.getValue().name()));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.