Pau*_*ton 16 java java-8 java-stream
假设您有一个这样的方法来计算Collection某些方法的最大值ToIntFunction:
static <T> void foo1(Collection<? extends T> collection, ToIntFunction<? super T> function) {
if (collection.isEmpty())
throw new NoSuchElementException();
int max = Integer.MIN_VALUE;
T maxT = null;
for (T t : collection) {
int result = function.applyAsInt(t);
if (result >= max) {
max = result;
maxT = t;
}
}
// do something with maxT
}
Run Code Online (Sandbox Code Playgroud)
使用Java 8,可以将其转换为
static <T> void foo2(Collection<? extends T> collection, ToIntFunction<? super T> function) {
T maxT = collection.stream()
.max(Comparator.comparingInt(function))
.get();
// do something with maxT
}
Run Code Online (Sandbox Code Playgroud)
新版本的缺点function.applyAsInt是对于相同的值重复调用T.(特别是如果集合具有大小n,则foo1调用applyAsInt n时间,然后foo2调用它的2n - 2次数).
第一种方法的缺点是代码不太清晰,您无法修改它以使用并行性.
假设您希望使用并行流来执行此操作,并且applyAsInt每个元素仅调用一次.这可以用简单的方式编写吗?
Tun*_*aki 10
您可以使用自定义收集器来保持运行最大值和最大元素的对:
static <T> void foo3(Collection<? extends T> collection, ToIntFunction<? super T> function) {
class Pair {
int max = Integer.MIN_VALUE;
T maxT = null;
}
T maxT = collection.stream().collect(Collector.of(
Pair::new,
(p, t) -> {
int result = function.applyAsInt(t);
if (result >= p.max) {
p.max = result;
p.maxT = t;
}
},
(p1, p2) -> p2.max > p1.max ? p2 : p1,
p -> p.maxT
));
// do something with maxT
}
Run Code Online (Sandbox Code Playgroud)
一个优点是,这创建了一个Pair在整个收集过程中使用的单个中间对象.每次接受元素时,都会使用新的最大值更新此持有者.修整器操作只返回最大元素并且忽略最大值.
| 归档时间: |
|
| 查看次数: |
462 次 |
| 最近记录: |