为什么Set.add不返回对象?

时间:2016-08-22 12:29:46

标签: java

为什么Set.add()没有返回你想要添加的对象,或者一个对象是你想要添加的对象,如果它已经在集合中?

我可以拥有一个具有两个属性的对象,但hashcode()/equals()方法中只考虑其中一个属性(然后使用我不考虑hashcode()/equals()的属性。

一个简单的答案是Set扩展了Collection接口,但这并不令人满意;那么问题是为什么Set没有一个额外的方法来完成我想要它做的事情,例如:set.addObject()

我知道我可以使用Map.getOrDefault,但我需要指定地图的两个参数。

2 个答案:

答案 0 :(得分:4)

  

一个简单的答案是Set扩展了Collection接口,但这并不令人满意

是否满意,add返回boolean而不是Object中已有Set的答案的答案。 Collection.add返回一个布尔值,表示底层集合是否已更改。

一般来说,你会返回什么表明没有添加元素,请记住“已经在集合中”并不是不添加元素的唯一原因?

为什么没有addObject方法的问题是完全独立的,基于意见的:可能认为它有用,但API设计师要么:

  • 没有考虑添加它,因为他们没有看到需要;
  • 考虑到了这一点,但认为它没有发挥其重要性,因为在极少数情况下,当你想要这样的功能时,你可以通过其他方式来做。
  • 认为它可能有用,但后来无法修改接口以添加新方法,因为这会破坏Set的现有实现。

    现在,接口可以具有默认方法实现,这显然是可能的。但后来我们回到了上面的其他两个原因。

实际上,我收回上面所说的“那个”已经在集合中“不是不添加元素的唯一原因”。

根据the Javadoc of Collection.add

  

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

所以,好吧,应该是唯一的原因。但是你必须想知道为什么List返回你刚刚添加的元素会有用。

答案 1 :(得分:3)

确实会很好。

一个简单的用例是缓存,因此不会使用重复的实例:

目前必须按如下方式实施:

class Shared<T>
    private final Map<T, T> map = new HashMap<>();

    public T share(T obj) {
        T old = map.get(obj);
        if (old == null) {
            map.put(obj, obj);
            old = obj;
        }
        return old;
    }
}

但是当Set.addObject返回旧对象或null时添加对象:

    private final Set<T> set = new HashSet<>();

    public T share(T obj) {
        return set.addObject(obj);
    }

Set的代数完整性,让所有操作都可用,确实缺乏这种功能。