HashMap .get () возвращает ноль для каждого значения, кроме последнего - PullRequest
0 голосов
/ 01 мая 2018

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

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}"

РЕДАКТИРОВАТЬ: ИСПРАВЛЕНО!

Ответы [ 4 ]

0 голосов
/ 01 мая 2018

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

0 голосов
/ 01 мая 2018

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

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

0 голосов
/ 01 мая 2018

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

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

0 голосов
/ 01 мая 2018

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

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

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

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

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