Question

Friends, I am having a problem in getting entire data using TreeSet. I have sorted the TreeSet on some same values.

here is my code:

MyCars class:

class MyCars implements Comparable<MyCars>{

    private String number;
    private int yearModel;
    private double horsePower;

    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public int getYearModel() {
        return yearModel;
    }
    public void setYearModel(int yearModel) {
        this.yearModel = yearModel;
    }
    public double getHorsePower() {
        return horsePower;
    }
    public void setHorsePower(double horsePower) {
        this.horsePower = horsePower;
    }
    @Override
    public int compareTo(MyCars c) {
        return Double.compare(this.horsePower,c.getHorsePower());
    }
}

SortTest class:

public class SortTest {

    void GoForSort(){
        Set dataStructure=new TreeSet();

        MyCars c1=new MyCars();
        c1.setNumber("SRT-Viper123");
        c1.setYearModel(2013);
        c1.setHorsePower(450.00);

        MyCars c2=new MyCars();
        c2.setNumber("Chevrolet-Corvette901");
        c2.setYearModel(2012);
        c2.setHorsePower(450.00);

        MyCars c3=new MyCars();
        c3.setNumber("Ford-Mustang678");
        c3.setYearModel(2014);
        c3.setHorsePower(455.00);

        dataStructure.add(c1);
        dataStructure.add(c2);
        dataStructure.add(c3);

        Iterator<MyCars> it=dataStructure.iterator();
        while(it.hasNext()){
            MyCars c=it.next();
            System.out.println(c.getNumber()+"\t"+c.getHorsePower()+"\t"+c.getYearModel());
        }

    }
    public static void main(String[] args) {
        SortTest st=new SortTest();
        st.GoForSort();

    }

}

As you can see I have sorted the TreeSet on the basis of horsePower. And I have given SAME value for horse-power to two objects.

Here is the output I get:

SRT-Viper123    450.0   2013
Ford-Mustang678 455.0   2014

But I also want Chevrolet-Corvette901 to come in this set of output. Why I am not getting it.

Is there any way to include that also? Because I found there was NO Problem when I change my collection to ArrayList. Does TreeSet sorts only unique elements?

Is there any trick to get & print all objects during Iteration regardless of their uniqueness in TreeSet...

Was it helpful?

Solution 2

Normally with a Set, the uniqueness of the contained objects is determined by their equals() method. In your example, you would implement Car.equals() such that two Cars would be equal if they had the same number, modelYear and horsePower. Then you could add your Corvette into the set and it wouldn't conflict with another model that has the same horsepower.

TreeSet is different: it determines that two objects are identical, not when equals() returns true, but when the compareTo() returns 0. This means you can easily find yourself with two objects that the TreeSet treats as identical, even though they aren't.

Indeed the doc for TreeSet states:

Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface.

In other words, to not break the Set contract, TreeSet depends on YOU only ever supplying a Comparator that's consistent with the equals() implementation of the objects you put in the set.

Since TreeSet allows you to specify an arbitrary Comparator, we might as well be more succinct and say that TreeSet breaks the Set contract.

OTHER TIPS

TreeSet is a child of Set and sets do not store duplicate values. Here is the first line from the definition of set in java docs.

A collection that contains no duplicate elements.

Edit: As pointed out by @AlexEfimov in the comment below, TreeSet uses the compareTo method to determine the ordering and equality of elements, and so as others have pointed out, the compareTo implementation of MyCars would make the two elements with the same horse power equal, and hence only one of them would be stored in the TreeSet.

You have two options:

  1. Make your compareTo also compare the number and yearModel fields.

  2. Store a collection (array or List) at each node - usually called a MultiSet.

So long as your compareTo reports that two items are equal, only one of them will appear in the set.

Set doesn't store duplicated elements. If you want to store both of your cars you should change equals and compareTo methods to compare also number. Then both entries will be different.

Remember that equals method should be consistent with compareTo, so I strongly recommend you to override equals method as well.

Sets only store unique elements.

From Wikipedia on a Set

In mathematics, a set is a collection of distinct objects, considered as an object in its own right. For example, the numbers 2, 4, and 6 are distinct objects when considered separately, but when they are considered collectively they form a single set of size three, written {2,4,6}. Sets are one of the most fundamental concepts in mathematics.

A Set has distinct/unique elements, i.e. no duplicates.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top