TreeSet引发ClassCastException?

时间:2015-03-27 21:25:29

标签: java

我有以下TreeSet:

private TreeSet<BWidgetObject<D>> entries = new TreeSet<BWidgetObject<D>>();

其中:

public interface BWidgetObject<D> extends Comparable<D> {
}

我创建了:

public class BItemDtoWidgetObject implements BWidgetObject<ItemDto> {
  private ItemDto itemDto;

  @Override
  public int hashCode() {
    return itemDto.hashCode();
  }

  @Override
  public int compareTo(ItemDto o) {
    return itemDto.compareTo(o);
  }

  @Override
  public boolean equals(Object obj) {
    BItemDtoWidgetObject otherWidgetObject;
    if (obj instanceof BItemDtoWidgetObject) {
      otherWidgetObject = (BItemDtoWidgetObject)obj;
    }
    else {
      throw new IllegalStateException("BItemDtoWidgetObject - equals obj is not instance of BItemDtoWidgetObject");
    }
    boolean result = this.itemDto.equals(otherWidgetObject.getDto());    
    return result;
  }
}

在我的主程序中,我使用了上面的TreeSee entries插入并删除了BItemDtoWidgetObject

public void instert(BItemDtoWidgetObject w) {
  entries.add(w);
}

public boolean remove(BItemDtoWidgetObject w) {
  return entries.remove(w);
}

插入操作正常,但是当我像这样执行remove时:

BItemDtoWidgetObject w = // some instance
boolean isRemoved = remove(w);

然后我收到以下错误:

Caused by: java.lang.ClassCastException
    at Unknown.fillInStackTrace_0_g$(Unknown Source)
    at Unknown.Throwable_1_g$(Unknown Source)
    at Unknown.Exception_1_g$(Unknown Source)
    at Unknown.RuntimeException_1_g$(Unknown Source)
    at Unknown.ClassCastException_1_g$(Unknown Source)
    at Unknown.dynamicCast_0_g$(Unknown Source)
    at Unknown.compareTo_3_g$(Unknown Source)
    at Unknown.compareTo_Ljava_lang_Object__I__devirtual$_0_g$(Unknown Source)
    at Unknown.compare_48_g$(Unknown Source)
    at Unknown.compare_49_g$(Unknown Source)
    at Unknown.removeWithState_0_g$(Unknown Source)
    at Unknown.remove_222_g$(Unknown Source)
    at Unknown.remove_226_g$(Unknown Source)

我不明白为什么我得到ClassCastException。我实现了hashCode,equals和compareTo,因此删除项目时一切都会正常。

为什么条目TreeSet会引发ClassCastException?

修改:ItemDto是:

class ItemDto {
 String id;

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

}

2 个答案:

答案 0 :(得分:3)

TreeSet按顺序保留您放入其中的元素。

为了能够确定正确的顺序,它需要能够比较元素。

因此,TreeSet要求您的班级BWidgetObject实现接口Comparable,或者您要使用TreeSet的构造函数Comparator

注意:BWidgetObject<D>应该延伸Comparable<BWidgetObject<D>>,而不是Comparable<D>

public interface BWidgetObject<D> extends Comparable<BWidgetObject<D>> {
}

public class BItemDtoWidgetObject implements BWidgetObject<ItemDto> {
    // ...

    @Override
    public int compareTo(BWidgetObject<ItemDto> other) {
        // ...
    }
}

答案 1 :(得分:0)

public int compareTo(ItemDto o) {
    return itemDto.compareTo(o);
}

应该是

public int compareTo(BItemDtoWidgetObject o) {
    return itemDto.compareTo(o.itemDto);
}

可比较的接口采用相同类型的实例。不是你的包装类型。