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

时间:2014-06-11 21:44:28

标签: java collections arraylist

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

  

public boolean add(E e)

     

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

  

public void add(int index,        E元素)

     

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

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

  

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

所以我去了Collection.add(E)

  

布尔加法(E e)

     

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

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

据我所知,与ArrayList相反,其他数据结构不允许重复(例如集合)。但即使这样,问题也无法按照以下方式解决:

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

这样,如果e在集合中,则不采取任何行动。为什么返回boolean代替void方法更好?

3 个答案:

答案 0 :(得分:18)

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可以实现这一点。

答案 1 :(得分:1)

因为知道某些东西是否实际被添加,或者已经存在的东西通常很有用。

答案 2 :(得分:1)

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

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

否则你必须这样做

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

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