mohsenJsh
mohsenJsh

Reputation: 2108

what is proper java collection with unique element (like set) with get element feature

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)

    }

Upvotes: 0

Views: 62

Answers (4)

Coder-Man
Coder-Man

Reputation: 2531

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).

Upvotes: 2

Aman Chhabra
Aman Chhabra

Reputation: 3894

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)

}

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 180201

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);
}    

Upvotes: 1

Scary Wombat
Scary Wombat

Reputation: 44834

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;
}

Upvotes: 2

Related Questions