2016-09-23 90 views
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个对象?

+2

'this.comparisonCount ++;' –

+1

写共用辅助类含有['AtomicInteger'](https://docs.oracle.com/javase/8/docs/ api/java/util/concurrent/atomic/AtomicInteger.html)作为计数器,将其分配给数组中的实例,并在每次比较完成时增加此计数器。 – Turing85

+0

http://ideone.com/OzW8dB :) –

回答

0

考虑绑定一个原子整型字段称为counter,说你的收藏。在排序算法之前将其设置为零,然后在compareTo内将其增加1(原子级)。

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

也许它需要递增两次返回值为1,0?

+0

'计数器'应该在每个if-else块中增加? –

+0

@AnimeshPandey:那可能是你想要做的,是的。 – Bathsheba

+0

'它需要递增两次,返回值为1,0?'背后的原因是什么? –

0

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

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; 
     } 
    } 
} 

}

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(); 
+0

感谢您的回复。在@Bathsheba给出的答案中提到,我们可能需要增加计数器两次,才能返回1或0的比较结果? –

+0

@AnimeshPandey你在这些情况下比较两次是一个实现细节 - 这是一个数字比较,所以基本上是免费的。知道执行多少个数字比较真的很有趣,而不是比较多少个*实例*?除此之外,在排序算法中会执行大量的数字比较,您不计算它们。 –

+0

我同意@AndyTurner它是一个你不应该考虑的实现细节。将计数器与您的比较器实现混合是非常糟糕的设计,您应该清楚地避免出于可维护性的原因 –

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())); 
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);