3

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.

3
  • 4
    implement correct hashCode() and equals() for your exceptions Commented Jun 6, 2018 at 13:15
  • Can you tell us why you are doing this? Commented Jun 6, 2018 at 13:15
  • To properly display on the frontend with my messageFactory Commented Jun 6, 2018 at 13:17

3 Answers 3

4

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)
Sign up to request clarification or add additional context in comments.

Comments

1

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

2 Comments

Actually, the to string is not enough, since I'll do further processing with it later. But your TreeSet solution with log(n) works like a charm.
@0x2E5 in that case you might consider assylias' suggestion of using Map<String, Exception> which is O(1) per add.
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.