首页 > 解决方案 > Java:Comparable vs Comparator - 内存和性能

问题描述

在我的一次采访中,有人问我

Comparable 和 Comparator 之间的性能差异是什么?

我回答说不知道。面试官说,

如果 Comparable 由Employee类实现,当创建 5000 个 Employee 对象并将其添加到 ArrayList 中时,堆内存中将有 5000 个具有compareTo方法的对象。因此,除非绝对必要,否则不要使用 Comparable。使用 Comparator,消除了上述内存开销。

他说的对吗?

标签: javaperformancecollectionscomparatorcomparable

解决方案


那个答案是不正确的。

添加实现的接口或方法不会影响类的各个实例所需的内存。

首先,从概念上讲,它没有意义。

实现的接口和方法是每个类的信息。同一类的两个实例将始终实现完全相同的接口并具有完全相同的方法。因此,JVM 为每个对象存储该信息是没有意义的。

其次,您可以使用如下示例代码轻松验证这一点:

public class MyClass implements Comparable<MyClass> {

  private final long l;

  MyClass(long l) {this.l = l;}

  @Override
  public int compareTo(MyClass o) {
    return 0;
  }

  public static void main(String[] args) {
    long l = 0;
    try {
      var list = new ArrayList<MyClass>();
      while (true) {
        list.add(new MyClass(l++));
      }
    } catch (OutOfMemoryError e) {
      System.out.println("Created " + l + " objects before things went south ...");
    }
  }
}

使用 Java 11运行它-Xmx32m会在每次运行时为我创建大约 200000 个对象(略有不同,可能是由于 GC 细节)。

删除Comparable接口和/或compareTo方法不会显着改变该值。

您可以尝试添加其他字段或删除l,这更改数字。


推荐阅读