[英]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.