【问题标题】:How to sort a list that contains numbers and special characters alphabetically?如何按字母顺序对包含数字和特殊字符的列表进行排序?
【发布时间】:2019-04-03 06:38:08
【问题描述】:

我的问题实际上是双重的,但首先,我正在尝试编写一个按字母顺序对列表进行排序并将其写入文件的程序,但是在尝试对文件进行排序时,带有特殊字符或数字的行的那一刻是引入,排序不再起作用。如果列表只是以字母开头的字符串,那么它的排序和写入都非常好,而且是按顺序排列的。

我只是在由输入文件中的行组成的字符串列表上使用Collections.sort,然后我试图将它们写入输出文件。

我的输入文件包含以下几行:

These are some test lines
short line
abcdefghij
this line is much longer than the short line
123 456
#Ignore this line
Blah blah blah
# ignore this, too

我的输出文件最终被排序到:

# ignore this, too
#Ignore this line
123 456
Blah blah blah
These are some test lines
abcdefghij
short line
this line is much longer than the short line

至于第二个问题,我想以某种方式排除带有 # 的行被写入文件。 这是我的代码:

BufferedReader inputStream = null;
        PrintWriter outputStream = null;
        String inFile = args[0];
        String outFile = args[1];
        List<String> lines = new LinkedList<>();

        try {
            inputStream =
                    new BufferedReader(new FileReader(inFile));
            outputStream=
                    new PrintWriter(new FileWriter(outFile));
            String line;
            while ((line = inputStream.readLine()) != null) {
                lines.add(line);
                if(args[2].equals("LONGESTFIRST") ) {
                    Collections.sort(lines, new Comparator<String>() {
                        @Override
                        public int compare(String o1, String o2) {
                            return o2.length() - o1.length();
                        }
                    });
                } else if (args[2].equals("SHORTESTFIRST")) {
                    Collections.sort(lines, new Comparator<String>() {
                        @Override
                        public int compare(String o1, String o2) {
                            return o1.length() - o2.length();
                        }
                    });
                } else if (args[2].equals("LEXICOGRAPHIC")) {
                    Collections.sort(lines);
                } else if (args[2].equals("REVERSE")) {
                    Collections.sort(lines, Collections.reverseOrder());
                }
            }
            for (int i = 0; i < lines.size(); i++) {
                outputStream.println(lines.get(i));
            }

我尝试过在 if(!lines.startsWith("#") { 之类的 if 语句中包含倒数第二行,但不幸的是,这不起作用。

顺便说一句,文字墙很抱歉!

【问题讨论】:

  • 关于您的第一个问题:您的列表排序。如果您想要另一种排序方式,请准确说出它应该是什么。关于第二个:如果它以#开头,请不要将行添加到列表或输出中。 lines.startsWith("#") 不可能工作,因为 lines 不是 a 行,而是整个行列表。 line,或lines.get(i),是一行。
  • 您已经在实现compare 方法。将实现更改为您想要的顺序应该不会那么复杂......
  • @JBNizet 感谢您的回复!你肯定已经解决了第二个问题。至于第一个,它是如何按字母顺序排序的?如果是这种情况,“abcdefghij”将在“blah blah blah”之前。我对排序的理解是默认情况下会按字母顺序排序。
  • STRing 的自然顺序不是字母顺序。这是字典顺序。所有小写​​字母都按字典顺序排在大写字母之前(这只是字符的顺序,基于您的数字 unicode 值)。您需要不区分大小写的排序(请参阅 String 类中定义的常量)或 Collat​​or(它还将处理重音字母和其他特定于语言环境的规则)。
  • @JBNizet 哦,好吧,太好了!我只是完全误解了字典顺序,并认为它与字母顺序相同,感谢您澄清这一点。那么一切都很好!

标签: java sorting collections io


【解决方案1】:

第一件事是:您不必在每次插入到列表后对列表进行排序。

第二个是:如果您不希望输出中出现带有# 字符的行,您可以使用list.get(i).contains("#") 进行检查。如果它返回true,则从列表中删除这一行。

所以最终的算法可能看起来像:

  1. 从文件中读取行,将每一行添加到列表中。
  2. 使用您的一个比较器(仅一次)对列表进行排序,方法与您当前的操作相同。
  3. 遍历列表。检查一行是否对写入文件有效(list.get(i).contains("#") 或您喜欢的任何内容),如果是,则将其写入文件。


更新:
对于不区分大小写的排序,您可能希望使用String 类提供的默认比较器CASE_INSENSITIVE_ORDER

List<String> myList = ...;
Collections.sort(myList, String.CASE_INSENSITIVE_ORDER);

【讨论】:

    【解决方案2】:

    您不必将这些行放在列表中

    while ((line = inputStream.readLine()) != null) {
      if (line.startsWith("#"))
        continue;
      lines.add(line);
      // ...
    }
    

    【讨论】:

      猜你喜欢
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多