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

2022-09-02 12:46:40

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

公共布尔添加(E e)

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

public void add(int index, E element)

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

我注意到第一个返回,而第二个是.事实证明,第一个必须返回一个,因为:booleanvoidaddboolean

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

所以我去了Collection.add(E)

布尔加法(E e)

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

所以我的问题是,为什么指定返回布尔值而不是空值?当我有东西时,我期望只做一个手术。addadd

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

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

这样,如果 IS 在集合中,则不执行任何操作。为什么返回 a 而不是方法更好?ebooleanvoid


答案 1

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

某些类(如)始终接受元素,因此将始终返回 。你是对的,在这些情况下,返回类型也会同样好。ArrayListtruevoid

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

你可以问,“代码不能手动检查这个吗?例如,使用集合:

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

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

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

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


答案 2

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