Java Collections API怪癖

因此,当涉及到Java Collections API时,我们倾向于认为已经了解了所有内容。 我们知道我们的身边方式列表设置地图Iterables迭代器 。 我们已经为Java 8的Collections API增强做好了准备。

但是随后,我们偶尔会偶然发现其中一个奇怪的怪癖,这些怪癖源于JDK的深度及其向后兼容的悠久历史。 让我们看看无法修改的集合

不可修改的收藏

Collections API不会反映集合是否可修改。 那里
不是不可变的ListSetCollection基类型,可变的子类型可以扩展。 因此,JDK中不存在以下API:

// Immutable part of the Collection API
public interface Collection {
  boolean  contains(Object o);
  boolean  containsAll(Collection<?> c);
  boolean  isEmpty();
  int      size();
  Object[] toArray();
  <T> T[]  toArray(T[] array);
}

// Mutable part of the Collection API
public interface MutableCollection 
extends Collection {
  boolean  add(E e);
  boolean  addAll(Collection<? extends E> c);
  void     clear();
  boolean  remove(Object o);
  boolean  removeAll(Collection<?> c);
  boolean  retainAll(Collection<?> c);
}

现在,可能有原因,为什么在Java早期就没有以这种方式实现事情。 很有可能,可变性不被视为值得在类型层次结构中占据其自身类型的功能。 因此,出现了Collections帮助器类,其中包含有用的方法,例如unmodifiableList()unmodifiableSet()unmodifiableCollection()以及其他方法。 但是要当心使用不可修改的集合! Javadoc中提到了一个非常奇怪的事情 :返回的集合不会将hashCode和equals操作传递到后备集合,而是依赖于Object的equals和hashCode方法。 在后备集合是集合或列表的情况下,必须保留这些操作的合同。 “保留这些行动的合同”。 那很模糊。 它背后的原因是什么? 这个堆栈溢出答案给出了一个很好的解释:

UnmodifiableList是UnmodifiableCollection,但相反情况并非如此-包裹列表的UnmodifiableCollection不是UnmodifiableList。 因此,如果将包装List a的UnmodifiableCollection与包装相同List a的UnmodifiableList进行比较,则两个包装器不应相等。 如果只是传递给包装列表,它们将是相等的。 尽管这种推理是正确的,但其含义可能是出乎意料的。

底线

最重要的是,您不能依赖Collection.equals() 。 虽然List.equals()Set.equals()定义明确,但不要信任Collection.equals() 。 它的行为可能没有意义。 当在方法签名中接受Collection时,请记住这一点:

public class MyClass {
  public void doStuff(Collection<?> collection) {
    // Don't rely on collection.equals() here!
  }
}

参考:Java,SQL和JOOQ博客上我们的JCG合作伙伴 Lukas Eder提出的Java Collections API怪癖

翻译自: https://www.javacodegeeks.com/2013/03/java-collections-api-quirks.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值