Angesichts einer Liste von deviceIds, ich versuche, eine effizientere Art der Behandlung von Duplikaten zu finden. Wenn ein Duplikat in der DeviceId-Liste gefunden wird, muss ich nur die letzte Datei behalten und die anderen löschen. Was ich bis jetzt erreicht habe, scheint in Ordnung zu sein, aber ich frage mich, ob es effizienter gemacht werden kann? Meine aktuelle Methode scheint nicht gut zu skalieren, zum Beispiel verarbeitet sie 25.000 Dateien in 5 Sekunden, benötigt aber 70 Sekunden für 100.000 Dateien. Irgendwelche Gedanken?Versuchen, eine effizientere Möglichkeit zum Filtern von Dateien zu finden
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;
}
}
}
Edit:
implementiert ich TacticalCoders Lösung, die wunderbar funktioniert, Verarbeitung 100.000 Dateien in 0,60 Sekunden.
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();
}
}
Sie können eine Methode betrachten, die Ihre Liste in kleinere teilt (wie 25.000) tut Ihre Sortiermethode, dann führt sie zusammen mit einer Mergesort Art von Algorithmus –
Eine einfachere Komparator würde 'filea.lastModified() zurückgeben. fileb.lastModified()) '. Nicht schneller, nur ein bisschen sauberer. Aber Vorsicht Nullen (auch ein Problem in Ihrer Implementierung). –