6

我在遵循以下代码片段时遇到了麻烦:

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

我知道代码的结果是什么,并且在单元测试中是正确的,但我对番石榴或者这个实现如何/为什么工作并不太熟悉。此外,如果列表“价格”中存在空值,目前似乎也不安全?所以我追求的是:

  1. 代码如何工作的一般解释。
  2. 它目前是空安全的吗?如果不是,它怎么会变成这样?
4

2 回答 2

6

它创建了一个新的双打列表,它是原始的 0.88 *。

构造是:

匿名内部类

这是有时在 Java 中完成回调/闭包的一种方式。另请参阅Java 教程

new Function<Double, Double>() {
    public Double apply(final Double from) {
        return from *.88;
    }
}

使用上述函数回调

Iterables.transform(prices, *func*)

将结果转换为 ArrayList

上面的结果是一个Iterable,所以它需要存储到一个列表中。另请参阅Lists.newArrayList 与新 ArrayList

Lists.newArrayList( ... )
于 2013-07-10T03:51:28.280 回答
2

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

更传统的实现是这样的:

List<Double> discountedPrices = Lists.newArrayList();
for(Double price: prices) {
    discountedPrices.add(price * .88);
}

2)不完全确定你所说的空安全是什么意思?假设您的意思是如果列表“价格”包含空值会发生什么?如果是这样,番石榴在 Iterables.filter(Collection, Predicate) 中为您提供了另一种解决方案。在您的情况下,您希望过滤掉空值,并且为此目的有一个内置的番石榴谓词。因此,在您的情况下,您可以执行以下操作:

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

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

于 2013-07-10T03:53:57.607 回答