Как отсортировать список, содержащий цифры и специальные символы в алфавитном порядке?

#java #sorting #collections #io

#java #сортировка #Коллекции #io

Вопрос:

Мой вопрос на самом деле двоякий, но, во-первых, я пытаюсь написать программу, которая сортирует список по алфавиту и записывает его в файл, но при попытке отсортировать файл, в тот момент, когда вводятся строки со специальными символами или цифрами, сортировка больше не работает. Если список представляет собой просто строки, начинающиеся с букв, он отлично сортируется и записывается по порядку.

Я просто использую 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, например if(!lines.startsWith("#") { … но, к сожалению, это не работает.

Кстати, извините за стену текста!

Комментарии:

1. Что касается вашего первого вопроса: ваш список отсортирован. Если вам нужен другой способ сортировки, то точно скажите, каким он должен быть. Что касается второго: просто не добавляйте строку в список или в выходные данные, если она начинается с #. lines.startsWith("#") не может работать, поскольку lines это не строка, а весь список строк. line или lines.get(i) это строка.

2. вы уже реализуете compare метод. Не должно быть так сложно изменить реализацию, чтобы она располагалась в нужном вам порядке…

3. @JBNizet Спасибо за ответ! Вы определенно ответили на второй вопрос. Что касается первого, как он сортируется в алфавитном порядке? Если бы это было так, «abcdefghij» было бы перед «бла-бла-бла». Я понимаю сортировку так, что по умолчанию она будет сортироваться в алфавитном порядке.

4. Естественный порядок строк не является алфавитным порядком. Это лексикографический порядок. Все строчные буквы идут перед прописной буквой в лексикографическом порядке (это просто порядок символов, основанный на числовом значении unicode). Вам нужен порядок без учета регистра (см. Константы, определенные в классе String) или средство сортировки (которое также будет обрабатывать буквы с ударением и другие правила, зависящие от локали).

5. @JBNizet О, ладно, отлично! Я просто совершенно неправильно понял лексикографический порядок и думал, что он такой же, как алфавитный, спасибо, что прояснили это. Тогда все хорошо!

Ответ №1:

Во-первых, вам не нужно сортировать список после каждой вставки в список.

Второй: если вы не хотите, чтобы в выходных данных присутствовали строки с # символами, вы можете просто проверить это с помощью list.get(i).contains("#") . И если он вернется true , удалите эту строку из списка.

Таким образом, окончательный алгоритм, вероятно, будет выглядеть примерно так:

  1. Прочитайте строки из файла, добавьте каждую строку в список.
  2. Отсортируйте список, используя один из ваших компараторов (только один раз), так же, как вы это делаете в данный момент.
  3. Выполните цикл по списку. Проверьте, допустима ли строка для записи в файл ( list.get(i).contains("#") или все, что вам нравится), и если да, запишите ее в файл.

Обновить:
Для сортировки без учета регистра вы, вероятно, захотите использовать компаратор по умолчанию, CASE_INSENSITIVE_ORDER предоставляемый String class:

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

Ответ №2:

Вам просто не нужно помещать такие строки в список

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