简体   繁体   中英

Java TreeSet remove duplicates based on object attribute

I wish to use TreeSet to remove duplicate object based on their attributes (here is toString() which return object's name ), here is my code:

Set<Object> s = new TreeSet<>(new Comparator<Object>() {          
            @Override
            public int compare(Object o1, Object o2) {
                if (o1.toString().equals(o2.toString())) {
                    return 0;
                } else {
                    return 1;
                }
            }
        });
s.addAll(listComCopy);
listComCopy.clear();
listComCopy.addAll(s);

listComCopy is a list of object.

It does the work but it only compares consecutive objects on the list, so if i have list(50).equals(list(150)) it will ignore.

Do you have any idea of how can i refactor this code to eliminate all duplicates regardeless their order in the list?

According to TreeSet's constructor javadoc :

TreeSet(Comparator comparator)
Constructs a new, empty tree set, sorted according to the specified comparator .

The comparator you are providing is only used for sorting, not for duplicate removal.

If you want to remove duplicates, you should implement .equals() and .hashcode() on your object class you are storing on this TreeSet, so duplicate removal logic will work out of the box when you add a new element to it.

Your compare method does not adhere to the requirements.

See Comparator.compare ...

Compares its two arguments for order. Returns a negative integer , zero, or a positive integer as the first argument is less than , equal to, or greater than the second.

You would be better off using String.compareTo in your compare .

    Set<Object> s = new TreeSet<>(new Comparator<Object>() {
        @Override
        public int compare(Object o1, Object o2) {
            return o1.toString().compareTo(o2.toString());
        }
    });

you might want to compare the strings using the compareTo method instead of using the equals method. That will allow the tree set to build an actual tree like structure.

You should reconsider you Comparator implementation. From java.util.Comparator#compare javadoc:

@return a negative integer, zero, or a positive integer as the * first argument is less than, equal to, or greater than the * second.

You never return negative number in your code, consider return o1.toString().compareTo(o2.toString()) as your Comparator implementation

TreeSet does not seem to use equals and hashCode on the element class as HashSet uses for its duplicate removal. Instead, it uses the sorted list to eliminate duplicates. To get the desired effect (of duplicate removal), one should ensure flawless implementation of the Comparator's compare. In this case, replacing "if (o1.toString().equals(o2.toString())) { return 0; } else { return 1; }" with "o1.toString().compareTo(o2.toString())" should fix issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM