将ImmutableCollection作为参数与创建本地副本

时间:2013-08-12 13:08:03

标签: java guava

当使用Guava时,ImmutableCollection作为函数的参数,最好是要求ImmutableCollection作为参数类型:

void <T> foo(ImmutableCollection<T> l)

或者该函数应该采用Collection<T>并在

中创建一个不可变的集合
void <T> foo(Collection<T> l)
{
    ImmutableCollection<T> l2 = ImmutableCollection.copyOf(l);

    // ...
}

第一个版本似乎更可取,因为调用者确信他传递给函数的地图不会被它修改。但是第一个版本需要带有集合的客户端代码来调用copyOf(),即:

Collection collection = map.values();
foo(ImmutableCollection.copyOf(collection));

// instead of simply

foo(collection);

PS:这不完全正确,因为ImmutableCollection没有copyOf()ImmutableListImmutableSet没有。

5 个答案:

答案 0 :(得分:3)

我认为这取决于foo函数应该对集合参数做什么。

  • 如果foo要阅读集合元素,那么void <T> foo(Collection<T> l)更可取,因为它会将决定留给调用者。

  • 如果foo要将集合合并到某个对象的状态中,那么可以优选不可变集合。但是,我们需要问问自己,foo方法是否应该负责处理此问题,或者调用者的责任。

没有一个权利(或“最佳实践”)答案。但是,使用ImmutableCollection作为参数的正式类型可能会导致复杂性和/或在某些情况下不必要的复制

答案 1 :(得分:2)

查看番石榴文档:"copyOf is smarter than you think."

因此,您可以使用通用Collection接口,而不会感到遗憾。

在我看来,复制是否必要(而不是功能评论)取决于您持有多长时间的数据。

答案 2 :(得分:0)

使用更通用的Collection接口;你写一次电话要好得多,要求所有的客户都要在每次电话会议上这样做。如果您真的关心性能,并且性能分析表明它是一个问题,您可以对传入的集合进行类检查,看看是否可以避免复制。

答案 3 :(得分:0)

这取决于foo正在做什么。很可能它只是简单地读取集合值,在这种情况下它不需要复制它,特别是不可变的集合值。

答案 4 :(得分:0)

使用ImmutableCollection的一个优点是该方法可以保证它不会修改集合。但是那个保证只针对用户,平台不理解它,所以你不妨在评论或自定义注释中表达它。