HashMap .get () возвращает null для каждого значения, кроме последнего

У меня есть файл с разными именами:

Thomas Danny
Jack Thomas
Danny Mike
Thomas Kate
Victor James

Обновлено: у меня есть отдельные пробелы между именами, поэтому он правильно разбивается, это не проблема.

Каждая пара представляет, кто кого пригласил на вечеринку. Моя задача - добраться до конца цикла через HashMap. Например, когда в качестве аргумента указано «Кейт», программа должна распечатать «Джек», потому что Томас пригласил Кейт, а Джек пригласил Томаса.

Мой код на данный момент:

 Map<String, String> whoInvited = new HashMap<>();
    String[] pairs = text.split("\n");
    for (String pair : pairs){
        String[] invite = pair.split(" ");
        whoInvited.put(invite[1], invite[0]);
    }

    System.out.println(whoInvited.size())
    //Returns 5
    System.out.println(whoInvited.get("Danny"));
    //Returns null
    System.out.println(whoInvited.get("James"));
    //The only one that returns anything besides null(returns "Victor")

    String lookingFor = "Kate";
    while (whoInvited.containsKey(lookingFor)){
        lookingFor = whoInvited.get(lookingFor);
    }
    System.out.println(lookingFor);
}

Я не понимаю, как HashMap так запутался. Если я использую функцию .get () внутри цикла for, она дает мне идеальное значение, но сразу после завершения цикла он становится беспорядочным, имея только последнее значение.

Распечатка whoInvited дает мне просто "= Victor}"

Обновлено: ИСПРАВЛЕНО!

Пора использовать отладчик, чтобы увидеть, что на самом деле происходит во время выполнения кода.

Hovercraft Full Of Eels 01.05.2018 21:15

"дает мне просто" = Виктор} "" это говорит о том, что входные данные не то, что вы описываете.

Andy Turner 01.05.2018 21:17

Добавьте System.out.println(whoInvited);, чтобы увидеть содержимое whoInvited.

M. le Rutte 01.05.2018 21:17

@ M.leRutte последняя строка вопроса.

Andy Turner 01.05.2018 21:17

@AndyTurner System.out.println (LookingFor) ;?

M. le Rutte 01.05.2018 21:18

@ M.leRutte последнюю строку вопрос, а не код: "Распечатка whoInvited дает мне только" = Victor} "".

Andy Turner 01.05.2018 21:19

Пожалуйста, предоставьте минимальный воспроизводимый пример.

shmosel 01.05.2018 21:28

После загрузки карты вместо того, чтобы смотреть на отдельные записи, попробуйте распечатать всю карту System.out.println(whoInvited); и посмотрите, правильно ли она выглядит.

Bohemian 01.05.2018 21:28
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
8
85
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Он не помещает нули, у вас есть содержимое, разделенное пробелами. Когда вы разделяете пробел, вы получаете много пустых значений, потому что у вас есть несколько последовательных пробелов:

"Thomas    Danny".split(" ")
==> String[5] { "Thomas", "", "", "", "Danny" }

Это объясняет, почему invite[1] преобразуется в пустую строку. И поскольку ключи карты уникальны, каждая пустая клавиша перезаписывает предыдущую, и остается только последняя.

Вы можете обойти проблему, просто разделив на любое количество последовательных пробелов:

"Thomas    Danny".split(" +")
==> String[2] { "Thomas", "Danny" }

Проблема не в этом, просто я сначала неправильно отформатировал. Отредактировал как есть.

Home Boy 01.05.2018 21:24

Вы разделяете строки на пробелы, но это приведет к тому, что между пробелами внутри строки будут выдаваться пустые строки. Для вашего примера это означает, что invite[1] почти всегда будет "".

Это означает, что ключом всегда будет одно и то же значение, в результате чего будет сохранено только последнее значение. Чтобы исправить это, вы должны разделить, используя выражение регулярного выражения для обработки нескольких пробелов, например \s+, тогда значения в разделении будут фактическими строками.

Проблема не в этом, просто я сначала неправильно отформатировал. Отредактировал как есть.

Home Boy 01.05.2018 21:22

Между именами больше одного пробела. Лучше использовать регулярное выражение для разделения. Попробуйте pair.split ("+")

Обновлять: У вас формат файла unix или windows ??? Попробуйте это для разделения новой строки: Строки строки [] = string.split ("\ r? \ N");

Проблема не в этом, просто я сначала неправильно отформатировал. Отредактировал как есть.

Home Boy 01.05.2018 21:26

Обновлено: Ваш формат файла - unix или windows ??? Попробуйте это для разделения новой строки: String lines [] = string.split ("\\ r? \\ n");

Achu 01.05.2018 21:53
Ответ принят как подходящий

Возникшая у вас проблема вызвана тем, что окончания строк в разных операционных системах различаются. Windows использует \r\n, а Unix использует \n. При разделении на \n из-за \r происходят странные вещи. Замена text.split("\n") на text.split("\r\n") устранит проблему для Windows.

Разделите на \R, например: text.split("\\R"), что означает «перевод строки» для любой ОС.

Bohemian 01.05.2018 21:29

или text.split(System.lineSeparator())

Lino 01.05.2018 21:32

Другие вопросы по теме