Java 为什么List.add(E)返回布尔值,而List.add(int,E)返回void?
查看,我发现ArrayList有一个重载的add方法: 公共布尔加法(E) 将指定的元素追加到此列表的末尾 及 公共无效添加(整数索引, 电子元件) 在此列表中的指定位置插入指定元素。将当前位于该位置的元素(如果有)和任何后续元素向右移动(将一个元素添加到其索引中) 我注意到第一个返回的是Java 为什么List.add(E)返回布尔值,而List.add(int,E)返回void?,java,collections,arraylist,Java,Collections,Arraylist,查看,我发现ArrayList有一个重载的add方法: 公共布尔加法(E) 将指定的元素追加到此列表的末尾 及 公共无效添加(整数索引, 电子元件) 在此列表中的指定位置插入指定元素。将当前位于该位置的元素(如果有)和任何后续元素向右移动(将一个元素添加到其索引中) 我注意到第一个返回的是布尔值,而第二个返回的是空值。事实证明,第一个add必须返回一个布尔值,因为: 返回: true(由Collection.add(E)指定) 所以我去了: 布尔加法(E) 确保此集合包含指定的元素(可选操作)。
布尔值
,而第二个返回的是空值
。事实证明,第一个add
必须返回一个布尔值,因为:
返回:
true(由Collection.add(E)指定)
所以我去了:
布尔加法(E)
确保此集合包含指定的元素(可选操作)。如果此集合因调用而更改,则返回true。(如果此集合不允许重复并且已包含指定元素,则返回false。)
所以我的问题是,为什么指定add
返回布尔值而不是空值?当我添加
某个东西时,我希望只执行一个操作
我知道,与ArrayList相反,还有其他数据结构不允许重复(例如集合)。但即便如此,问题也不能通过以下方式解决:
public void add(E e){
if(e is not in set){
add e;
}
}
这样,如果e
在集合中,则不会采取任何操作。为什么返回一个boolean
而不是void
方法更好呢?因为知道是否确实添加了某些内容,或者是否已经添加了一些内容通常很有用。因为这是一个额外的信息,不需要花费任何费用,在某些情况下可能有用。例如:
Set<String> set = new HashSet<String>();
set.add("foobar");
boolean wasAlreadyThere = set.add("foobar");
这需要两倍的工作(首先必须查找,然后再次查找才能添加)。Collection.add
是一种非常通用的方法(不是Java泛型,而是广泛适用的)。因此,他们需要一个普遍适用的返回值
有些类(如ArrayList
)总是接受元素,因此总是返回true
。在这些情况下,返回类型为void
也一样好
但是其他的,比如Set
,有时不允许添加元素。在Set
的情况下,如果已经存在相等的元素,则会发生这种情况。知道这一点通常是有帮助的。另一个例子是有界集合(它只能容纳一定数量的元素)
您可以问,“难道代码不能手动检查吗?”例如,使用一组:
if (!set.contains(item)) {
set.add(item);
itemWasAdded(item);
}
这比您现在可以做的更详细,但不是全部:
if (set.add(item)) {
itemWasAdded(item);
}
但是这种check-then-act行为不是线程安全的,这在多线程应用程序中非常重要。例如,可能是另一个线程在您检查第一个代码段中的set.contains(item)
和set.add(item)
之间添加了一个相等的项。在多线程场景中,这两个动作确实需要是单个原子动作;从方法返回boolean
使之成为可能。我的猜测是因为有时您可能想知道是否未能将某些内容放入集合中。如果返回了void
,则除了查找后面的元素之外,没有其他方法可以知道。但是,我想不出任何相关的例子……您的代码不会做同样的工作,因为它不会让调用方知道它是否已经包含对象。等价的代码在.add之前应该有一个.contains。如果您不关心对add
的调用是否导致了任何更改,那么您就没有义务对结果做任何处理。但其他人可能会发现这些信息很有用。我最近使用了一个使用示例:一个处理队列和一个搜索算法,该算法只在邻居是新的情况下查看分片并将邻居添加到队列中(否则,如果你自己弯曲,你将永远搜索)。显然可以用几种不同的方式实现,但这是其中之一。这个答案更适合作为注释。所有答案都适合作为注释,答案实际上在javadocs中->返回:如果此集合由于调用而更改,则返回:true。。。不公平的否决票顺便说一句,@A4L这并不公平。我同意你的观点,但它肯定回答了OP的一半问题,并且没有错,因此可能不值得投赞成票,但肯定不值得投反对票。被接受的答案在内容上与这个答案完全相同,因为它没有回答关于List#add(int,E)
的部分,它只是更详细了一点,但是有这么多的投票,这很奇怪。我之所以不投票,问题是为什么这两个调用有不同的返回类型。如果有人问“为什么许多澳大利亚哺乳动物都有育儿袋,而在世界其他地方却很罕见?”我会投反对票:“这样它们就可以抱着它们的孩子了”。我不想变得很迂腐,但是。。。第一个例子中的逻辑不是倒过来的吗?不是Java泛型的意义上的逻辑
-谢天谢地!:)+回答得好。对于某些类型的实现,检查然后添加也可能是低效的,因此API允许您以更好的方式处理这些情况,这很好。谢谢您的回答。我不同意任何细节。”返回类型的void也一样好。直到现在,我还没有发现任何情况下,返回虚空将是一个好主意。我宁愿让添加的对象返回,也不要void。
if (set.add(item)) {
itemWasAdded(item);
}