如何在TreeSet中删除和更新已排序的元素?

时间:2017-03-14 10:42:12

标签: java collections set comparator

我有一些实体类

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

我将一些元素推送到TreeSet特殊订单

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

此任务的主要目标是通过quoteID删除并更新部分数据 但如果我这样做

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

此后方法删除也不起作用。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

插入“Q7”时,比较器与“Q1”相比返回1。 如果您现在想要用new Data("Q7", "OFFER", 0, 0)删除“Q7”,则比较器返回-1。 因此,树的“错误”路径的孩子接下来比较。

treeSet.contains(new Data("Q7", "OFFER", 2, 0))将返回true(比较“Q1”返回1)。

答案 1 :(得分:1)

您应该注意更改Comparator<Data> offerOrder的实施,因为该实施不允许使用treeSet.contains找到您要查找的对象。

例如在您的情况下:

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

然后返回true

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

您的equals方法中也存在错误:

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

您应该使用:

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

鉴于quoteIDString并不清楚Quote类是什么。

我建议以这种方式更改使用hashCodeequals方法:

@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;
}

答案 2 :(得分:0)

您不能像在Data对象中一样搜索“quoteID”。您必须迭代每个Data对象并匹配“quoteID”。

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