java 为什么在 Set 接口上没有定义 replace() 方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2636660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:09:23  来源:igfitidea点击:

why no replace() method defined on the Set interface?

java

提问by Eleco

Currently I have to write the following to update an element already contained in a Set:

目前,我必须编写以下内容来更新已包含在 Set 中的元素:

Set mySet= ...
Element e1 = new Element (...);
....
....
Element e2 = new Element (...);
\e1 and e2 are different instances, but equals.

\update the element contained into the Set
if (mySet.contains(e2)){
    mySet.remove(e2);
    myset.add(e2);
 }

That doesnt look nice. Is there an alternative ?

那不好看。有替代方案吗?

采纳答案by penpen

A Set is a data structure made to avoid duplicate by mean of using equals() on the object; that also means that two object that are equals() to each other are considered to be perfectly equivalent. Ie, whether you use the version already in the Set or the new one, your code should work the same.

Set是通过在对象上使用equals()来避免重复的数据结构;这也意味着彼此 equals() 的两个对象被认为是完全等价的。即,无论您使用 Set 中已有的版本还是新的版本,您的代码都应该以相同的方式工作。

If you want to update the object with a new value, then this is clearly not the case for you (the two version can not replace each other), and you should then use another data structure (eg, a Map, where you can easily override the value, in this case, the key can even be the object itself).

如果你想用新的值更新对象,那么这显然不是你的情况(两个版本不能相互替换),然后你应该使用另一种数据结构(例如,一个 Map,在那里你可以很容易地覆盖值,在这种情况下,键甚至可以是对象本身)。

回答by Stephen C

Why is no replace() method defined on the Set interface?

为什么 Set 接口上没有定义 replace() 方法?

I can think of three reasons:

我能想到三个原因:

  1. It is functionally redundant: set.replace(old, nu)is simply if (set.remove(old)) { set.add(nu) }for example.

  2. The behavior in the case where oldis not present adds complications.

  3. Adding replaceto the SetAPI forces all implementations of Setto implement a (redundant) method.

  1. 它在功能上是多余的:set.replace(old, nu)只是if (set.remove(old)) { set.add(nu) }例如。

  2. old不存在的情况下的行为增加了复杂性。

  3. 添加replaceSetAPI 会强制所有实现Set实现(冗余)方法。

It may even be that there are deeper reasons; e.g. to do with the implementability of replacein some obscure case.

甚至可能还有更深层次的原因;例如,replace在一些晦涩的情况下与 的可实施性有关。

However, as others have pointed your use case does not require a replaceat all. Your code has the same effect (*) as this:

但是,正如其他人指出的那样,您的用例根本不需要 a replace。您的代码具有与此相同的效果 (*):

    Set myset = ...
    myset.add(element);

(* Actually, you might be able to detect a difference if your element.equals(Object)method compares element objects field by field. Depending on the Set implementation, you might get different object references in the sets after executing the two code sequences. But, IMO you'd be asking for trouble if you made assumptions about that kind of thing!)

(* 实际上,如果您的element.equals(Object)方法逐个字段比较元素对象,您可能能够检测到差异。根据 Set 实现,在执行两个代码序列后,您可能会在集合中获得不同的对象引用。但是,IMO 你会如果你对那种事情做出假设,那就是自找麻烦!)

回答by bruno conde

I think the alternative is just use add.

我认为替代方案就是使用add.

From the docs:

文档

Adds the specified element to this set if it is not already present (optional operation). More formally, adds the specified element e to this set if the set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.

如果指定的元素尚不存在,则将其添加到此集合中(可选操作)。更正式地,如果集合不包含元素 e2 使得 (e==null ? e2==null : e.equals(e2)),则将指定的元素 e 添加到该集合中。如果此集合已包含该元素,则调用将保持该集合不变并返回 false。

However, I can't really tell from your question if you are trying to updateor replacean element. When you change an element's the property, those changes are automatically reflected in the Setbecause the Set contains references, so no updateisn't really needed. If your trying to replacea differentelement, such a replacemethod would be redundant as explained by Stephen C.

但是,如果您尝试更新替换元素,我无法从您的问题中真正判断出来。当您更改元素的属性时,这些更改会自动反映在 中,Set因为 Set 包含引用,因此实际上不需要更新。如果你想更换一个不同的元素,这样的replace通过解释的方法将是多余的斯蒂芬·Ç

(after question edit)

(问题编辑后)

e1 and e2 are different instances, but equals.

e1 和 e2 是不同的实例,但相等。

I suggest that you implement equality on Element. That way, the addmethod checks the existence of an element not by reference (the default Object.equals) but by your notion of equality on Element. So even if the references of e1 and e2 are different, e1.equals(e2) == true.

我建议你在 上实现平等Element。这样,该add方法不是通过引用(默认值Object.equals)而是通过您对等式的概念来检查元素是否存在Element。所以即使 e1 和 e2 的引用不同,e1.equals(e2) == true.

回答by Omry Yadan

by definition a set cannot contain an element more than once, so your contains->remove->add thing is pointless. just add your item as many time as you want to the set.

根据定义,集合不能多次包含一个元素,因此您的 contains->remove->add 内容毫无意义。只需将您的项目添加到集合中即可。

回答by Sripathi Krishnan

No need to remove and then add. Just modify the object directly. Since Sets (or any collection) just store the reference, you don't need a replace() method.

无需删除然后添加。直接修改对象即可。由于 Sets(或任何集合)只存储引用,因此您不需要 replace() 方法。

EDIT : the above statement is INCORRECT. See http://java.sun.com/j2se/1.4.2/docs/api/java/util/Map.html

编辑:上述陈述是不正确的。见http://java.sun.com/j2se/1.4.2/docs/api/java/util/Map.html

Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map

注意:如果将可变对象用作映射键,则必须非常小心。如果对象的值以影响相等比较的方式更改,而对象是映射中的键,则未指定映射的行为