Java сортирует строковый массив имен файлов по их расширению - PullRequest
5 голосов
/ 13 января 2009

У меня есть массив имен файлов, и мне нужно отсортировать этот массив по расширениям имени файла. Есть ли простой способ сделать это?

Ответы [ 8 ]

20 голосов
/ 13 января 2009
Arrays.sort(filenames, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        // the +1 is to avoid including the '.' in the extension and to avoid exceptions
        // EDIT:
        // We first need to make sure that either both files or neither file
        // has an extension (otherwise we'll end up comparing the extension of one
        // to the start of the other, or else throwing an exception)
        final int s1Dot = s1.lastIndexOf('.');
        final int s2Dot = s2.lastIndexOf('.');
        if ((s1Dot == -1) == (s2Dot == -1)) { // both or neither
            s1 = s1.substring(s1Dot + 1);
            s2 = s2.substring(s2Dot + 1);
            return s1.compareTo(s2);
        } else if (s1Dot == -1) { // only s2 has an extension, so s1 goes first
            return -1;
        } else { // only s1 has an extension, so s1 goes second
            return 1;
        }
    }
});

Для полноты: java.util.Arrays и java.util.Comparator.

4 голосов
/ 13 января 2009

Если я правильно помню, Arrays.sort (...) берет Comparator <>, который он будет использовать для сортировки. Вы можете предоставить реализацию, которая смотрит на часть расширения строки.

3 голосов
/ 13 января 2009

Вы можете реализовать пользовательский Компаратор строк. Сделайте так, чтобы они сортировали их по подстроке после последнего индекса '.'. Затем передайте компаратор и ваш массив в

Arrays.sort(stringArray, yourComparator);

//  An implementation of the compare method
public int compare(String o1, String o2) {
    return o1.substring(o1.lastIndexOf('.')).compareTo(o2.substring(o2.lastIndexOf('.'));
}
2 голосов
/ 14 января 2009

Компараторы часто трудно получить точно правильно, и ключ сравнения должен генерироваться для каждого сравнения, которое для большинства алгоритмов сортировки означает O (n log n). Другой подход заключается в создании пар (ключ, значение) для каждого элемента, который необходимо отсортировать, поместить их в TreeMap и затем запросить значения, поскольку они отсортированы по ключу.

Например

import java.util.Arrays;
import java.util.TreeMap;

public class Bar {

    public static void main(String[] args) {
        TreeMap<String, String> m2 = new TreeMap<String, String>();
        for (String string : Arrays.asList(new String[] { "#3", "#2", "#1" })) {
            String key = string.substring(string.length() - 1);
            String value = string;
            m2.put(key, value);
        }
        System.out.println(m2.values());
    }
}

распечатывает

[#1, #2, #3]

Вы легко сможете адаптировать вычисления ключа к вашей проблеме.

Это вычисляет ключ только один раз для каждой записи, следовательно, O (n) - (но сортировка по-прежнему O (n log n)). Если вычисление ключа дорого или n велико, это может быть вполне измеримо.

1 голос
/ 18 октября 2017
    String DELIMETER = File.separator + ".";
    List<String> orginalList = new CopyOnWriteArrayList<>(Arrays.asList(listOfFileNames));
    Set<String> setOfuniqueExtension = new TreeSet<>();

    for (String item : listOfFileNames) {
        if (item.contains(".")) {
            String[] split = item.split(DELIMETER);
            String temp = "." + split[split.length - 1];
            setOfuniqueExtension.add(temp);
        }
    }

    List<String> finalListOfAllFiles = new LinkedList<>();
    setOfuniqueExtension.stream().forEach((s1) -> {
        for (int i = 0; i < orginalList.size(); i++) {
            if (orginalList.get(i).contains(s1)) {
                finalListOfAllFiles.add(orginalList.get(i));
                orginalList.remove(orginalList.get(i));
                i--;
            }
        }
    });

    orginalList.stream().filter((s1) -> (!finalListOfAllFiles.contains(s1))).forEach((s1) -> {
        finalListOfAllFiles.add(s1);
    });

    return finalListOfAllFiles;
1 голос
/ 13 января 2009

Создайте свой собственный Comparator , который обрабатывает строки как имена файлов и сравнивает их на основе расширений. Затем используйте Arrays.sort с аргументом Comparator.

1 голос
/ 13 января 2009

Создайте компаратор и сравните строковые расширения. Взгляните на следующее

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html

Затем передайте свой список строк в Arrays.sort (список, компаратор)

0 голосов
/ 14 января 2009

Если вы просто хотите сгруппировать файлы по их расширению и не заботиться о фактическом алфавитном порядке, вы можете использовать это:

Я думаю, что самое простое, что вы можете сделать, это также работает, когда имя файла не имеет "." это просто поменять имена и сравнить их.

Arrays.sort(ary, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        String r1 = new StringBuffer(o1).reverse().toString();
        String r2 = new StringBuffer(o2).reverse().toString();
        return r1.compareTo(r2);
    }
});

Жаль, что у строки Java даже нет обратного ().

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