Dmitriy S
Dmitriy S

Reputation: 401

How I can remove and update sorted elements in TreeSet?

I have some entity class

class Data{
    private String quoteID;
    private String bidOrOffer;
    private float price;
    private long   volume;
    private Date   createDate;

    public Data(String quoteID, String bidOrOffer, float price, long volume) {
        this.quoteID = quoteID;
        this.bidOrOffer = bidOrOffer;
        this.price = price;
        this.volume = volume;
        createDate = new Date();
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 13 * hash + Objects.hashCode(this.quoteID);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Data other = (Data) obj;
        if (!Objects.equals(this.quoteID, other.quoteID)) {
            return false;
        }
        return true;
    }
}

and I push some elements into TreeSet whit special order

Comparator<Data> offerOrder = (Data o1, Data o2) -> {
    if(o1.equals(o2))
        return 0;      
    if(o1.getPrice() == o2.getPrice()
            && o1.getVolume() == o2.getVolume()){
        return o1.getCreateDate().after(o2.getCreateDate())? 1:-1;
    }
    if(o1.getPrice() == o2.getPrice()){
        return o1.getVolume() > o2.getVolume()? 1:-1;
    }
    if(o1.getPrice() > o2.getPrice())
        return 1;
    else
        return -1;
};


Set<Data> treeSet = new TreeSet<>(offerOrder);
treeSet.add(new Data("Q1", "OFFER", 1.32f, 1000000));
treeSet.add(new Data("Q6", "OFFER", 1.32f, 1000000));
treeSet.add(new Data("Q7", "OFFER", 1.33f, 200000));

The main goal of this task it is remove and update some data by quoteID but if I do this

treeSet.contains(new Data("Q7", "OFFER", 0, 0)); //return false

thereafter method remove doesn't work too.

Any ideas?

Upvotes: 1

Views: 1144

Answers (3)

AG_
AG_

Reputation: 54

You cannot search "quoteID" as is inside Data object. You have to iterate each Data object and match for "quoteID".

Iterator<Data> iterator = treeSet.iterator();
while(iterator.hasNext()){          
        Data dataobj = iterator.next();
        String qID = dataobj.quoteID;
        if(qID.equals("Q7")){
            //write your code.
        }
}

Upvotes: 0

Stefan Warminski
Stefan Warminski

Reputation: 1835

While inserting "Q7" the comparator returns 1 in compare to "Q1". If you now want to remove "Q7" with new Data("Q7", "OFFER", 0, 0) the comparator returns -1. So the child of the "wrong" path of the tree compared next.

treeSet.contains(new Data("Q7", "OFFER", 2, 0)) would return true (compare to "Q1" returns 1).

Upvotes: 2

freedev
freedev

Reputation: 30137

You should take care of change the implementation of your Comparator<Data> offerOrder because that implementation does not permit to find the object you're looking for with treeSet.contains.

For example in your case:

  Comparator<Data> offerOrder = (Data o1, Data o2) -> {
     return o1.quoteID.compareTo(o2.quoteID);
  };

And then returns true:

treeSet.contains(new Data("Q7", "OFFER", 0, 0)); //return true

There is also an error in your equals method:

    final Quote other = (Quote) obj;
    if (!Objects.equals(this.quoteID, other.quoteID)) {
        return false;
    }

You should use:

    if (!this.quoteID.equals(other.quoteID)) {
        return false;
    }

And given that quoteID is a String is not clear what is the Quote class.

I suggest to change use hashCode and equals methods in this way:

@Override
public int hashCode()
{
  final int prime = 31;
  int result = 1;
  result = prime * result + ((quoteID == null) ? 0 : quoteID.hashCode());
  return result;
}

@Override
public boolean equals(Object obj)
{
  if (this == obj)
    return true;
  if (obj == null)
    return false;
  if (getClass() != obj.getClass())
    return false;
  Data other = (Data) obj;
  if (quoteID == null) {
    if (other.quoteID != null)
      return false;
  } else if (!quoteID.equals(other.quoteID))
    return false;
  return true;
}

Upvotes: 1

Related Questions