为什么List.add(E)返回布尔值,而List.add(int,E)返回void



查看javadoc,我发现ArrayList有一个重载的add方法:

公共布尔加法(E E(

将指定的元素追加到此列表的末尾。

public void add(int index,E元素(

在此列表中的指定位置插入指定的元素。将当前位于该位置的元素(如果有(和任何后续元素向右移动(在其索引中添加一个(。

我注意到第一个返回了boolean,而第二个是void。事实证明,第一个add必须返回boolean,因为:

退货:true(由Collection.add(E(指定(

所以我去了Collection。添加(E(:

布尔加法(E E(

确保此集合包含指定的元素(可选操作(。如果此集合因调用而更改,则返回true。(如果此集合不允许重复并且已经包含指定的元素,则返回false。(

所以我的问题是,为什么add被指定为返回布尔值而不是void?当我add的时候,我希望只做一个操作。

我知道,与ArrayList相反,还有其他数据结构不允许重复(如集合(。但即使在那时,这个问题也不能按照以下方式解决:

public void add(E e){
    if(e is not in set){
        add e;
    }
}

这样,如果e在集合中,则不采取任何操作。为什么返回boolean而不是void方法更好?

Collection.add是一个非常通用的方法(不是Java泛型的意义上的方法,而是广泛适用的方法(。因此,他们想要一个普遍适用的回报值。

有些类(如ArrayList(总是接受元素,因此总是返回true。您是对的,在这些情况下,返回类型void也同样好。

但其他一些元素,如Set,有时不允许添加元素。在Set的情况下,如果已经存在相等元素,就会发生这种情况。知道这一点通常很有帮助。另一个例子是有界集合(只能容纳一定数量的元素(。

你可以问,"难道代码就不能手动检查吗?"例如,用一个集合:

if (!set.contains(item)) {
    set.add(item);
    itemWasAdded(item);
}

这比你现在能做的更详细,但不是很多:

if (set.add(item)) {
    itemWasAdded(item);
}

但是这种先检查后执行的行为不是线程安全的,这在多线程应用程序中可能至关重要。例如,可能是另一个线程在您检查第一个代码片段中的set.contains(item)set.add(item)之间添加了一个相等的项。在多线程场景中,这两个操作实际上需要是单个原子操作;从该方法返回CCD_ 18使得这成为可能。

因为知道某个东西是真的添加了还是已经添加了通常很有用。

因为这是一个额外的信息,不需要任何成本,在某些情况下可能很有用。例如:

Set<String> set = new HashSet<String>();
set.add("foobar");
boolean wasAlreadyThere = set.add("foobar");

否则你将不得不做

boolean wasAlreadyThere = set.contains("foobar");
set.add("foobar");

这需要两倍的工作量(首先必须查找,然后再次查找才能添加(。

最新更新