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

看看javadoc我看到一个ArrayList有一个重载的add方法:

public boolean add(E e)

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

public void add(int index,E element)

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

我注意到第一个返回了一个boolean而第二个返回了一个void 。 事实certificate,第一个add HAS返回一个boolean因为:

返回:true(由Collection.add(E)指定)

所以我去了Collection.add(E) :

布尔加法(E e)

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

所以我的问题是,为什么add指定返回boolean而不是void? 当我add一些东西时,我希望只做一个操作。

我知道还有其他数据结构,与ArrayList相反,不允许重复(例如集合)。 但即便如此,问题也不可能按照以下方式解决:

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

这样,如果集合中的e IS没有采取任何行动。 为什么返回boolean而不是void方法更好?

Collection.add是一种非常通用的方法(在Javagenerics的意义上 – 在广泛适用的意义上)。 因此,他们想要一般适用的返回值。

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

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

您可以问,“无法编码只是手动检查?” 例如,有一组:

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

这比你现在做的更冗长,但不是很多:

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

但是这种check-then-act行为不是线程安全的,这在multithreading应用程序中至关重要。 例如,可能是另一个线程在您检查第一个代码片段中的set.contains(item)set.add(item)之间添加了相同的项。 在multithreading场景中,这两个动作确实需要是单个primefaces动作; 从方法返回boolean使这成为可能。

因为知道是否实际添加了某些内容通常很有用,或者已经存在。

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

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

否则你必须这样做

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

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