Java sort按其扩展名排列的文件名字符串数组

时间:2009-01-13 19:32:21

标签: java arrays file sorting filenames

我有一个文件名数组,需要通过文件名的扩展名对该数组进行排序。有一个简单的方法吗?

8 个答案:

答案 0 :(得分:20)

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.Arraysjava.util.Comparator

答案 1 :(得分:4)

如果我没记错的话,Arrays.sort(...)需要一个Comparator&lt;&gt;它将用于进行排序。您可以提供它的实现,查看字符串的扩展部分。

答案 2 :(得分:3)

您可以实现自定义Comparator字符串。使其在最后一个'.'索引之后按子字符串排序。然后将比较器和数组传入

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

答案 3 :(得分:2)

比较器通常很难完全正确,并且必须为每次比较生成比较密钥,对于大多数排序算法而言,这意味着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很大,那么这可能是非常可测量的。

答案 4 :(得分:1)

创建比较器并比较字符串扩展名。看看下面的

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

然后将您的字符串列表传递给Arrays.sort(List,Comparator)

答案 5 :(得分:1)

创建您自己的Comparator,将字符串视为文件名,并根据扩展名对其进行比较。然后将Arrays.sort与Comparator参数一起使用。

答案 6 :(得分:1)

    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;

答案 7 :(得分:-1)

如果您只想按文件扩展名对文件进行分组,而不关心实际的字母顺序,可以使用:

我认为,当filenname没有“。”时,你可以做的最简单的事情也有效。只是反转名称并进行比较。

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的字符串甚至没有反向()。