0

I Used Java HashSet for storing unique elements but now I want to retrieve element but HashSet does not has something like that, Here is what I want for my problem:

for my usecase LinkInfo hashCode() and equals() methods do not use LinkInfo.id field I want to get linkinfo instance from set and update all of its' fields except id field that should be from old instance

Set<LinkInfo> fooSet = new HashSet<>()

public void updateFoo(LinkInfo linkInfo) {

    LinkInfo temp = fooSet.get(linkInfo);


    linkInfo.setId(temp.getId());

    // now update set
    fooSet.remove(linkInfo)
    fooSet.add(linkInfo)

    }
mohsenJsh
  • 2,048
  • 3
  • 25
  • 49
  • Mate, may be I am not getting your question. Please elaborate what is happening now and what is that you want. – Aman Chhabra Jun 20 '18 at 05:01
  • As per the [accepted answer](https://stackoverflow.com/questions/12014641/java-retrieving-an-element-from-a-hashset) *If you know what element you want to retrieve, then you already have the element.* – Scary Wombat Jun 20 '18 at 05:03

4 Answers4

2

Rather than

LinkInfo temp = fooSet.get(linkInfo);

the below logic is the same as what you seem to want

if (fooSet.contains(linkInfo)) {
   temp = linkInfo;
}
Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
2

I don't know why you're doing this, but to answer the question, yes you can do this, but you should use a map, like so:

import java.util.HashMap;
import java.util.Map;

public class Main {
    static class Test {
        public int a,b;

        public Test(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public boolean equals(Object obj) {
            Test that = (Test)obj;
            return this.a == that.a && this.b == that.b;
        }

        @Override
        public int hashCode() {
            return a ^ b;
        }
    }
    public static void main(String[] args) {
        Map<Test,Test> map = new HashMap<>();
        Test t = new Test(1,2);
        System.out.println(System.identityHashCode(t));
        map.put(t, t);
        Test t2 = new Test(1,2);
        System.out.println(System.identityHashCode(t2));
        System.out.println(System.identityHashCode(map.get(t2)));
    }
}

Now you are able to retrieve the instance that you put into that map initially through an instance that is equal to it.

The program printed:

475266352
1355531311
475266352

on my computer. You can use a HashSet and iterate through it achieving the same result, but it won't be O(1).

Coder-Man
  • 2,391
  • 3
  • 11
  • 19
1

You have a bit of a logical problem here. Why should an API that depends on equals() provide a method getElementEqualTo(e)? In order to use such a method, you need to present an object that, for the API's purposes, is equivalent to the desired result. What would be the point of that?

But that doesn't mean you're out of luck. I think you're saying that your LinkInfo class provides hashCode() and equals() methods suitable for identifying the object you want by means of a different object that you can obtain. In that case, it sounds like a HashMap could serve your purpose. Just map each key to itself.

HashMap<LinkInfo, LinkInfo> infos;

public void updateInfo(LinkInfo linkInfo) {
    LinkInfo temp = infos.remove(linkInfo);

    if (temp != null) {
        linkInfo.setId(temp.getId());
    }

    infos.put(linkInfo, linkInfo);
}    
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

I do agree with Scary answer above, but in case you want the exact reference that is stored in the Set instead of an similar equal object, you may use below code:

public void updateFoo(LinkInfo linkInfo) {

LinkInfo temp = null;
for(LinkInfo curLinkInfo:fooSet) if (curLinkInfo.equals(linkInfo))temp = curLinkInfo;

if(temp!=null)
linkInfo.setId(temp.getId());

// now update set
fooSet.remove(linkInfo)
fooSet.add(linkInfo)

}
Aman Chhabra
  • 3,824
  • 1
  • 23
  • 39