#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
, удалите эту строку из списка.
Таким образом, окончательный алгоритм, вероятно, будет выглядеть примерно так:
- Прочитайте строки из файла, добавьте каждую строку в список.
- Отсортируйте список, используя один из ваших компараторов (только один раз), так же, как вы это делаете в данный момент.
- Выполните цикл по списку. Проверьте, допустима ли строка для записи в файл (
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);
// ...
}