Как отсортировать коллекцию имен файлов по номерам, а не по алфавиту? - PullRequest
0 голосов
/ 05 мая 2019

Я сейчас использую 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 ]

1 голос
/ 05 мая 2019

Поместите этот параметр 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);
0 голосов
/ 05 мая 2019

Вы ищете натуральный компаратор, который понимает последовательность чисел.

Вы можете использовать один из них:

Первый может использоваться как зависимость maven, однако, поскольку Comparator не реализует Comparator<String> (а скорее только Comparator), вы также можете сделать запрос на вытягивание для этого.

Последний, вероятно, лучший, так как это ASL 2.0.

Кстати, вы должны продолжать использовать File (или Path) в TreeSet и передавать в компараторе:

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

Эта сортирует File записей по имени, используя naturalSortComparator.

0 голосов
/ 05 мая 2019

Этот компаратор должен решить вашу проблему.

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;
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...