Java sort String array of file names by their extension

前端 未结 8 766
后悔当初
后悔当初 2021-01-13 02:29

I have an array of filenames and need to sort that array by the extensions of the filename. Is there an easy way to do this?

相关标签:
8条回答
  • 2021-01-13 02:36

    Comparators are often hard to get exactly right, and the comparison key has to be generated for every comparison which for most sorting algorithms mean O(n log n). Another approach is to create (key, value) pairs for each item you need to sort, put them in a TreeMap, and then ask for the values as these are sorted according to the key.

    For instance

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

    prints out

    [#1, #2, #3]
    

    You should easily be able to adapt the key calculation to your problem.

    This only calculates the key once per entry, hence O(n) - (but the sort is still O(n log n)). If the key calculation is expensive or n is large this might be quite measurable.

    0 讨论(0)
  • 2021-01-13 02:42
    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;
            }
        }
    });
    

    For completeness: java.util.Arrays and java.util.Comparator.

    0 讨论(0)
  • 2021-01-13 02:45

    Create a Comparator and compare the string extensions. Take a look at the following

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

    Then pass in your List of strings to Arrays.sort(List, Comparator)

    0 讨论(0)
  • 2021-01-13 02:48

    You can implement a custom Comparator of Strings. Make it sort them by the substring after the last index of '.'. Then pass in the comparator and your array into

    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('.'));
    }
    
    0 讨论(0)
  • 2021-01-13 02:48
        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;
    
    0 讨论(0)
  • 2021-01-13 02:54

    If I remember correctly, the Arrays.sort(...) takes a Comparator<> that it will use to do the sorting. You can provide an implementation of it that looks at the extension part of the string.

    0 讨论(0)
提交回复
热议问题