我为我的对象定义了4个比较器:
public static Comparator<mObject> comp0 = new Comparator<mObject>() {
@Override
public int compare(mObject l, mObject r) {
...compare
}
};
public static Comparator<mObject> comp1 = new Comparator<mObject>() {
@Override
public int compare(mObject l, mObject r) {
...compare
}
};
public static Comparator<mObject> comp2 = new Comparator<mObject>() {
@Override
public int compare(mObject l, mObject r) {
...compare
}
};
public static Comparator<mObject> comp4 = new Comparator<mObject>() {
@Override
public int compare(mObject l, mObject r) {
...compare
}
};
现在我想创建一个包含4个比较器的数组,如下所示:
public final static Comparator<mObject>[] Object_comparators = { comp0,
comp1,
comp2,
comp3};
但是Eclipse强调{..}之间的所有内容,就像它是一个错误。为什么它,我怎么能解决它?
答案 0 :(得分:9)
您无法使用参数化泛型类型创建类数组。
如果你不介意失去类型安全,你可以这样做:
Comparator[] list = new Comparator[4];
但我首选的策略是使用List
:
List<Comparator<mObject>> list = Arrays.asList(comp0, comp1, comp2, comp3);
答案 1 :(得分:2)
正如Mark Elliot所说,你不能在数组中使用泛型类型。
这是因为类型擦除,而数组在运行时已知其类型。
由于类型擦除,通用类型在运行时永远不会被识别。
这意味着泛型在编译时非常有用,而且通过一些技巧,可以将Animal对象插入List<Comparator>
顺便说一下,如果没有指定数组的类型,就不能声明创建匿名数组,因为数组类型没有类型擦除。
因此,不允许使用泛型类型创建数组,并可能导致一些意外行为。
想一想:如果你创建了一个car(Car [])数组,那么你可以将它转换为Object []。这并不意味着您可以将对象放在该数组中,因为数组的类型在运行时仍然是已知的。如果你试图把狗放在那个数组上,你会得到一个ArrayStoreException。
现在如果我们创建了一个数组Car<Ferrari>[]
怎么办?您仍然可以将其强制转换为Object []。
它的工作方式类似于Car []数组,除非在这种情况下,当您将其转换为Object []时,您将能够在运行时放置类型为Car<Renault>
的对象,因为泛型类型不是已知<!/强>
我认为Java阻止了我们这种行为。
但您仍然可以使用一系列泛型参考!!!
public static void main(String[] args) {
Comparator<String> NORMAL = new Comparator<String>() {
@Override
public int compare(String s, String s1) {
return s.compareTo(s1);
}
};
Comparator<String> REVERSE = new Comparator<String>() {
@Override
public int compare(String s, String s1) {
return - s.compareTo(s1);
}
};
Comparator<String>[] comparators = new Comparator[] {NORMAL,REVERSE};
List<String> strings = Arrays.asList("f","d","c","a","e","b");
TreeSet<String> normalSet = new TreeSet<String>(comparators[0]);
normalSet.addAll(strings);
for ( String s : normalSet ) {
System.out.println("normal : " + s);
}
TreeSet<String> reverseSet = new TreeSet<String>(comparators[1]);
reverseSet.addAll(strings);
for ( String s : reverseSet ) {
System.out.println("reverse : " + s);
}
}
产生输出:
normal : a
normal : b
normal : c
normal : d
normal : e
normal : f
reverse : f
reverse : e
reverse : d
reverse : c
reverse : b
reverse : a
所以你可以使用带有泛型的数组,但是Java似乎阻止你做这样的事情。
我想这是因为最初的数组合约可能是这样的:
如果您创建一个X类型的数组,您将永远无法放置 其中的任何东西都是非 - 非X.如果你尝试,你将得到一个ArrayStoreException
因此允许使用泛型创建的数组会导致不同的规则,如:
如果您创建一个类型为
X<Y>
的数组,您将永远无法做到 放任何不是X的东西。如果你尝试,你会得到一个 ArrayStoreException信息。但是你可以添加X<Y>
和X<Z>
个对象!
正如我之前的代码所示,我们无法使用泛型创建数组,但我们可以创建没有泛型的数组,并将其用作带有泛型的数组。
Comparator<String>[] comparators = new Comparator[] {NORMAL,REVERSE};
我想这是某种方式让Java告诉我们“如果你知道你在做什么,那么你可以做到这一点”