将比较器对象存储在数组中

时间:2011-12-02 14:56:22

标签: java

我为我的对象定义了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强调{..}之间的所有内容,就像它是一个错误。为什么它,我怎么能解决它?

2 个答案:

答案 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告诉我们“如果你知道你在做什么,那么你可以做到这一点”