【问题标题】:Which FunctionalInterface should I use?我应该使用哪个功能接口?
【发布时间】:2018-12-22 06:38:49
【问题描述】:

我正在学习写一些 lambda 表示为FunctionalInterface。 所以,要添加我使用的两个整数:

BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> a + b;
System.out.println(biFunction.apply(10, 60));

给我输出 70。但是如果我这样写

BinaryOperator<Integer, Integer, Integer> binaryOperator = (a, b) -> a + b;

我收到一个错误提示

类型参数数量错误:3;必需:1

BinaryOperator 不是BinaryFunction 的孩子吗?如何改进?

【问题讨论】:

    标签: java java-8 functional-interface


    【解决方案1】:

    BinaryOperator

    因为BinaryOperator 可以处理单一类型的操作数和结果。即BinaryOperator&lt;T&gt;

    BinaryOperator 不是 BinaryFunction 的子代吗?

    是的。 BinaryOperator 执行 extends BiFunction。 但请注意文档状态(格式化我的):

    这是BiFunction 的特化,适用于 操作数和结果都是同一类型

    完整的表示如下:

    BinaryOperator<T> extends BiFunction<T,T,T>
    

    因此您的代码将适用于

    BinaryOperator<Integer> binaryOperator = (a, b) -> a + b;
    System.out.println(binaryOperator.apply(10, 60));
    

    IntBinaryOperator

    如果您要处理当前示例中的两个原始整数(添加我使用的两个整数),您可以将IntBinaryOperator FunctionalInterface 用作

    IntBinaryOperator intBinaryOperator = (a, b) -> a + b;
    System.out.println(intBinaryOperator.applyAsInt(10, 60));
    

    表示对两个int 值操作数的操作并产生 一个 int 值的结果。这是原始类型特化 BinaryOperatorint


    我用的是 Integer,我还能用 IntBinaryOperator

    是的,你仍然可以使用它但是注意IntBinaryOperator的表示

    Integer first = 10;
    Integer second = 60;
    IntBinaryOperator intBinaryOperator = new IntBinaryOperator() {
        @Override
        public int applyAsInt(int a, int b) {
            return Integer.sum(a, b);
        }
    };
    Integer result = intBinaryOperator.applyAsInt(first, second); 
    

    会导致您拆箱 firstsecond 到基元,然后自动装箱 总和作为result 类型Integer 的输出.

    注意:注意在 Integer 中使用 null-safe 值,否则你可能会得到一个 @ 987654343@.

    【讨论】:

    • 感谢您的回答。我正在使用Integer,我还能使用IntBinaryOperator吗?
    • @Mani 在这种情况下,最好使用BinaryOperator,因为IntBinaryOperator 会增加自动装箱和拆箱的开销。请参阅答案中的编辑。
    • 好的。再次感谢您的回答和解释。
    【解决方案2】:
    BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> a + b;
    

    可以用

    表示
    BinaryOperator<Integer> binaryOperator = (a, b) -> a + b;
    

    但通常您希望在 int 而不是 Integer 上执行算术计算,以避免拆箱计算(整数到整数)并再次装箱以返回结果(整数到整数):

    IntBinaryOperator intBinaryOperator = (a, b) -> a + b;
    

    附带说明,您还可以使用方法引用而不是 lambda 来计算两个 ints 之间的总和。
    Integer.sum(int a, int b) 是您要查找的内容:

    IntBinaryOperator biFunction = Integer::sum;
    

    【讨论】:

    • 感谢您的回答。我正在使用Integer,我还能使用IntBinaryOperator吗?另一个答案和文档为它读取原始类型操作。
    【解决方案3】:

    BinaryOperator 不是 BinaryFunction 的子代吗?

    是的,是的。如果你查看BinaryOperator的源代码,你会看到:

    public interface BinaryOperator<T> extends BiFunction<T,T,T> {
        // ...
    }
    

    所以你只需要修正你的语法:

    BinaryOperator<Integer> binaryOperator = (a, b) -> a + b;
    System.out.println(binaryOperator.apply(10, 60));
    

    如何改进?

    您可以使用IntBinaryOperator。它进一步简化了语法:

    IntBinaryOperator binaryOperator = (a, b) -> a + b;
    System.out.println(binaryOperator.applyAsInt(10, 60));
    

    【讨论】:

    • 感谢您的回答。我正在使用Integer,我还能使用IntBinaryOperator吗?另一个答案和文档为它读取原始类型操作。
    • @Mani 是的,它会自动从Integer拆箱到int
    • 我明白了。再次感谢您的回答。
    猜你喜欢
    • 2020-03-20
    • 2017-03-03
    • 2019-06-18
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    相关资源
    最近更新 更多