Meena Chaudhary
Meena Chaudhary

Reputation: 10665

TreeSet<Object> allowing multiple objects of same type

I have a TreeSet<Floor> object which stores floors to be visited by an elevator. Floor is an abstract class which is extended by concrete floor class e.x FloorOne, FloorTwo etc. As per the logic my TreeSet<Floor> should store only one instance of each Floor subtype but instead I am able to insert multiple instances of each subtypes. Floor class implements Comparable so I can sort floors in TreeSet<Floor> as per their number. Below is the code for class Floor

public abstract class Floor implements Comparable<Floor>{

    protected int floorNo;
    public abstract void floorVisited();
    public int getFloorNo() {
        return floorNo;
    }   
    @Override
    public int compareTo(Floor floor) {
        return this.getFloorNo() > floorButton.getFloorNo() ? 1 : -1;
    }
}

Code for one of the subtype:

public class FloorOne extends Floor{

    public FloorOne(){
        floorNo = 1;
    } 
    @Override
    public void floorVisited() {
        System.out.println("Floor No. " + floorNo + " was visited");
    }
}

adding floors to TreeSet<Floor> by calling addFloor() method of ElevatorController.

controller.addFloor(new FloorFour());
controller.addFloor(new FloorFour());
controller.addFloor(new FloorTwo());

addFloor() method in ElevatorController.

private TreeSet<Floor> travelUpwards;
private TreeSet<Floor> travelDownwards;

public void addFloor(Floor floor) {

    if (floor.getFloorNo() > currentFloor.getFloorNo()) {
        travelUpwards.add(floor);
    } else if (floor.getFloorNo() < currentFloor.getFloorNo()) {
        travelDownwards.add(floor);
    }
}

Output I'm getting is:

Floor No. 2 was visited
Floor No. 4 was visited
Floor No. 4 was visited

As per my understanding a new instance of object FloorFour is created when I call addFloor(new FloorFour()) and that is why TreeSet<Floor> do not consider them as duplicate. But is there a way I can stop insertion of same floor more than once.

Upvotes: 1

Views: 1617

Answers (3)

Mureinik
Mureinik

Reputation: 311073

Your compareTo method is wrong - it never allows floors to be "equal", and thus breaks the general contract of Java's compareTo method.

Since the floor number is an int, instead of reinventing the wheel, you should just use java.lang.Integer.compare(int, int):

@Override
public int compareTo(Floor floor) {
    return Integer.compare(this.getFloorNo(), floor.getFloorNo());
}

Upvotes: 2

Joe
Joe

Reputation: 31057

@Override
public int compareTo(Floor floor) {
    return this.getFloorNo() > floorButton.getFloorNo() ? 1 : -1;
}

This can never return zero, so it will never indicate that two floors are equal. You should ensure you return zero when they are equal, rather than -1.

Upvotes: 2

DeiAndrei
DeiAndrei

Reputation: 947

Having a correct implementation of the compareTo() method would probably solve your problem.

@Override
public int compareTo(Floor floor) {
    return this.getFloorNo() - floor.getFloorNo();
}

Upvotes: 2

Related Questions