1

I have a Java Set<MyClass> on which I've overridden equals and hashCode to use the String name; variable.

public class MyClass{
    final String name;
    public boolean equals(Object o){...}
    public int hashCode(){return name.hashCode();}
}

Is there anyway I can get my Object out of the HashSet using something like

MyClass o = set.get("nameofmyobject");

Is there a way to do this in Java, or a datastructure? or do I need to change up all of my Sets to Maps?

Jay Smith
  • 471
  • 3
  • 17

3 Answers3

3

No. You need to change to a Map. None of the methods of Set return an element.

Addendum A
If you don't care about speed you can always search manually:

MyClass find(String name, Set<MyClass> set)
{
    MyClass wrapper = new MyClass(name);
    for (MyClass e : set) {
        if (wrapper.equals(e)) {
            return e;
        }
    }
    return null;
}

Addendum B
If you use a TreeSet you can use floor:

MyClass find(String name, TreeSet<MyClass> set)
{
    MyClass wrapper = new MyClass(name);
    MyClass candidate = set.floor(wrapper);
    if (candidate != null && wrapper.equals(candidate)) {
        return candidate;
    } else {
        return null;
    }
}
tom
  • 21,844
  • 6
  • 43
  • 36
  • I do care about speed, which is why I'm using set, and will now have to move to a Map. I'm just not happy about increasing the Space requirements by `O(n)` to store (what seems to me) redundant keys – Jay Smith Jun 11 '13 at 23:31
  • @JaySmith It won't use any more space. Java's `HashSet` is implemented using a `HashMap`. See the [JDK7 source](http://hg.openjdk.java.net/jdk7/2d/jdk/file/8f19b165347b/src/share/classes/java/util/HashSet.java). – tom Jun 11 '13 at 23:42
  • Thanks for the link tom, never knew that – Jay Smith Jun 12 '13 at 19:03
2

Have a look at this question. The answer is no. Sets are not for getting elements, but to look for equality. Use a Map or List insteed.

Community
  • 1
  • 1
Steve Benett
  • 12,843
  • 7
  • 59
  • 79
  • A list gives `O(n)` access. Might as well just iterate through the set. – tom Jun 11 '13 at 23:09
  • I like the link to that question. I hadn't seen that. Even that question doesn't really explain why though :( – Jay Smith Jun 11 '13 at 23:11
  • If you look up in a Set for an Object you have the Object already, otherwise you couldn't find it i guess. So why not working with the Object after the equality check? – Steve Benett Jun 11 '13 at 23:18
  • Notice my question, I don't have the Object, I just have `key` that represents equality for the object – Jay Smith Jun 11 '13 at 23:33
1

As Tim said you can't. And if so you would have to call it like set.get(myClassInstance); and not set.get(some member of the stored instance)

Use

   Map<String, MyClass> myMap = new HashMap<String, MyClass>();
Stefano L
  • 1,486
  • 2
  • 15
  • 36