err*_*ist 4 java enumeration java-8 java-stream
如何使用Java 8流方法(例如,对于数组,创建一个求值的地方),以惯用方式枚举Stream<T>哪个T实例将每个实例映射到一个唯一的整数?T[] valuesMap<T,Integer>Map.get(values[i]) == itrue
目前,我正在定义一个匿名类,它增加一个int字段以便与该Collectors.toMap(..)方法一起使用:
private static <T> Map<T, Integer> createIdMap(final Stream<T> values) {
return values.collect(Collectors.toMap(Function.identity(), new Function<T, Integer>() {
private int nextId = 0;
@Override
public Integer apply(final T t) {
return nextId++;
}
}));
}
Run Code Online (Sandbox Code Playgroud)
但是,使用Java 8流API是否没有更简洁/更优雅的方式? - 如果可以安全地并行化,则可获得奖励积分.
如果存在重复元素,您的方法将失败.
除此之外,您的任务需要可变状态,因此可以通过Mutable减少来解决.当我们填充地图时,我们可以简单地使用地图的大小来获取未使用的ID.
更棘手的部分是合并操作.以下操作只是重复右图的分配,这将处理潜在的重复.
private static <T> Map<T, Integer> createIdMap(Stream<T> values) {
return values.collect(HashMap::new, (m,t) -> m.putIfAbsent(t,m.size()),
(m1,m2) -> {
if(m1.isEmpty()) m1.putAll(m2);
else m2.keySet().forEach(t -> m1.putIfAbsent(t, m1.size()));
});
}
Run Code Online (Sandbox Code Playgroud)
如果我们依赖于唯一元素,或者插入一个显式distinct(),我们可以使用
private static <T> Map<T, Integer> createIdMap(Stream<T> values) {
return values.distinct().collect(HashMap::new, (m,t) -> m.put(t,m.size()),
(m1,m2) -> { int leftSize=m1.size();
if(leftSize==0) m1.putAll(m2);
else m2.forEach((t,id) -> m1.put(t, leftSize+id));
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
182 次 |
| 最近记录: |