0x2E5
0x2E5

Reputation: 55

Adding Object to HashSet

I am trying to add an Object (Exception) to a Set, however it adds every Exception, eventhough some are duplicates. debug

In my case duplicates are Exceptions which have the same Detail message.

How do I properly add the Exceptions to the HashSet only if the Exception.getDetails() doesn't already exist?

Is there another approach than a HashSet?

Performance is a criteria here, quadratic solutions (O(n^2))are not an option.

Upvotes: 3

Views: 4268

Answers (3)

Davide Lorenzo MARINO
Davide Lorenzo MARINO

Reputation: 26926

You need to redefine equals and hashCode methods.

If the detail is a String you can redefine them as follow

public boolean equals(Object obj) {
   if (!(obj instanceof YourException)) {
     return false;
   } 
   return getDetail().equals(((YourException) obj).getDetail());
}

public int hashCode() {
   return getDetail().hashCode();
}

Consider this code as a base to program. You have to check for null values for example.

Once redefined equals and hashCode inserting YourException in a TreeSet is an operation done in O(log(n)) where n is the size of the set, from javadoc:

This implementation provides guaranteed log(n) time cost for the basic operations (add, remove and contains).

Upvotes: 1

assylias
assylias

Reputation: 328598

You have a few options:

  • override hashcode and equals in your exception class
  • use a TreeSet with a custom Comparator
  • use a Map<String, Exception> where the key is the getDetails() result (for example, a HashMap)

Upvotes: 4

Peter Lawrey
Peter Lawrey

Reputation: 533500

You need to override how the Execptions are compared so it recognises duplicates the way you want. You can't do this for a HashSet but you can for TreeSet e.g.

Set<Exception> exceptions = new TreeSet<>(Comparator.comparing(Object::toString));

This example compares the toString which is the exception type and message in most cases.

If you really want to use a HashSet you need to wrap the Exception in a class which implements hashCode and equals the way you want.

If all you care about is the type and message you can store just the toString of each exception

final Set<String> exceptions = new HashSet<>();

public void addException(Exception e) {
    exceptions.add(e.toString());
}

Upvotes: 1

Related Questions