如何将 Stream 方法分配给 java 8 中的函数?
How to assign Stream method to a Function in java 8?
我有一个案例如下:
RowDataSet rdsHavingMaxNumericValue = dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.max((r1, r2) -> r1.getId().compareTo(r2.getId()))
.get();
我有两种情况需要根据具体情况查找最小值或最大值?我如何用函数替换第三行的调用最大值,以便它直接使用 .apply() 方法并执行操作?
我已成功分配 Collection.max 或 Collection 分钟,如下所示:
BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation = expComponents[0] == 'M' ? Collections::max : Collections::min;
我使用它如下:
RowDataSet rds = mrOrlrOperation.apply(dataList, <some comparator>);
只使用一个条件可能会更简单:
Stream<?> stream = dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null);
Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId);
RowDataSet rdsHavingMaxNumericValue =
expComponents[0] == 'M' ? stream.max(c).get() : stream.min(c).get();
如果需要,您可以将 min/max 操作存储在单独的 Function
中:
BiFunction<Stream<RowDataSet>, Comparator<RowDataSet>, RowDataSet>> operation =
expComponents[0] == 'M' ? (s, c) -> s.max(c).get() : (s, c) -> s.min(c).get();
RowDataSet rdsHavingMaxNumericValue = operation.apply(stream, c);
选择使用 min
而不是 max
与仍然使用 max
操作没有什么不同,但顺序相反,因此您可以使用
初始化:
Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId);
if(expComponents[0] != 'M') c = c.reversed();
实际操作
RowDataSet rdsHavingMaxNumericValue =
dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.max(c)
.get();
颠倒顺序对性能没有影响。它只是意味着调用 r2.getId().compareTo(r1.getId())
而不是 r1.getId().compareTo(r2.getId())
…
另一种选择是
Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId);
BinaryOperator<RowDataSet> op = expComponents[0] == 'M'?
BinaryOperator.maxBy(c): BinaryOperator.minBy(c);
RowDataSet rdsHavingMaxNumericValue =
dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.reduce(op)
.get();
您可以使用任一变体来创建您的 BiFunction
,例如
变体 1:
Function<Comparator<RowDataSet>, Comparator<RowDataSet>>
maxOrMin = expComponents[0] == 'M'? Function.identity(): Comparator::reversed;
BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation
= (dataList, comparator) -> dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.max(maxOrMin.apply(comparator))
.get();
变体 2:
Function<Comparator<RowDataSet>, BinaryOperator<RowDataSet>>
maxOrMin = expComponents[0] == 'M'? BinaryOperator::maxBy: BinaryOperator::minBy;
BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation
= (dataList, comparator) -> dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.reduce(maxOrMin.apply(comparator))
.get();
当然,您也可以忍受代码重复
BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation
= expComponents[0] == 'M'?
(dataList, comparator) -> dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.max(comparator)
.get():
(dataList, comparator) -> dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.min(comparator)
.get();
在任何一种情况下,条件 expComponents[0] == 'M'
仅在创建 BiFunction
时检查一次,并且在调用 mrOrlrOperation.apply(…)
时从不评估。
max
是归约运算,那么可以使用泛型reduce
:
public void reducing(BiOperator<...> myFunction) {
RowDataSet rdsHavingMaxNumericValue = dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.reduce((r1, r2) -> myFunction.apply(r1,r2))
.get();
}
...
reducing(Integer::max);
...
我有一个案例如下:
RowDataSet rdsHavingMaxNumericValue = dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.max((r1, r2) -> r1.getId().compareTo(r2.getId()))
.get();
我有两种情况需要根据具体情况查找最小值或最大值?我如何用函数替换第三行的调用最大值,以便它直接使用 .apply() 方法并执行操作?
我已成功分配 Collection.max 或 Collection 分钟,如下所示:
BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation = expComponents[0] == 'M' ? Collections::max : Collections::min;
我使用它如下:
RowDataSet rds = mrOrlrOperation.apply(dataList, <some comparator>);
只使用一个条件可能会更简单:
Stream<?> stream = dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null);
Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId);
RowDataSet rdsHavingMaxNumericValue =
expComponents[0] == 'M' ? stream.max(c).get() : stream.min(c).get();
如果需要,您可以将 min/max 操作存储在单独的 Function
中:
BiFunction<Stream<RowDataSet>, Comparator<RowDataSet>, RowDataSet>> operation =
expComponents[0] == 'M' ? (s, c) -> s.max(c).get() : (s, c) -> s.min(c).get();
RowDataSet rdsHavingMaxNumericValue = operation.apply(stream, c);
选择使用 min
而不是 max
与仍然使用 max
操作没有什么不同,但顺序相反,因此您可以使用
初始化:
Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId);
if(expComponents[0] != 'M') c = c.reversed();
实际操作
RowDataSet rdsHavingMaxNumericValue =
dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.max(c)
.get();
颠倒顺序对性能没有影响。它只是意味着调用 r2.getId().compareTo(r1.getId())
而不是 r1.getId().compareTo(r2.getId())
…
另一种选择是
Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId);
BinaryOperator<RowDataSet> op = expComponents[0] == 'M'?
BinaryOperator.maxBy(c): BinaryOperator.minBy(c);
RowDataSet rdsHavingMaxNumericValue =
dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.reduce(op)
.get();
您可以使用任一变体来创建您的 BiFunction
,例如
变体 1:
Function<Comparator<RowDataSet>, Comparator<RowDataSet>>
maxOrMin = expComponents[0] == 'M'? Function.identity(): Comparator::reversed;
BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation
= (dataList, comparator) -> dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.max(maxOrMin.apply(comparator))
.get();
变体 2:
Function<Comparator<RowDataSet>, BinaryOperator<RowDataSet>>
maxOrMin = expComponents[0] == 'M'? BinaryOperator::maxBy: BinaryOperator::minBy;
BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation
= (dataList, comparator) -> dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.reduce(maxOrMin.apply(comparator))
.get();
当然,您也可以忍受代码重复
BiFunction<List<RowDataSet>, Comparator<RowDataSet>, RowDataSet> mrOrlrOperation
= expComponents[0] == 'M'?
(dataList, comparator) -> dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.max(comparator)
.get():
(dataList, comparator) -> dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.min(comparator)
.get();
在任何一种情况下,条件 expComponents[0] == 'M'
仅在创建 BiFunction
时检查一次,并且在调用 mrOrlrOperation.apply(…)
时从不评估。
max
是归约运算,那么可以使用泛型reduce
:
public void reducing(BiOperator<...> myFunction) {
RowDataSet rdsHavingMaxNumericValue = dataList.stream()
.filter(r -> r.getLong(NUMERIC_VALUE) != null)
.reduce((r1, r2) -> myFunction.apply(r1,r2))
.get();
}
...
reducing(Integer::max);
...