Collections.sort() не сортирует в правильном порядке

#java #sorting #collections

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

Вопрос:

У меня есть этот код на Java:

 List<String> unSorted = new ArrayList<String>();
List<String> beforeHash = new ArrayList<String>();
String[] unSortedAux, beforeHashAux; 
String line = null;

BufferedReader reader = new BufferedReader(new FileReader("C:\CPD\temp0.txt"));
    while ((line = reader.readLine()) != null){
        unSorted.add(line);  
        beforeHash.add(line.split("#")[0]); 

    }
    reader.close();

    Collections.sort(beforeHash);
    beforeHashAux = beforeHash.toArray(new String[beforeHash.size()]);
    unSortedAux = unSorted.toArray(new String[unSorted.size()]);

    System.out.println(Arrays.toString(beforeHashAux));
    System.out.println(Arrays.toString(unSortedAux));
 

Он считывает файл с именем temp0.txt , который содержит:

 Carlos Magno#261
Mateus Carl#12
Analise Soares#151
Giancarlo Tobias#150
 

Моя цель — отсортировать имена в строке без строки после «#». Я использую beforeHash.add(line.split(«#»)[0]); чтобы сделать это. Проблема в том, что он правильно считывает файл, но сортирует в неправильном порядке. Соответствующие выходные данные:

 [Analise Soares, Giancarlo Tobias, Mateus Carl, Carlos Magno]
[Carlos Magno#261, Mateus Carl#12, Analise Soares#151, Giancarlo Tobias#150]
 

Первый результат является «отсортированным», обратите внимание, что «Карлос Магно» идет после «Матеус Карл». Я не могу найти проблему в своем коде.

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

1. Нет необходимости в коде ввода-вывода в вашем примере. Вы могли бы упростить его до постоянного списка, чтобы избавить нас всех от создания файлов.

2. Что такое beforeHash ? Можете ли вы показать нам его декларацию?

3. Вы упустили всю важную информацию: что такое объявление beforeHash и тип содержащихся элементов.

4. извините за это, я отредактирую его

5. beforeHash — это anArrayList<String>();, я знаю, что это неправильное имя, оно в основном берет ту часть строки, которая стоит перед «#» (хэш) и помещает ее в список

Ответ №1:

Проблема в том, что «Карлос Магно» начинается с знака порядка байтов в Юникоде.

Если вы скопируете и вставите свой образец текста ( [Analise ... Carlos Magno] ) в проводник Unicode, вы увидите, что непосредственно перед «C» Карлоса Магно у вас есть U FEFF.

В принципе, вам нужно будет удалить это при чтении файла. Самый простой способ сделать это — просто использовать:

 line = line.replace("ufeff", "");
 

… или сначала проверьте:

 if (line.startsWith("ufeff")) {
    line = line.substring(1);
}
 

Обратите внимание, что вы действительно должны указать кодировку, которую хотите использовать при открытии файла — используйте a FileInputStream , завернутый в an InputStreamReader .

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

1. 1 Но я неохотно нажимаю на ссылки tinyurl… почему бы не разместить полную ссылку на csharpindepth.com/Articles/General/Unicode.aspx#explorer ?

2. @Duncan: Потому что это легче запомнить tinyurl.com/unicode-explorer , и другие, возможно, захотят запомнить это для себя. Вы всегда можете использовать preview.tinyurl.com/unicode-explorer если вы хотите — но непонятно, почему вы доверяете csharpindepth.com в течение tinyurl.com ссылка…

3. О, спасибо за ответ, я сходил с ума от этой проблемы.

4. Просто любопытно, как мог кто-то, кто никогда не был сожжен невидимыми персонажами, обнаружить это? Это просто что-то, о чем вы прочитали / испытали один раз, а затем запомнили?

5. @user3580294: Вроде того. Сначала я воспроизвел проблему, используя текст в сообщении, затем я начал смотреть на то, из чего на самом деле состоят данные.