匿名内部类 - 集合排序

时间:2016-05-02 20:24:48

标签: java

我正在创建一个Comparator作为Anonymous内部类,我不确定它是否是最好的方法。我在我的代码中只创建了一次,但我不确定每次排序列表时是否创建了内部类。例如,在应用程序中,如果我使用该比较器调用sort方法10次,是否会创建10个额外的类?

Collections.sort(originalList, new Comparator<User>() {
    @Override
    public int compare(User o1, User o2) {
        int value1 = o1.getPropertyCode().compareTo(o2.getPropertyCode());
        if (value1 == 0) {
            int value2=o1.getPropertyValue().compareTo(o2.getPropertyValue());
            return value2;
        }
        return value1;
    }
});

VS

Collections.sort(originalList,new SomeComparator());

2 个答案:

答案 0 :(得分:3)

编译器将匿名类转换为常规类定义,并且实际上给出了类似OutterClass$1的名称,您不能通过该名称引用该类,但您可以执行new Object() {}.class.getName()到看到它总是一样的。每当你的代码遇到问题时,它只使用一个类 - 无论你是否给它一个明确的名字。你的2个选项基本相同。

但是当你在Collections.sort(originalList, new之前阅读你的代码行时,你应该意识到new每次都会创建一个新实例(不是类)。即它分配内存,初始化东西,......不需要多次,因为创建的比较器对象永远不会有差异。

您要做的是将创建的比较器存储在类似字段中(或者像Java自己的源String.CASE_INSENSITIVE_ORDER中那样)

private static final Comparator<User> USER_COMPARATOR = new Comparator<User>() {
    @Override
    public int compare(User o1, User o2) {
        int value1 = o1.getPropertyCode().compareTo(o2.getPropertyCode());
        if (value1 == 0) {
            int value2=o1.getPropertyValue().compareTo(o2.getPropertyValue());
            return value2;
        }
        return value1;
    }
};
private void someCode() {
    Collections.sort(originalList, USER_COMPARATOR);
}

或者使用Java 8,您可以将其转换为lambda(注意缺少的new),每次都不会创建新实例

Collections.sort(originalList, (o1, o2) -> {
    int value1 = o1.getPropertyCode().compareTo(o2.getPropertyCode());
    if (value1 == 0) {
        int value2=o1.getPropertyValue().compareTo(o2.getPropertyValue());
        return value2;
    }
    return value1;
});

答案 1 :(得分:0)

这取决于。如果在方法中有比较器,那么在每次调用时都会实例化一个新的比较器。此外,该比较器将包含对包含类的引用。

另一方面,如果将匿名内部类定义为静态字段,那么将只有一个(每个类加载器)。