如何让枚举在实现接口时使用它们的 compareTo 方法?
How to make enums use their compareTo method when they implement an interface?
结构是这样的:
public interface ItemList{ }
public enum ItemList1 implements ItemList {
Apple,
Orange;
}
public enum ItemList2 implements ItemList {
Banana,
Grapes;
}
还有 5 个这样的枚举
要求是使用这些枚举作为 Map 中的键,在这些 Map 中我将键设置为:
public Class SomeClass {
private Map<ItemList, OtherObject> objectList;
//other code
}
进入地图的 ItemList 在运行时决定。我需要使用像 TreeMap 这样的排序 Map 来进行其他操作。
因此,TreeMap 显然无法比较键枚举,因为我已将它们声明为 ItemList 超类型。
所以,我搜索了其他问题并做了类似的事情,以便枚举可以使用它们的 compareTo 方法:
public interface ItemList<SelfType extends ItemList<SelfType>> extends Comparable<SelfType>{ }
public enum ItemList1 implements ItemList<SelfType> {
//enum values
}
但这并不能解决问题。当我尝试检索将我的枚举作为键的 TreeMap 时,我仍然得到相同的 "ClassCastException"。
如果我在这里做错了什么,请提出建议,或者有什么其他方法可以解决这个问题?
编辑:
Link 我遵循的解决方案,但它不起作用:
How to implement an interface with an enum, where the interface extends Comparable?
编辑 2
问题已确定。对不起大家。
我的地图中填充了不同类型的枚举作为键,而所有键都应属于同一类型才能进行排序。
听起来你应该做的就是
private Map<? extends ItemList, OtherObject> objectList;
...表示objectList
是ItemList
的某个子类型的特定映射,然后
objectList = new TreeMap<ItemList1, OtherObject>();
或
objectList = new TreeMap<ItemList2, OtherObject>();
将其声明为某种特定类型的 ItemList
。 (您可能需要在填充它时将其临时存储为 Map<ItemListN, OtherObject>
,但随后您可以将其放入 objectList
。
嗯,你已经发现是 Map
的实际内容,而不是 classes 的声明导致异常,但值得注意的是,使用集合比较这些enum
s 比你想象的要简单。
例如TreeMap
不关心其声明的泛型类型是否具有可比较的键。如果你有 class 声明,如
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>>
这样复杂的类型声明。
结构是这样的:
public interface ItemList{ }
public enum ItemList1 implements ItemList {
Apple,
Orange;
}
public enum ItemList2 implements ItemList {
Banana,
Grapes;
}
还有 5 个这样的枚举
要求是使用这些枚举作为 Map 中的键,在这些 Map 中我将键设置为:
public Class SomeClass {
private Map<ItemList, OtherObject> objectList;
//other code
}
进入地图的 ItemList 在运行时决定。我需要使用像 TreeMap 这样的排序 Map 来进行其他操作。 因此,TreeMap 显然无法比较键枚举,因为我已将它们声明为 ItemList 超类型。
所以,我搜索了其他问题并做了类似的事情,以便枚举可以使用它们的 compareTo 方法:
public interface ItemList<SelfType extends ItemList<SelfType>> extends Comparable<SelfType>{ }
public enum ItemList1 implements ItemList<SelfType> {
//enum values
}
但这并不能解决问题。当我尝试检索将我的枚举作为键的 TreeMap 时,我仍然得到相同的 "ClassCastException"。
如果我在这里做错了什么,请提出建议,或者有什么其他方法可以解决这个问题?
编辑: Link 我遵循的解决方案,但它不起作用: How to implement an interface with an enum, where the interface extends Comparable?
编辑 2 问题已确定。对不起大家。 我的地图中填充了不同类型的枚举作为键,而所有键都应属于同一类型才能进行排序。
听起来你应该做的就是
private Map<? extends ItemList, OtherObject> objectList;
...表示objectList
是ItemList
的某个子类型的特定映射,然后
objectList = new TreeMap<ItemList1, OtherObject>();
或
objectList = new TreeMap<ItemList2, OtherObject>();
将其声明为某种特定类型的 ItemList
。 (您可能需要在填充它时将其临时存储为 Map<ItemListN, OtherObject>
,但随后您可以将其放入 objectList
。
嗯,你已经发现是 Map
的实际内容,而不是 classes 的声明导致异常,但值得注意的是,使用集合比较这些enum
s 比你想象的要简单。
例如TreeMap
不关心其声明的泛型类型是否具有可比较的键。如果你有 class 声明,如
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>>
这样复杂的类型声明。