为什么java.util.HashSet没有get(Object o)方法?

FGr*_*reg 58 java hashset

我已经看到了有关Set根据索引值获取对象的其他问题,我理解为什么这是不可能的.但我无法找到一个很好的解释为什么不允许通过对象获取,所以我想问.

HashSetHashMap得到一个对象的支持应该非常简单.就像现在一样,似乎我必须遍历每个项目HashSet并测试相等,这似乎是不必要的.

我可以使用一个,Map但我不需要一个键:值对,我只需要一个Set.

比如说我有Foo.java:

package example;

import java.io.Serializable;

public class Foo implements Serializable {

    String _id;
    String _description;

    public Foo(String id){
        this._id = id
    }

    public void setDescription(String description){
        this._description = description;
    }

    public String getDescription(){
        return this._description;
    }

    public boolean equals(Object obj) {
        //equals code, checks if id's are equal
    }

    public int hashCode() {
        //hash code calculation
    }

}
Run Code Online (Sandbox Code Playgroud)

并且Example.java:

package example;

import java.util.HashSet;

public class Example {

    public static void main(String[] args){
        HashSet<Foo> set = new HashSet<Foo>();

        Foo foo1 = new Foo("1");
        foo1.setDescription("Number 1");

        set.add(foo1);
        set.add(new Foo("2"));

        //I want to get the object stored in the Set, so I construct a object that is 'equal' to the one I want.
        Foo theFoo = set.get(new Foo("1")); //Is there a reason this is not allowed?
        System.out.println(theFoo.getDescription); //Should print Number 1
    }

}
Run Code Online (Sandbox Code Playgroud)

是因为equals方法是为了测试"绝对"平等而不是"逻辑"平等(在这种情况下contains(Object o)就足够了)?

rsb*_*097 46

Java地图/集合备忘单

它只包含键/值对或值吗?

1)如果它包含,则选择是地图.订单重要吗?

.1-1)如果,请按照插入顺序或按键排序?

..1-1-1)如果有序,LinkedHashMap

..1-1-2)如果排序,TreeMap

.1-2)如果顺序是重要的是,HashMap的

2)如果它只存储,则选择是一个集合.它会包含重复吗?

.2-1)如果,则为ArrayList

.2-2)如果它包含重复项,主要任务是搜索元素(包含/删除)?

..2-2-1)如果,则为ArrayList

..2-2-2)如果,订单重要吗?

...2-2-2-1)如果顺序是重要,HashSet的

...2-2-2-2)如果,请按照插入顺序或按值排序?

....2-2-2-2-1)如果有序,LinkedHashSet

....2-2-2-2-2)如果排序,TreeSet

  • 好消息.另见:http://stackoverflow.com/questions/21974361/what-java-collection-should-use (5认同)
  • 不错的信息,但不是一个适合的问题的答案. (3认同)

Pet*_*rey 24

A Set是一个Collectiona.equals(b) == true视为重复的对象,因此尝试获取已有的同一对象是没有意义的.

如果您尝试get(Object)从集合中进行,Map则可能更合适.

你应该写的是

Map<String, String> map = new LinkedHashMap<>();

map.put("1", "Number 1");
map.put("2", null);
String description = set.get("1");
Run Code Online (Sandbox Code Playgroud)

如果一个对象不在集合中(基于等于),添加它,如果它在集合中(基于等于)给我该集合的该对象的实例

万一你需要这个,你可以使用Map.

Map<Bar, Bar> map = // LinkedHashMap or ConcurrentHashMap

Bar bar1 = new Bar(1);
map.put(bar1, bar1);

Bar bar1a = map.get(new Bar(1));
Run Code Online (Sandbox Code Playgroud)

  • 我可以看到为什么人们可能想要这样的东西:如果一个对象不在集合中(基于等于),添加它,如果它在集合中(基于等于)给我该集合的该对象的实例. (35认同)
  • 排序......除了它实际上*可能*有用,如果你有效的规范化.你不会得到*相同的*对象 - 你将得到一个*相等的*对象. (22认同)
  • 我试图在这个例子中提出的想法是,对象有一个标识符(它控制它与其他`Foo`类型的相等性)以及任何其他不对其身份做出贡献的字段.我希望能够通过构造一个"相等的"`Foo`对象来从Set中获取对象(包括额外的字段). (7认同)
  • "Set"的重点是"相等"元素是可以互换的.听起来你想要的是一个`Map <Foo,Foo>`. (2认同)
  • @FGreg甚至`Map <String,Foo>`作为键实际上是一个String.您不应该混淆用于查找查找内容的内容. (2认同)

xle*_*ier 5

你的最后一句是答案.

get(Object o)将通过HashSet寻找另一个对象等于o(使用equals(o)方法).所以它确实是相同的contains(o),只是没有返回相同的结果.


Yog*_*ngh 5

如果您想知道该new Foo("1");对象已经存在于中,set那么您需要使用contains方法:

boolean present =  set.contains(new Foo("1"));
Run Code Online (Sandbox Code Playgroud)

不支持 ie这种get方法,set.get(new Foo("1"));因为它没有意义。您已经拥有该对象,new Foo("1")即您将通过方法查看哪些额外信息get

  • *您已经拥有该对象,即 new Foo("1")* =&gt; 不完全是 - 他有另一个恰好相等的实例,但它仍然是一个不同的对象。 (13认同)
  • “Set”中原始“Foo”对象上的额外字段就是我想要的。创建 new Foo("1")` 等于 Set 中的对象,但不包含 Set 中的对象包含的额外信息。 (2认同)