【问题标题】:Java sort String array of file names by their extensionJava 按扩展名对文件名的字符串数组进行排序
【发布时间】:2010-10-01 05:23:21
【问题描述】:

我有一个文件名数组,需要按文件名的扩展名对该数组进行排序。有没有简单的方法可以做到这一点?

【问题讨论】:

    标签: java arrays file sorting filenames


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您可以实现自定义的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】:

        创建一个比较器并比较字符串扩展名。下面一起来看看

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

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            【解决方案5】:
            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 会使其检查完整的文件名,而不是简单地抛出 IndexOutOfBoundsException。这要么是一个错误,要么是一个出色的隐藏功能。 :)
            • 再想一想,这是一个错误(如果只有一个文件有扩展名怎么办?)。我将不得不编辑代码以更正它。
            • 很高兴您正在思考确切的实现方式;)
            【解决方案6】:

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

            我认为当文件名没有“。”时,您可以做的最简单的事情也适用。就是把名字倒过来比较一下。

            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的字符串连reverse()都没有。

            【讨论】:

            • 您确定要 r1.compareTo(r2) 而不是相反?
            • 取决于排序顺序是否真的很重要,或者您是否只想将具有相同扩展名的文件组合在一起。
            • 这根本不起作用,例如.png会排在.jpg之前。
            • @christoffer 你是对的,它根本不起作用......这种排序只是将具有相同扩展名的文件组合在一起,但顺序不是按字母顺序排列的。感谢您指出这一点,我已经更新了描述
            【解决方案7】:

            比较器通常很难完全正确,并且必须为每次比较生成比较键,对于大多数排序算法来说,这意味着 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 很大,这可能是相当可衡量的。

            【讨论】:

              【解决方案8】:
                  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;
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-07-02
                • 2015-02-21
                • 2012-10-14
                • 1970-01-01
                • 2017-11-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多