1

假设我有以下 compareTo:

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 个对象?

4

6 回答 6

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();
于 2016-09-23T07:44:30.053 回答
0

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

于 2016-09-23T07:37:05.560 回答
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);
于 2016-09-23T08:01:17.467 回答
0

设置一个全局计数器。下面是我的代码:

公共类 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;
        }
    }
}

}

于 2016-09-23T07:43:47.040 回答
0

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

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

也许它需要为返回值 1、0增加两次?

于 2016-09-23T07:31:56.640 回答
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()));
于 2016-09-23T08:00:48.407 回答