Java 奇怪的番石榴代码

Java 奇怪的番石榴代码,java,guava,Java,Guava,我在执行以下代码片段时遇到问题: prices = pricesService.getProductsByCategory(category); List<Double> discountedPrices = Lists.newArrayList(Iterables.transform(prices, new Function<Double, Double>() { public Double apply(final Double from) {

我在执行以下代码片段时遇到问题:

prices = pricesService.getProductsByCategory(category);
List<Double> discountedPrices = 
    Lists.newArrayList(Iterables.transform(prices, new Function<Double, Double>() {
        public Double apply(final Double from) {
            return from *.88;
        }
    }));
prices=pricesService.getProductsByCategory(类别);
列表折扣价格=
Lists.newArrayList(Iterables.transform(prices,newfunction()){
公共双人申请(最终双人从){
从*.88返回;
}
}));
我知道代码的结果是什么,它在单元测试中是正确的,但我对guava不太熟悉,也不太熟悉这个实现的工作原理。此外,如果“价格”列表中存在空值,目前看来也不安全?所以我想要的是:

  • 对代码如何工作的一般说明
  • 它当前是空安全的吗?如果不是的话,它是如何制造的

  • 它将创建一个新的双精度列表,其值为原始值的0.88*倍

    这些结构是:

    匿名内部类

    这是Java中有时执行回调/闭包的方式。另请参见本节

    将结果转换为ArrayList

    上面的结果是一个
    Iterable
    ,因此需要将其存储到列表中。另见

    1) 所以Guava有一个静态util类called Iterables,它有一个名为transform的方法,该方法将集合和Guava函数实例作为变量。在这种情况下,开发人员使用了一个内嵌匿名函数,该函数通过重写的方法“apply”返回一个双精度值

    更传统的实现应该是这样的:

    List<Double> discountedPrices = Lists.newArrayList();
    for(Double price: prices) {
        discountedPrices.add(price * .88);
    }
    
    List discountedPrices=Lists.newArrayList();
    对于(双倍价格:价格){
    折扣价格。增加(价格*.88);
    }
    
    2) 不完全确定空安全是什么意思?假设您的意思是如果列表“prices”包含空值会发生什么?如果是这样,guava在Iterables.filter(Collection,Predicate)中为您提供了另一个解决方案。在您的例子中,您希望过滤掉空值,并且有一个内置的guava谓词用于此目的。因此,在您的情况下,您可以执行以下操作:

     prices = Iterables.filter(prices, Predicates.notNull();
     List<Double> discountedPrices = Lists.newArrayList(
     Iterables.transform(prices, new Function<Double, Double>() {
            public Double apply(final Double from) {
                return from *.88;
            }
        }));
    
    prices=Iterables.filter(prices,Predicates.notNull();
    List discountedPrices=Lists.newArrayList(
    转换(价格,新函数(){
    公共双人申请(最终双人从){
    从*.88返回;
    }
    }));
    

    第一行返回的prices集合中没有空值,第二行的行为与之前完全相同,您可以安全地假设空值已被删除。

    哪个部分给您带来了麻烦?您是否阅读了
    .transform
    的文档?如果链中没有任何内容过滤掉空值,那么如何使其成为空值ll safe将是相当明显的,尽管您需要定义在这种情况下实际希望发生的事情。我想这对我来说只是有点陌生。将“transform”视为方法名称有点让我头疼。至于null部分,我只会检查from==null,我想?我不确定是否有不同的情况发生继续函数调用?将
    transform
    作为方法名有什么不对?当您理解此代码的作用时,请务必阅读:(并测试命令式方法和函数式方法的性能)。“Null-safe”是一个误导性术语。另一个短语可能是“不会告诉您代码中可能指示细微错误的空定时炸弹。"
    过滤器必须在
    转换之前应用,而不是在转换之后应用。否则,
    从*.88
    中隐式取消装箱将抛出
    NullPointerException
    。因此,这或多或少是解决此问题的一种函数式编程风格?在Java中没有看到太多函数行为!也有很棒的链接,谢谢!Kin当然,是的……在下一个JavaSE中可能会有一个语法速记,这种风格会变得更加简洁,在Groovy风格中。顺便说一句,这种风格在一些web框架中被大量使用,例如Wicket
    Lists.newArrayList( ... )
    
    List<Double> discountedPrices = Lists.newArrayList();
    for(Double price: prices) {
        discountedPrices.add(price * .88);
    }
    
     prices = Iterables.filter(prices, Predicates.notNull();
     List<Double> discountedPrices = Lists.newArrayList(
     Iterables.transform(prices, new Function<Double, Double>() {
            public Double apply(final Double from) {
                return from *.88;
            }
        }));