2

Say I have a custom datatype:

public class Notification {
    private String name;
    private String location;
    private String message;

    // Constructors, getter, setters, etc.          
}

And I want to add objects (of Notification type) from a list to a Set to get rid of duplicates. But just simply adding them to a Set doesn't work because Java doesn't know how to check to see if there are duplicates.

How do I tell Java that when I add a Notification object to a set, I want it to only check whether the name attribute is unique or not (disregarding other fields)?

lealceldeiro
  • 14,342
  • 6
  • 49
  • 80
  • In general, override the `.equals()` and `.hashCode()` methods. Those test for equality. I don't quite know enough to create an answer, so someone more knowledgeable will get on it. – Hypnic Jerk Jul 23 '18 at 21:15
  • Override `hashCode()` method. – PM 77-1 Jul 23 '18 at 21:15
  • 3
    Possible duplicate of [Java Set collection - override equals method](https://stackoverflow.com/questions/6187294/java-set-collection-override-equals-method) – PM 77-1 Jul 23 '18 at 21:15
  • 1
    _Don't_ use a `Set`. Use a `Map` keyed by the `name` attribute. – Louis Wasserman Jul 23 '18 at 21:19

2 Answers2

1

I found that using Map (keyed by name attribute) as mentioned by Louis Wasserman better than overriding hashChode and equals. If you're trying to do what I'm doing, you can implement something like the following:

Map<String, Notification> m = new HashMap();

    for (Notification n : notifications) {
        m.put(n.getHostname(), n);
    }

    Iterator it = m.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pair = (Map.Entry) it.next();
        System.out.println(pair.getKey() + " = " + pair.getValue());
    }

When you iterate through the Map, you'll see that it figures out whether the object is unique or not based on the key! Much easier than using a Set.

0

According to the Set documentation, it will contain a

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.

So from this we can see that if you override the equals method for Notification you can specify there how two elements (two notifications) are compared.

Also I recommend you to override the hashCode method in case you use an implementation of Set such as HashSet

For example you could go with something like this:

public class Notification {
    private String name;
    private String location;
    private String message;

    // Constructors, getter, setters, etc.          

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Notification)) return false;
        Notification notif = (Notification) o;
        return Objects.equals(name, notif.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

}
lealceldeiro
  • 14,342
  • 6
  • 49
  • 80