如何使枚举在实现接口时使用compareTo方法?

时间:2015-04-08 16:48:45

标签: java interface enums comparable

结构是这样的:

public interface ItemList{ }

public enum ItemList1 implements ItemList {

    Apple,
    Orange;
}

public enum ItemList2 implements ItemList {

    Banana,
    Grapes;
}

还有5个这样的枚举

要求是将这些枚举用作地图中的键,在这些地图中我将键设置为:

public Class SomeClass {
private Map<ItemList, OtherObject> objectList;
//other code
}

进入地图的ItemList在运行时决定。我需要使用像TreeMap这样的有序映射来进行其他操作。 因此,TreeMap无法比较关键枚举,因为我已将它们声明为ItemList超类型。

所以,我搜索了其他问题并做了类似的事情,以便枚举可以使用他们的compareTo方法:

public interface ItemList<SelfType extends ItemList<SelfType>> extends Comparable<SelfType>{ }

public enum ItemList1 implements ItemList<SelfType> {
     //enum values
}

但这并没有解决问题。我仍然得到相同的&#34; ClassCastException&#34;当我试图检索一个将我的枚举作为键的TreeMap时。

请告知我在这里做错了什么,或者可以通过什么方式解决这个问题?

编辑: 链接到我遵循的解决方案,但它不起作用: How to implement an interface with an enum, where the interface extends Comparable?

编辑2 确定问题。对不起大家。 我的地图填充了不同类型的枚举作为键,当所有键应属于相同类型以进行排序工作。

2 个答案:

答案 0 :(得分:1)

嗯,你已经发现它是Map的实际内容,而不是引起异常的类的声明,但是值得注意的是使用比较这些enum的集合是比你想象的容易。

E.g。 TreeMap并不关心其声明的Generic类型是否具有可比较的密钥。如果你有像

这样的类声明
public interface ItemList{ }
public enum ItemList1 implements ItemList { Apple, Orange }
public enum ItemList2 implements ItemList { Banana, Grapes }

您只需将其用作

即可
TreeMap<ItemList,Object> tm=new TreeMap<>();
tm.put(ItemList1.Apple, "A");
tm.put(ItemList1.Orange, "O");
System.out.println(tm.get(ItemList1.Apple)+" is for "+ItemList1.Apple);
tm.clear();
tm.put(ItemList2.Banana, "B");
tm.put(ItemList2.Grapes, "G");
System.out.println(tm.get(ItemList2.Banana)+" is for "+ItemList2.Banana);
没有问题;如果你将地图声明为TreeMap<Object,Object>,它甚至可以工作。

请注意,某些方法在请求自然顺序时需要类似的类型,方法是不指定Comparator,例如使用上面的类型声明,

List<Object> list=Arrays.<Object>asList(ItemList1.Orange,ItemList1.Apple,ItemList1.Orange);
Collections.sort(list);

无法编译,但是,您可以通过null Comparator

请求自然顺序轻松绕过它:

Collections.sort(list, null); // compiles and works

因此,在大多数情况下,没有必要乱用复杂的类型声明,例如ItemList<SelfType extends ItemList<SelfType>>

答案 1 :(得分:0)

听起来你应该做的就是

 private Map<? extends ItemList, OtherObject> objectList;

...表示objectListItemList某个子类型的特定地图,然后

 objectList = new TreeMap<ItemList1, OtherObject>();

 objectList = new TreeMap<ItemList2, OtherObject>();

将其声明为ItemList的某种特定类型。 (您可能必须在填充时将其暂存为Map<ItemListN, OtherObject>,但随后可以将其放入objectList