Java 试图找到一种更有效的过滤文件的方法

Java 试图找到一种更有效的过滤文件的方法,java,Java,给出一个DeviceID列表,我正试图想出一种更有效的方法来处理重复项。当在deviceId列表中发现重复文件时,我只需要保留最新的文件并删除其他文件。到目前为止,我提出的方案似乎还可以,但我想知道是否可以提高效率?我目前的方法似乎不能很好地扩展,例如,它在5秒内处理25000个文件,但处理100000个文件需要70秒。有什么想法吗 List<File> filteredList; for(int i = 0; i < deviceIds.size(); i++

给出一个DeviceID列表,我正试图想出一种更有效的方法来处理重复项。当在deviceId列表中发现重复文件时,我只需要保留最新的文件并删除其他文件。到目前为止,我提出的方案似乎还可以,但我想知道是否可以提高效率?我目前的方法似乎不能很好地扩展,例如,它在5秒内处理25000个文件,但处理100000个文件需要70秒。有什么想法吗

List<File> filteredList;
        for(int i = 0; i < deviceIds.size(); i++) {
            if(i < (deviceIds.size()-1) && deviceIds.get(i).equals(deviceIds.get(i+1))) {
                filteredList = Lists.newArrayList(Iterables.filter(fileList, new DeviceIdFilter(deviceIds.get(i))));
                Collections.sort(filteredList, new OldestFileComparator());
                for(int t = 0; t < (filteredList.size()-1); t++) {
                    filteredList.get(t).delete();
                }
            }
        }

private static class DeviceIdFilter implements Predicate<File> {
    private String deviceId;
    private DeviceIdFilter(final String deviceId) {
        this.deviceId = deviceId;
    }
    @Override
    public boolean apply(final File file) {
        return file.getName().contains(deviceId);
    }
}

public class OldestFileComparator implements Comparator<File> {
    public int compare(File filea, File fileb) {
        if (filea.lastModified() > fileb.lastModified()) {
            return +1;
        } else if (filea.lastModified() < fileb.lastModified()) {
            return -1;
        } else {
            return 0;
        }
    }
}
列表过滤器列表;
对于(int i=0;ifileb.lastModified()){
返回+1;
}else if(filea.lastModified()
编辑:

我实现了TacticalCoders解决方案,它工作得非常出色,在0.60秒内处理了100000个文件

    Map<String, List<File>> fileMap = new HashMap<String,List<File>>();
    String deviceId;
    List<File> deviceFileList;
    for(File file : fileList) {
        deviceId = getDeviceId(file.getName());
        if(fileMap.containsKey(deviceId)) {
            fileMap.get(deviceId).add(file);
        } else {
            deviceFileList = new LinkedList<File>();
            deviceFileList.add(file);
            fileMap.put(deviceId, deviceFileList);
        }
    }

    for (Map.Entry<String, List<File>> mapEntry : fileMap.entrySet()) {
        deviceFileList = mapEntry.getValue();
        if(deviceFileList.size() > 1) {
            Collections.sort(deviceFileList, new OldestFileComparator());
            for(int t = 0; t < (deviceFileList.size()-1); t++) {
                deviceFileList.get(t).delete();
            }
        }
Map fileMap=newhashmap();
字符串设备ID;
列表设备文件列表;
用于(文件:文件列表){
deviceId=getDeviceId(file.getName());
if(fileMap.containsKey(deviceId)){
获取(设备ID).add(文件);
}否则{
deviceFileList=新链接列表();
添加(文件);
put(deviceId,deviceFileList);
}
}
对于(Map.Entry mapEntry:fileMap.entrySet()){
deviceFileList=mapEntry.getValue();
如果(deviceFileList.size()>1){
排序(deviceFileList,new-OldestFileComparator());
对于(int t=0;t<(deviceFileList.size()-1);t++){
deviceFileList.get(t.delete();
}
}
例如,我目前的方法似乎不能很好地扩展 5秒内处理25000个文件,但100000个文件需要70秒 档案,有什么想法吗

List<File> filteredList;
        for(int i = 0; i < deviceIds.size(); i++) {
            if(i < (deviceIds.size()-1) && deviceIds.get(i).equals(deviceIds.get(i+1))) {
                filteredList = Lists.newArrayList(Iterables.filter(fileList, new DeviceIdFilter(deviceIds.get(i))));
                Collections.sort(filteredList, new OldestFileComparator());
                for(int t = 0; t < (filteredList.size()-1); t++) {
                    filteredList.get(t).delete();
                }
            }
        }

private static class DeviceIdFilter implements Predicate<File> {
    private String deviceId;
    private DeviceIdFilter(final String deviceId) {
        this.deviceId = deviceId;
    }
    @Override
    public boolean apply(final File file) {
        return file.getName().contains(deviceId);
    }
}

public class OldestFileComparator implements Comparator<File> {
    public int compare(File filea, File fileb) {
        if (filea.lastModified() > fileb.lastModified()) {
            return +1;
        } else if (filea.lastModified() < fileb.lastModified()) {
            return -1;
        } else {
            return 0;
        }
    }
}
这是因为你有一个O(n^2)算法(如果你碰巧有很多重复的,它可能会退化到比O(n^2)更糟糕的程度,在这种情况下,除了你的两个for循环外,你还要做一个O(n log n)排序,但我认为你没有100000个文件基本上总是相同的重复)

如果我正确地理解了这个问题,您可以只做第一步,在这里您将构建一个映射(在这里,键将是对应于设备ID的(子)字符串)

在第一次传递之后,每个具有重复项的文件都将位于至少包含两个条目的列表中,而每个没有重复项的文件都将位于其自己的列表中

然后在地图上迭代,每次找到包含多个条目的列表时,根据日期对列表进行排序,并删除除最新文件以外的所有文件

这样行吗


编辑你必须小心使用你的设备ID:我根本不知道它们是什么样子,但是如果一个ID可以是,比如说“nop100”,而另一个设备ID可以是,比如说“nop1000”,那么如果你在“nop1000”之前处理“nop100”,你的contains方法调用可能会遇到麻烦(因为“nop1000”会错误地匹配“nop100”设备)。据我所知,这个问题也存在于您发布的部分代码中。当然有解决方法,但如果不了解您正在处理的文件名类型,则很难进一步解决。

您可以查看一种将列表划分为较小列表(如25000)的方法执行排序方法,然后使用mergesort类算法将它们合并在一起。一个更简单的比较器将返回
filea.lastModified().compareTo(fileb.lastModified())
。不是更快,只是更干净一点。但要注意空值(也是实现中的一个问题).TacticalCoder,感谢您提供了出色的解决方案。我实现了这一点,处理同一组100000个文件只需0.60秒。至于DeviceID,它们始终是固定长度(16个字符),因此所包含的字符串似乎是合适的。@Hoofamon:great:)哦,好的,如果设备ID总是16个字符长,那么您应该不会有任何问题。