Java实现文件夹PDF文件反向语义排序出错求助
问题
需要将一组PDF文件按反向语义排序,涉及文件:
- Release_Notes_CNV_22.3.pdf
- Release_Notes_CNV_22.9.pdf
- Release_Notes_CNV_22.12.pdf
- Release_Notes_CNV_23.5.pdf
编写的Comparator排序代码出现错误,当前排序结果:
- Release_Notes_CNV_23.5.pdf
- Release_Notes_CNV_22.12.pdf
- Release_Notes_CNV_22.3.pdf // 错误位置
- Release_Notes_CNV_22.9.pdf
正确排序顺序应为:
- Release_Notes_CNV_23.5.pdf
- Release_Notes_CNV_22.12.pdf
- Release_Notes_CNV_22.9.pdf
- Release_Notes_CNV_22.3.pdf
代码如下:
private String getReleaseNotesPdfFileAbsolutePath(long number) { File folder = new File(String.format("%s%s%s", appHome, File.separator, releaseNotesFilesHomeFolderName)); File[] fileNames = folder.listFiles(); int i=1; Arrays.sort(fileNames, new Comparator<File>() { @Override public int compare(File o1, File o2) { float n1 = extractNumber(o1.getName()); float n2 = extractNumber(o2.getName()); int val = (int)n2 - (int)n1; System.out.println(n2 + " " + (int)n2 + " : " + n1 + " " + (int)n1 + " : " + val); return val; } private float extractNumber(String name) { float i = 0; try { int s = name.lastIndexOf('_')+1; int e = name.lastIndexOf('.'); String number = name.substring(s, e); i = Float.parseFloat(number); } catch(Exception e) { i = 0; // if filename does not match the format // then default to 0 } return i; } }); for(File file : fileNames){ if( i == number ) { return String.format("%s%s%s%s%s", appHome, File.separator, releaseNotesFilesHomeFolderName, File.separator, file.getName()); } i = i+1; } return String.format("%s%s%s%s%s", appHome, File.separator, releaseNotesFilesHomeFolderName, File.separator, Constants.RELEASE_NOTES_PDF); }
问题排查与修复
错误原因
代码中把提取到的浮点型版本号强制转为int后再做减法比较,直接丢失了小数部分的信息:
- 22.3和22.9转为int后都是22,两者相减结果为0,Comparator会判定这两个文件排序优先级相同,最终顺序由系统默认排序逻辑决定,导致错误顺序。
- 22.12转为int后也是22,和其他22.x版本的int值相同,同样会被判定为优先级相同,无法体现22.12 > 22.9 > 22.3的语义顺序。
修复方案
直接使用浮点型数值进行比较,借助Float.compare()方法保证比较逻辑的正确性,同时实现降序排序需求。
修复后的代码:
private String getReleaseNotesPdfFileAbsolutePath(long number) { File folder = new File(String.format("%s%s%s", appHome, File.separator, releaseNotesFilesHomeFolderName)); File[] fileNames = folder.listFiles(); int i=1; Arrays.sort(fileNames, new Comparator<File>() { @Override public int compare(File o1, File o2) { float n1 = extractNumber(o1.getName()); float n2 = extractNumber(o2.getName()); // 用Float.compare实现降序排序,n2在前表示数值大的文件排前面 int val = Float.compare(n2, n1); System.out.println(n2 + " : " + n1 + " : " + val); return val; } private float extractNumber(String name) { float i = 0; try { int s = name.lastIndexOf('_')+1; int e = name.lastIndexOf('.'); String number = name.substring(s, e); i = Float.parseFloat(number); } catch(Exception e) { i = 0; // 不符合格式的文件默认优先级最低 } return i; } }); for(File file : fileNames){ if( i == number ) { return String.format("%s%s%s%s%s", appHome, File.separator, releaseNotesFilesHomeFolderName, File.separator, file.getName()); } i = i+1; } return String.format("%s%s%s%s%s", appHome, File.separator, releaseNotesFilesHomeFolderName, File.separator, Constants.RELEASE_NOTES_PDF); }
改动说明
- 替换
(int)n2 - (int)n1为Float.compare(n2, n1):保留版本号的完整浮点数值信息,确保22.9 > 22.3、22.12 > 22.9的比较逻辑正确。 Float.compare(n2, n1)的返回规则:- 返回正数:当n2 > n1时
- 返回0:当n2 == n1时
- 返回负数:当n2 < n1时
完全符合反向(降序)排序的需求。
内容的提问来源于stack exchange,提问作者Vansh
相关产品推荐
相关产品推荐

