Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the reference to a duplicate in a Set

I have a Set object and I use this set to ensure that when I add an element to it that already exists in the set, it's not added. This is the easy part, just use Set.add(); But after this is done I need the reference to the object in the Set.

What I essentially mean is having a .add() that doesn't return a boolean, but the actual object you tried to add (if it wasn't added, the one in the set). Is there already a Set implementation that does this, or do I have to write my own?

At the moment I used a Set.add() and if it returns false I use an iterator to look for the one in the set. Although this works, I find it ugly. Especially when using the HashSet implementation which should be able to find the object a lot faster using hashcodes. Any ideas?

EDIT: Wow, lots of answers in a relatively short time, thanks. Ok, so what I'm trying to do is create a certain datastructure that loads data from some place and creates objects from it. This data might contain duplicates, and this wouldn't be a problem if I used a set and just needed this one set, but the datastructure needs to add references to these unique objects to other objects in the datastructure, therefore I need the references to the (unique) objects in the set. Also, I can't just not load the data that is already contained in the set, because there is more (unique) data linked to it, which is also added, together with a reference to that data that was already contained in the set. For illustration purposes (because the above explanation is far from clear) I'll give an example here:

Data:

foo     bar
1       3
1       4
2       5

Datastructure:

Set<Foo> totalFooSet  
Set<Bar> totalBarSet

Foo:

sometype data
Set<Bar> barSet  

Bar:

sometype data
Set<Foo> fooSet

This is sort of like a many-to-many relation.

I'm not sure if there is some major design flaw here, I've looked it over with some other people and we can't figure out how to do this differently. I like the idea of using the HashMap, so I'll create a subclass and add an addAndReturn() function to it.

like image 477
Erik Stens Avatar asked Jan 26 '26 12:01

Erik Stens


2 Answers

(As @AlexR says, I'm assuming that you want a reference to the previous object equal to the one you are trying to add now)

Instead of using a Set, try using a HashMap with the same object as a key and a value. Then you can do the following:

Foo objectToAdd = //obtained the normal way
Map<Foo,Foo> psuedoSet = //this is stored somewhere

Foo result = psuedoSet.get(objectToAdd);
if (result == null) {
    pseudoSet.put(objectToAdd, objectToAdd);
    result = objectToAdd;
}
return result;
like image 100
Sean Reilly Avatar answered Jan 29 '26 02:01

Sean Reilly


Similar to Sean's answer (which I upvoted), but possibly more reusable.

public class HashMapBackedSet<T> extends HashMap<T,T>{
    public T add( T toAdd ){
        T existing = get( toAdd );
        if( existing != null ){
            return existing;
        }
        put( toAdd, toAdd );
        return toAdd;
    }
}
like image 22
Dawood ibn Kareem Avatar answered Jan 29 '26 02:01

Dawood ibn Kareem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!