Учитывая список устройств, я пытаюсь найти более эффективный способ обработки дубликатов. Когда дубликат найден в списке deviceId, мне нужно сохранить только последний файл и удалить остальные. То, что я придумал, похоже, работает нормально, но мне интересно, можно ли сделать его более эффективным? Мой текущий метод, похоже, не очень хорошо масштабируется, например, он обрабатывает 25 000 файлов за 5 секунд, но занимает 70 секунд для 100 000 файлов. Есть предположения?Попытка найти более эффективный способ фильтрации файлов
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:
Я реализовал TacticalCoders решение, которое работало замечательно, обработку 100000 файлов в 0,60 секунды.
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();
}
}
Вы можете посмотреть на метод, который делит ваш список на более мелкие (например, 25 000), делает ваш метод сортировки, затем объединяет их вместе с алгоритмом слияния типа –
Простой компаратор возвращает 'filea.lastModified(). CompareTo (fileb.lastModified()) '. Не быстрее, просто немного чище. Но будьте осторожны с нулями (также проблема в вашей реализации). –