Not Comparator's tricks.

来源:互联网 发布:淘宝上的铁观音 编辑:程序博客网 时间:2024/05/18 13:24

 今天看了《Java 5.0 Tiger》当中的一个有关Comparator的范例,是将一个Comparator的实现类传给PriorityQueue的构造器,来实现增删元素时按照compare()指定的规则进行排序。为了简化起见,我将范例改为将从20到1这20个数依次用offer()放进PriorityQueue里,然后用poll()取出来。从打印结果上来看,完全正确,但是当我在compare()里增加了调试用打印语句时,则看到的结果非常奇怪。于是查阅相关资料。

API文档中有关这个接口的完整定义如下:

 

package java.util;
public interface Comparator<T>
{
    
int compare(T o1, T o2);
    bool equals(Object obj);
}

 

一般在实现这个接口时只需要实现compare方法,在实现时可以指定自己的任何排序规则。我修改后的范例如下:

 

import java.util.PriorityQueue;
import java.util.Comparator;

public class PriorityQueueTest
{
    
public static void main(String[] args)
    
{
        PriorityQueue
<Integer> pq = 
          
new PriorityQueue(20
            
new Comparator<Integer>()
            
{
                
public int compare(Integer i, Integer j)
                
{
                    
//测试用
                    System.out.print("" + i + " " + j);                    
                    
/*从小到大排序*/
                    
int result = i - j;
                    
//测试用
                    System.out.println(" -------- " + result);
                    
return result;
                    
                }

            }
);
        
for(int i = 0; i < 20; i++)
        
{
            pq.offer(
20-i);
        }

        
for(int i = 0; i < 20; i++)
        
{
            System.out.println(pq.poll());
        }

    }

}

从执行的结果中几乎看不出compare方法的调用规律,而且也看不出具体排序的过程。我一开始以为是根据compare方法的返回值的具体情况来决定下一次调用的连续次数和时机的,而且一下子就钻进了这个死角,认为一定是Comparator本身的问题,结果弄了大半个小时一点结果也没有(应该是一点结果也没有)。直到后来我用Arrays.sort()又试了一下,发现这次的调用和排序过程和PriorityQueue中的不一样,才发觉原来不是Comparator捣的鬼,要想知道具体是怎么排序的,主要是要看其使用者的实现如何。有时脑子突然间拐不过弯来的时候就容易得出错误的结论,而且分析问题时一定要既从细节又从全局来看,要把认为是问题的地方以及其周围有关的地方都弄清楚,才有可能得出正确的结论。

Arrays.sort()范例如下:

import java.util.*;

public class ComparatorTest
{
    
public static void main(String[] args)
    
{
        Integer[] abc 
= 
          
new Integer[] {1,5,6,8,10,15,2,7,3,11};
        Arrays.sort(abc,
          
new Comparator<Integer>()
          
{
            
public int compare(Integer i, Integer j)
            
{
                System.out.println(
"" + i + " " + j + " ----- " + (i-j));
                
return i-j;
            }

          }
);
        
for(int i=0; i<abc.length; i++)
        
{
            System.out.println(abc[i]);
        }

    }

}
原创粉丝点击