如何计算Comparator / Comparable中的比较次数?

时间:2016-09-23 07:28:26

标签: java sorting comparator timsort

假设我有以下比较:

public int compareTo(RandomClass o) {
    if (this.value() < o.value()) {
        return -1;
    } else if (this.value() > o.value()) {
        return 1;
    } else {
        return 0;
    }
}

我想知道调用Arrays.sort(randomClassArray)时确切的比较次数,其中randomClassArray有100个对象?

6 个答案:

答案 0 :(得分:2)

对我来说,最好的方法是使用Comparator类型的装饰器,它会计算它被调用的总次数:

public class Counter<T> implements Comparator<T> {

    private final AtomicInteger counter;
    private final Comparator<T> comparator;

    public Counter(Comparator<T> comparator) {
        this.counter = new AtomicInteger();
        this.comparator = comparator;
    }

    @Override
    public int compare(final T o1, final T o2) {
        counter.incrementAndGet();
        return comparator.compare(o1, o2);
    }

    public int getTotalCalled() {
        return this.counter.get();
    }
}

然后,您将自己提供comparator并使用Arrays.sort(T[], Comparartor)对数组进行排序,如下所示:

Counter<SomeClass> counter = new Counter<>(myComparator);
Arrays.sort(randomClassArray, counter);
int totalCalled = counter.getTotalCalled();

答案 1 :(得分:0)

考虑将一个名为counter atomic 整数类型字段绑定到您的集合中。在排序算法之前将其设置为零,然后在compareTo内将其递增1(原子地)。

如果您的排序算法已并行化,则需要 atomic 。我回避制作compareTo synchronized,因为这可能会破坏任何并行化的好处。

对于返回值为1,0,可能需要递增两次

答案 2 :(得分:0)

声明public static int变量并在compareTo()方法中递增它。 在Arrays.sort(randomClassArray)打印变量并重置后。

答案 3 :(得分:0)

设置全局计数器。 以下是我的代码:

  

public class ComparatorCount {

static int counter = 0;

public static void main(String[] args) {
    Random random = new Random();
    List<RandomClass> randomClassList = new ArrayList<>();
    for(int i = 0 ; i < 100 ; i++) {
        RandomClass rc = new RandomClass();
        rc.setValue(i + random.nextInt(100));
        randomClassList.add(rc);
    }

    Collections.sort(randomClassList);

    randomClassList.forEach(x -> System.out.println(x));

    System.out.println("compare " + counter + " times in total.");
}

static class RandomClass implements Comparable<RandomClass> {

    private int value;

    public int value() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public String toString() {
        return "randomClass : " + value;
    }

    @Override
    public int compareTo(RandomClass o) {
        counter++;
        if (this.value() < o.value()) {
            return -1;
        } else if (this.value() > o.value()) {
            return 1;
        } else {
            return 0;
        }
    }
}

}

答案 4 :(得分:0)

您可以编写自己的类,实现Comparator<RandomClass>接口:

public class CustomComparator implements Comparator<RandomClass> {

    private final AtomicInteger counter;

    public CustomComparator() {
        this.counter = new AtomicInteger(0);
    }

    @Override
    public int compare(RandomClass val1, RandomClass val2) {
        this.counter.incrementAndGet();
        if (val1.value() < val2.value()) {
            return -1;
        } else if (val1.value() > val2.value()) {
            return 1;
        }
        return 0;
    }

    public int getNumberOfOperations() {
        return this.counter.intValue();
    }
}

然后使用以下参数调用static <T> void sort(T[] a, Comparator<? super T> c)函数:

CustomComparator comparator = new CustomComparator();
Arrays.sort(randomClassAray, comparator);
System.out.println("Number of operations = " + String.valueOf(comparator.getNumberOfOperations()));

答案 5 :(得分:0)

试试这个。

public class ComparatorCounter<T extends Comparable<T>> implements Comparator<T> {

    public int counter = 0;

    @Override
    public int compare(T o1, T o2) {
        ++counter;
        return o1.compareTo(o2);
    }
}

RandomClass[] array = new RandomClass[9];
// fill array
ComparatorCounter<RandomClass> comp = new ComparatorCounter<>();
Arrays.sort(array, comp);
System.out.println("compare count=" + comp.counter);