Guava使用的经验和教训

Guava使用的经验和教训

1.com.google.common.collect.Lists#transform(List<T> originList,Function function)
由于Lists.transform是延迟调用,返回的其实是originList的view,也就是当客户端遍历生成的列表时,给定的Function应用到originList的元素上,而且每一次遍历生成的列表都会重新应用一次。

核心代码

@Override
    public Iterator<T> iterator() {
      return listIterator();
    }

    @Override
    public ListIterator<T> listIterator(int index) {
      return new TransformedListIterator<F, T>(fromList.listIterator(index)) {
        @Override
        T transform(F from) {
          return function.apply(from);
        }
      };
    }
错误的使用场景
1. 通过线程池执行Callable任务,任务的返回结果是通过Lists.transform来完成的

错误代码示例

@Override
    public List<XXX> call() {
        return Lists.transform(Safes.of(list), new Function<P, XXX>() {

            @Override
            public ResultWrapper<R> apply(P input) {
                return fun.apply(input);
            }
        });
    }

通常我们的使用场景是在主线程中创建任务,然后将任务提交到ThreadPool中,然后获取Future,在主线程中调用Future.get(),然后处理结果。但是由于上述的错误示例,发现代码的逻辑并没有并行执行,而是拿到结果后在遍历的串行执行的,这个就是因为Lists.transform的惰性调用导致并行化失败。

2.对Lists.transform的结果进行二次处理,然后执行集合求交集、差集等涉及到equals的操作

错误代码示例

List<XXX> result = Lists.transform();
List<XXX> subList = Lists.newArrayList();
for(XXX x:result){
    if(true){
        subList.add(x);
    }
}
result = CollectionUtils.substract(result,subList);

然后会发现没有任何元素被移除,前提条件是XXX没有重写equals方法。

解决方法

问题的原因就是因为惰性加载导致的,所以如果Lists.transform后,可以对结果集进行一次copy(To avoid lazy evaluation when the returned list doesn't need to be a view, copy the returned list into a new list of your choosing.)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,932评论 18 399
  • 不同地域文化、风土人情,孕育出众多独具特色、饶有情趣的歌谣。从一定意义上讲,中国人是世界上最聪明的,即便是从没念过...
    发呆的老渔民阅读 5,542评论 0 1
  • 性格硬的人,或许命才硬,要想活着,她必须如此。 一个女人最大的不幸,是一辈子也没能爱上自己的丈夫,反而成了最大的敌...
    朱珠的故事阅读 1,391评论 0 0
  • 一 遵循着卡片上的地址,夏珞来到了这家位于郊区的地下宾馆。 宾馆入口是一扇毫不起眼的铁门,上面布满了斑驳的铁锈,看...
    离尹阅读 4,344评论 8 12