Aveneon
Aveneon

Reputation: 171

Find if an object is already present in a HashMap

I am trying to create a HashMap, that adds objects to a line, if they are not already present in this line. This is how I check it:

if (!waiting.containsKey(p)) {
    waiting.put(current, p);
    current++;
}

Where p is our object, which is stored with an Integer. However, when I run this code. It will store the same object several times under different integers, how can this be prevented?

Upvotes: 0

Views: 1845

Answers (2)

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48610

If you want to use an object as a key, you can override the equals() and hashCode() methods to return and compare the id of the object.

Driver.java

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

public class Driver {
    public static void main(String[] args) {
        Map<MyObject, Integer> map = new HashMap<MyObject, Integer>();

        map.put(new MyObject(1000L, "One"),   1);
        map.put(new MyObject(1001L, "Two"),   2);
        map.put(new MyObject(1002L, "Three"), 3);

        Long id = 1001L; 

        System.out.println(contains(map, id)); // true
        System.out.println(get(map, id));      // 2
    }

    public static <T, U> boolean contains(Map<T, U> map, T obj) {
        return map.containsKey(obj);
    }

    public static boolean contains(Map<MyObject, Integer> map, Long id) {
        return contains(map, new MyObject(id, ""));
    }

    public static <T, U> U get(Map<T, U> map, T obj) {
        return map.get(obj);
    }

    public static Integer get(Map<MyObject, Integer> map, Long id) {
        return get(map,  new MyObject(id, ""));
    }
}

MyObject.java

public class MyObject {
    private Long id;
    private String name;

    protected Long getId() {
        return id;
    }

    protected void setId(Long id) {
        this.id = id;
    }

    protected String getName() {
        return name;
    }

    protected void setName(String name) {
        this.name = name;
    }

    public MyObject(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        MyObject other = (MyObject) obj;
        if (id == null) {
            if (other.id != null) return false;
        } else if (!id.equals(other.id)) return false;
        return true;
    }

    @Override
    public String toString() {
        return "MyObject { id : " + id + ", name : " + name + "}";
    }
}

Upvotes: 0

nano_nano
nano_nano

Reputation: 12523

thats because you call containsKey with the object and not the key:

parameter must be an Integer key

Integer lKey = 0;
if(!waiting.containsKey(lKey)){
        waiting.put(current, p);
        current++;
        }

if your object has an identifier use this identifier for the map.

if(!waiting.containsKey(p.getId())){
            waiting.put(p.getId(), p);
            current++;
            }

otherwise use containsValue():

if(!waiting.containsValue(p)){
            waiting.put(current, p);
            current++;
            }

but then you have to overwrite the equals method.

Upvotes: 1

Related Questions