common-io之Comparator阅读

来源:互联网 发布:csol三米优化刀 编辑:程序博客网 时间:2024/04/30 07:20

1.  首先我们来查看AbstractFileComparator这个抽象类

 首先我们来看一下IO包里面的Comparator,这个都比较好理解,首先是AbstractFileComparator这个类,他提供了两个接口,可以实现对Array和Collection的sort功能。

 

Java代码  收藏代码
  1. <span style="font-size: medium;"><span style="color: #99cc00;">// 实现了对File数组的排序功能  
  2. public File[] sort(File... files) {  
  3.         if (files != null) {  
  4.             Arrays.sort(files, this);  
  5.         }  
  6.         return files;  
  7.     }</span></span>  

  // 实现对collection的排序

Java代码  收藏代码
  1. public List<File> sort(List<File> files) {  
  2.         if (files != null) {  
  3.             Collections.sort(files, this);  
  4.         }  
  5.         return files;  
  6.     }  

 2. CompositeFileComparator类的实现

   这个类的主要意图是使用里面的delegate file comparator来进行File的排序。首先看一下构造函数:

 

Java代码  收藏代码
  1. public CompositeFileComparator(Comparator<File>... delegates) {  
  2.         if (delegates == null) {  
  3.             this.delegates = (Comparator<File>[]) NO_COMPARATORS;//1  
  4.         } else {  
  5.             this.delegates = (Comparator<File>[]) new Comparator<?>[delegates.length];//2  
  6.             System.arraycopy(delegates, 0this.delegates, 0, delegates.length);  
  7.         }  
  8.     }  
 

在构造函数里面如果delegates是null的话,就设置成空的comparators,负责就直接赋值给delegates属性。

 

 

Java代码  收藏代码
  1. public CompositeFileComparator(Iterable<Comparator<File>> delegates) {  
  2.         if (delegates == null) {  
  3.             this.delegates = (Comparator<File>[]) NO_COMPARATORS; //1  
  4.         } else {  
  5.             List<Comparator<File>> list = new ArrayList<Comparator<File>>();  
  6.             for (Comparator<File> comparator : delegates) {  
  7.                 list.add(comparator);  
  8.             }  
  9.             this.delegates = (Comparator<File>[]) list.toArray(new Comparator<?>[list.size()]); //2  
  10.         }  
  11.     }  
 

这个也很好理解,就是为空的时候直接赋个空的comparator,负责的话构造一个ArrayList,遍历Iterator,把结果集放到list里面,然后讲list转化成数组。

 

 

Java代码  收藏代码
  1. public int compare(File file1, File file2) {  
  2.        int result = 0;  
  3.        for (Comparator<File> delegate : delegates) {  
  4.            result = delegate.compare(file1, file2);  
  5.            if (result != 0) {  
  6.                break;  
  7.            }  
  8.        }  
  9.        return result;  
  10.    }  
 

这个函数也就是关键,这个是遍历delegates,并对它们进行一一比较,一旦分出胜负就break掉,并返回。

 

3. DefaultFileComparator类的实现

      这个类故名思意就是使用File的compare方法进行两个File的比较,这个里面需要注意的是里面提供了两个常量的Comparator,一个是ReverseComparator,这个会在后面讲到。

 

Java代码  收藏代码
  1. /** Singleton default comparator instance */  
  2.     public static final Comparator<File> DEFAULT_COMPARATOR = new DefaultFileComparator();  
  3.   
  4.     /** Singleton reverse default comparator instance */  
  5.     public static final Comparator<File> DEFAULT_REVERSE = new ReverseComparator(DEFAULT_COMPARATOR);  

 

4.  DirectoryFileComparator类的实现

    这个类也比较好理解,就是实现了Directory和File进行比较的函数,看到下面的函数的实现,我们就可以看到它的实现了。

 

Java代码  收藏代码
  1. public int compare(File file1, File file2) {  
  2.        return (getType(file1) - getType(file2));  
  3.    }  
  4.   
  5.    /** 
  6.     * Convert type to numeric value. 
  7.     * 
  8.     * @param file The file 
  9.     * @return 1 for directories and 2 for files 
  10.     */  
  11.    private int getType(File file) {  
  12.        if (file.isDirectory()) {  
  13.            return 1;  
  14.        } else {  
  15.            return 2;  
  16.        }  
  17.    }  

 我们可以看出,如果是directory的话是返回1的,如果是file的话是返回2. 就是directory永远小于file,真的不知道这个类在什么时候会用到。

 

4.  ExtensionFileComparator类的实现

     这个类从名称上应该可以看出是用来比较File的extension的,这个很好理解,但是在这里面有一个比较关键的就是比较的时候是case sensitive的还是insensitive的,这个里面在IO里面它实现了一个CaseSensitive这个类来实现的。我们下来分析一下这个类的实现:

       构造函数是可以传递一个IOCase对象,用来标记是Case Sensitive,默认是Case Sensitive的。

 

Java代码  收藏代码
  1. public ExtensionFileComparator() {  
  2.      this.caseSensitivity = IOCase.SENSITIVE;  
  3.  }  
  4.   
  5.   
  6.  public ExtensionFileComparator(IOCase caseSensitivity) {  
  7.      this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;  
  8.  }  

       这下面就是这个类比较关键的地方,就是获得文件的后缀名,然后使用caseSensitivity来比较文件的后缀名的。

 

Java代码  收藏代码
  1. public int compare(File file1, File file2) {  
  2.         String suffix1 = FilenameUtils.getExtension(file1.getName());  
  3.         String suffix2 = FilenameUtils.getExtension(file2.getName());  
  4.         return caseSensitivity.checkCompareTo(suffix1, suffix2);  
  5.     }  
 

5.  LastModifiedFileComparator类的实现

 

  这个类也比较好理解,就是用来比较文件的最后修改时间的,然后比较最后修改时间。

 

Java代码  收藏代码
  1. public int compare(File file1, File file2) {  
  2.         long result = file1.lastModified() - file2.lastModified();  
  3.         if (result < 0) {  
  4.             return -1;  
  5.         } else if (result > 0) {  
  6.             return 1;  
  7.         } else {  
  8.             return 0;  
  9.         }  
  10.     }  

 6.  NameFileComparator类的实现

 

   这个类其实也比较好理解,就是对文件名进行比较,凡是牵扯到字符串比较的,都有Case Sensitenvity的问题,所以在这个类的构造函数里面也会传递一个IOCase对象,在compareTo函数获得两个文件的文件名后直接使用文件名进行比较即可。这个代码我就不贴了,特别好理解。

 

 7 .  PathFileComparator类的实现

 

   这个类也比较好理解,就是对file的path进行比较,这个同样也有case sensitivity的问题,所以会在构造函数里面传递一个IOCase对象,在compareTo函数里面分别获取两个文件的path,然后调用IOCase进行比较。

 

 8 .  ReverseComparator类的实现

 

      这个类其实用的比较多,主要是想返回right和left的比较结果,所以在设计上也稍微比较高明一些,就是有一个delegate,然后在compareTo函数里面调用delegate的compareTo函数,不过把参数修改后compareTo(right,left),我想大家应该都明白怎么回事了,代码我就不贴上来了。

 

 

 9 .  SizeFileComparator类的实现

     这个类其实也比较好理解就是比较两个文件的大小,我们知道在Java里面File即可以是一个真实的File,也可以是一个Directory,所以遇到directory的时候我们到底要不要统计它的子元素的大小,所以他在设计的时候就考虑到了,专门设计了一个sumDirectoryContents变量,用来统计是不是计算directory里面文件的大学的总和。我们来具体的看一下代码:


Java代码  收藏代码
  1. public int compare(File file1, File file2) {  
  2.         long size1 = 0;  
  3.         if (file1.isDirectory()) {  
  4.             size1 = sumDirectoryContents && file1.exists() ? FileUtils.sizeOfDirectory(file1) : 0;  
  5.         } else {  
  6.             size1 = file1.length();  
  7.         }  
  8.         long size2 = 0;  
  9.         if (file2.isDirectory()) {  
  10.             size2 = sumDirectoryContents && file2.exists() ? FileUtils.sizeOfDirectory(file2) : 0;  
  11.         } else {  
  12.             size2 = file2.length();  
  13.         }  
  14.         long result = size1 - size2;  
  15.         if (result < 0) {  
  16.             return -1;  
  17.         } else if (result > 0) {  
  18.             return 1;  
  19.         } else {  
  20.             return 0;  
  21.         }  
  22.     }  



原创粉丝点击