The choice to use min instead of max is not different to still using the max operation, but with a reversed order, so you could use
Initialization:
Comparator<RowDataSet> c = Comparator.comparingLong(RowDataSet::getId); if(expComponents[0] != 'M') c = c.reversed();
Actual operation
RowDataSet rdsHavingMaxNumericValue = dataList.stream() .filter(r -> r.getLong(NUMERIC_VALUE) != null) .max(c) .get();
Reversing the order has no performance impact. It just implies calling r2.getId().compareTo(r1.getId()) instead of r1.getId().compareTo(r2.getId())…
An alternative would be
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();
This anticipates what min and max would do…
You can use either variant to create your BiFunction, e.g.
Variant 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();
Variant 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();
Of course, you could also live with a code duplication
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();
In either case, the condition expComponents[0] == 'M' is checked only once when the BiFunction is created and never evaluated when mrOrlrOperation.apply(…) is invoked.