vote up 2 vote down
star

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?

offensive?
add comment

7 Answers:

vote up 13 vote down
check
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.

link|offensive?
comments (8)
vote up 4 vote down

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.

link|offensive?
add comment
vote up 3 vote down

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('.'));
}
link|offensive?
add comment
vote up 1 vote down

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)

link|offensive?
add comment
vote up 1 vote down

Create your own Comparator that treats the strings as filenames and compares them based on the extensions. Then use Arrays.sort with the Comparator argument.

link|offensive?
add comment
vote up 0 vote down

I think the simplest thing you can do that also works when the filenname does not have a "." is to just reverse the names and compare them.

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

Its a shame that java's string does not even have a reverse().

link|offensive?
comments (2)
vote up 0 vote down

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.

link|offensive?
add comment

Your Answer:

Get an OpenID
or

Not the answer you're looking for? Browse other questions tagged or ask your own question.