在参数范围内找到最小函数

时间:2015-10-20 11:59:44

标签: java lambda java-8

我们假设我有:

int x = 5;
int y = 10;

和带签名的函数

public double CalculateEntropySplittingOnFeature(List<Sample> samples, int cutOffPoint) 

我想找到包含5到0之间的整数值,我的函数返回最低值。我的解决方案:

((List <Integer>) IntStream.range(x, y))
                .stream()
                .min(new Comparator<Integer>() {
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        return Double.compare(CalculateEntropySplittingOnFeature(samples, o2), CalculateEntropySplittingOnFeature(samples, o1));
                    }
                });

但是,我觉得有一个更好/更优雅(/更有效)的解决方案,而不是生成一个IntStream并将其转换为列表然后再次流式传输...任何建议?

3 个答案:

答案 0 :(得分:3)

((List <Integer>) IntStream.range(x, y))会抛出ClassCastException,因为IntStream未实现List<Integer>

使用

IntStream.range(x, y).boxed()

获得Stream<Integer>

编辑:

Optional<Integer> min =
    IntStream.range(x, y)
             .boxed ()
             .min ((o1,o2)->Double.compare(CalculateEntropySplittingOnFeature(samples, o2), 
                     CalculateEntropySplittingOnFeature(samples, o1)));

答案 1 :(得分:2)

您在评论中要求提供样式建议。我建议:

Optional<Integer> lowest = IntStream.range(0, 5).boxed()
    .min(Comparator.comparingDouble(n -> calcEntropySplittingOnFeatures(samples, n)));

答案 2 :(得分:0)

正如其他答案所述,您可以通过在其上调用IntStreamStream<Integer>转换为boxed()。但是,当您认为min(Comparator)只是reduce(BinaryOperator.minBy(Comparator))的捷径时,您可以在没有装箱的情况下进行操作。您可以为int值重新实现相同的操作:

OptionalInt result=IntStream.range(x, y).reduce((a,b)->
    CalculateEntropySplittingOnFeature(samples, a)<=
    CalculateEntropySplittingOnFeature(samples, b)? a: b);

由于这看起来并不像使用Comparator.comparingDouble(…)那样简洁,因此您可以本着BinaryOperator.minBy(Comparator.comparingDouble(…)))的精神使用辅助方法:

public static IntBinaryOperator minBy(IntToDoubleFunction f) {
    return (a,b) -> f.applyAsDouble(a)<=f.applyAsDouble(b)? a: b;
}

并将其用作

OptionalInt result=IntStream.range(x, y)
    .reduce(minBy(i -> CalculateEntropySplittingOnFeature(samples, i)));