我应该使用哪个FunctionalInterface?

时间:2018-12-22 06:38:49

标签: java java-8 functional-interface

我正在学习写一些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的孩子吗?我该如何改善?

3 个答案:

答案 0 :(得分:10)

BinaryOperator

由于BinaryOperator处理一种类型的操作数和结果。即BinaryOperator<T>

  

BinaryOperator不是BinaryFunction的子代吗?

是的。 BinaryOperatorextends 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值的操作数进行的运算并产生   整数值的结果。这是原始类型专门化   BinaryOperator代表int


  

我正在使用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); 

会给您带来 unboxing firstsecond到基元的费用,然后 autoboxing 的总和作为{{1}的输出},类型为result

注意 :请谨慎使用Integer null-safe值,否则可能会导致Integer

答案 1 :(得分:6)

DECLARE @ProductRecipe TABLE (ProductRecipeID INT, ComponentProductID INT)
INSERT INTO @ProductRecipe (ProductRecipeID, ComponentProductID) VALUES (21, 130)
INSERT INTO @ProductRecipe (ProductRecipeID, ComponentProductID) VALUES (21, 468)
INSERT INTO @ProductRecipe (ProductRecipeID, ComponentProductID) VALUES (21, 500)
INSERT INTO @ProductRecipe (ProductRecipeID, ComponentProductID) VALUES (22, 468) --values were (22, 130) in question
INSERT INTO @ProductRecipe (ProductRecipeID, ComponentProductID) VALUES (22, 500)
INSERT INTO @ProductRecipe (ProductRecipeID, ComponentProductID) VALUES (23, 130)
INSERT INTO @ProductRecipe (ProductRecipeID, ComponentProductID) VALUES (23, 501)

DECLARE @ComponentPricing TABLE (PricingID INT, ProductID INT)
INSERT INTO @ComponentPricing (PricingID, ProductID)
VALUES (314023, 130)
 , (313616, 130)
 , (313071, 130)
 , (312865, 130)
 , (316323, 468)
 , (316329, 468)
 , (398864, 500)

; with base as
    (
        --Joining the two datasets together.
        select pr.ProductRecipeID
        , pr.ComponentProductID
        , cp.PricingID
        from @ProductRecipe as pr
        left join @ComponentPricing as cp on pr.ComponentProductID = cp.ProductID   
    )
    , pr_exclude as
    (
        --Identifying that ProductRecipeID 23 should be excluded because of the 501 NULL value
        select distinct b.ProductRecipeID
        from base as b
        where b.PricingID is null   
    )
    , final_base as
    (
        --Assigning Rank to each ComponentProductID
        select b.ProductRecipeID
        , b.ComponentProductID
        , b.PricingID
        , dense_rank() over (partition by b.ProductRecipeID order by b.ComponentProductID asc) as prod_rnk
        from base as b
        left join pr_exclude as p on b.ProductRecipeID = p.ProductRecipeID
        where 1=1
        and p.ProductRecipeID is null
    )
--Joining it all together
select a.ProductRecipeID
, a.PricingID as Component1
, b.PricingID as Component2
, c.PricingID as Component3
, d.PricingID as Component4
, e.PricingID as Component5
from final_base as a
left join final_base as b on a.ProductRecipeID = b.ProductRecipeID and b.prod_rnk = 2
left join final_base as c on b.ProductRecipeID = c.ProductRecipeID and c.prod_rnk = 3
left join final_base as d on c.ProductRecipeID = d.ProductRecipeID and d.prod_rnk = 4
left join final_base as e on d.ProductRecipeID = e.ProductRecipeID and e.prod_rnk = 5
where a.prod_rnk = 1
order by 1, 2, 3, 4, 5, 6

可以用

表示
BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> a + b;

但是通常您希望对BinaryOperator<Integer> binaryOperator = (a, b) -> a + b; 而不是int进行算术运算,以避免拆箱计算(从Integer到int)并再次装箱以返回结果(从int到Integer):< / p>

Integer

请注意,您还可以使用方法引用而不是lambda来计算两个IntBinaryOperator intBinaryOperator = (a, b) -> a + b; 之间的和。
Integer.sum(int a, int b)是您要寻找的:

int

答案 2 :(得分:4)

  

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));