0

我正在使用 Comparator 按大小比较文件,但是当我尝试编译我的代码时,我收到警告:“java 使用未经检查或不安全的操作”。我将我的代码放入注释中,然后程序运行了,所以我认为是在 Comparator 类中排序的问题。这是我的代码:

public class size implements Comparator {

    @Override
    public int compare(Object o1, Object o2) {

        long s1 = ((Class)o1).getSize();
        long s2 = ((Class)o2).getSize();

        if (s1 > s2){
            return 1;
        }
        else if (s1 < s2){
            return -1;
        }
        else {
            return 0;
        }
    }
}
4

7 回答 7

3

这两行包含不安全的强制转换:

long s1 = ((Class)o1).getSize();
long s2 = ((Class)o2).getSize();

不安全的强制转换是这个表达式:(Class)o1,你将 o1 是一个对象转换为一个类,而没有事先检查它o1是一个实例Class

如果您向方法提供 Class 实例,则您的程序运行良好。问题是您无法确保没有人使用不是类的对象调用您的方法。

您应该实现一个类型安全的比较器,前提是您的 java 版本比 1.4 更新。

public class size implements Comparator<Class> {   
    @Override
    public int compare(Class o1, Class o2) {
        // compare the two class objects
于 2013-05-23T13:27:22.600 回答
2

将您声明Comparator为 aComparator<File>并将比较方法替换为

compare(File o1, File o2)

编辑:或者Comparator<Class>如果您正在比较课程。这就是你似乎在做的

于 2013-05-23T13:27:49.927 回答
2

我认为代码中有错误。你应该这样做:

 public static void main(String[] args) {
    File parentFile = new File("path to your parent file");
    File[] files = parentFile.listFiles();
    Arrays.sort(files, new Comparator<File>() {
    @Override
    public int compare(File o1, File o2) {
        return new Long(o1.length()).compareTo(o2.length());
    }
});
于 2013-05-23T13:31:01.080 回答
0

您应该使用 o1.getClass() 而不是强制转换

于 2013-05-23T13:28:31.820 回答
0

首先,您使用 Comparator 作为原始类型。这是错误的,向它添加一个类型参数,然后实现compare(File, File).

其次,Comparator 的性能会很糟糕,因为会length导致本地系统调用来找出文件的大小。

要解决性能问题,您需要为文件编写一个包装类。可以Comparable直接实现:

public class FileBySize implements Comparable<FileBySize> {
   private final File f;
   private final Long size;
   public FileBySize(File f) { this.f = f; this.size = f.length(); }
   @Override public int compareTo(FileBySize other) {
     return this.size.compareTo(other.size);
   }
}
于 2013-05-23T13:32:05.567 回答
0

这是对的。Comparator是一个参数化接口,即用泛型定义的类。

这是您应该实现比较器以避免警告和ClassCasetException抛出机会的方式:

public class SizeComparator implements Comparator<Object> {
......
}

你的比较器有点特别。它适用于任何对象。这是我在Comparator<Object>这里写的一个原因。在大多数情况下,您会更具体地定义类参数并在compare()方法中使用相同的类,例如

public class SizeComparator implements Comparator<String> {
     public int compare(String s1, String s2) {
         .......
     }
}

顺便说一句,在您的情况下,您还可以将比较器定义如下:

public class SizeComparator implements Comparator<T extends Object> {
     public int compare(T o1, T o2) {
         .......
     }
}

并注意我更改了您的班级名称这一事实。遵循广为人知的命名约定很重要。

于 2013-05-23T13:32:15.320 回答
-1
long s1 = ((Class)o1).getSize();

是它抱怨的地方。我认为这解决了它:

if(o1 instanceof Class)  
{  
     long s1 = ((Class)o1).getSize();
}  

本质上你并不能保证这o1是一个Class

于 2013-05-23T13:25:23.150 回答