如何按数字而不是字母顺序对文件名集合进行排序?

时间:2019-05-05 08:56:39

标签: java string sorting collections

我目前正在使用SortedSet<String> fileNames = new TreeSet<String>()对文件名进行排序,但是并没有按照我想要的顺序进行排序。

那正是我要做的:

File folder = new File(PATH);
File[] listOfFiles = folder.listFiles();
SortedSet<String> fileNames = new TreeSet<String>;
for (int i = 0; i < listOfFiles.length; i++) 
{
     if (listOfFiles[i].isFile())
     {
        fileNames.add(listOfFiles[i].getName());
     }
}

输出:

X_1(1).PNG
X_1(2).PNG 
X_1(3).PNG 
X_10(1).PNG
X_10(2).PNG
X_10(3).PNG
X_100(1).PNG
X_100(2).PNG
X_100(3).PNG 

所需的输出:

X_1(1).PNG
X_1(2).PNG
X_1(3).PNG
X_2(1).PNG
X_2(2).PNG
X_2(3).PNG

3 个答案:

答案 0 :(得分:1)

将此Comparator参数放入TreeSet构造函数中:

Comparator<String> stringComparator = (o1, o2) -> {
  int o1FirstNum = Integer.parseInt(o1.substring(o1.indexOf('_') + 1, o1.indexOf('(')));
  int o2FirstNum = Integer.parseInt(o2.substring(o2.indexOf('_') + 1, o2.indexOf('(')));

  if (o1FirstNum == o2FirstNum) {
    int o1SecondNum = Integer.parseInt(o1.substring(o1.indexOf('(') + 1, o1.indexOf(')')));
    int o2SecondNum = Integer.parseInt(o2.substring(o2.indexOf('(') + 1, o2.indexOf(')')));
    return o1SecondNum - o2SecondNum;
  }

  return o1FirstNum - o2FirstNum;
};

SortedSet<String> fileNames = new TreeSet<String>(stringComparator);

答案 1 :(得分:0)

此比较器应该可以解决您的问题。

public class Test {

    public static void main(String... args) {
        String[] list = {"X_1(1).PNG", "X_1(2).PNG", "X_1(3).PNG", "X_10(1).PNG", "X_10(2).PNG", "X_10(3).PNG", "X_100(1).PNG", "X_100(2).PNG", "X_100(3).PNG"};

        SortedSet<String> fileNames = new TreeSet<>(Test::compare);
        fileNames.addAll(Arrays.asList(list));

        fileNames.forEach(System.out::println);
    }

    private static int compare(String first, String second) {
        int firstNumber = Integer.parseInt(first.substring(first.indexOf('_') + 1, first.indexOf('(')));
        int secondNumber = Integer.parseInt(second.substring(first.indexOf('_') + 1, second.indexOf('(')));

        int difference = firstNumber - secondNumber;

        if (difference != 0) {
            return difference;
        }

        firstNumber = Integer.parseInt(first.substring(first.indexOf('(') + 1, first.indexOf(')')));
        secondNumber = Integer.parseInt(second.substring(first.indexOf('(') + 1, second.indexOf(')')));

        return firstNumber - secondNumber;
    }

}

答案 2 :(得分:0)

您正在寻找一种自然排序比较器,该比较器可以理解数字序列。

您可以使用以下之一:

第一个可以用作Maven依赖项,但是由于Comparator不实现Comparator<String>(而仅实现Comparator),因此您也可以执行拉取请求。

最后一个可能是最好的,因为它是ASL 2.0。

顺便说一句,您应该继续使用TreeSet中的File(或Path)并传递一个比较器:

Comparator<String> naturalSortComparator = ...;
TreeSet<File> files = new TreeSet<>(Comparators.comparing(File::getName, naturalSortComparator));

此人将使用File按名称对naturalSortComparator个条目进行排序。