Как заменить символы в LinkedHashMap?

#java

#java

Вопрос:

Я написал метод, который создает карту символов входной строки, но мне нужно, чтобы все пробелы этой строки были помещены в конец карты.

Пример ввода: «abc de»

Пример вывода :

 "A" - quantity
"B" - quantity
"C" - quantity
"D" - quantity
"E" - quantity
" " - quantity
  

Вот мой код:

 public LinkedHashMap<Character, Integer> output() {
    LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
    for (int i = 0; i < inputString.length(); i  ) {
        char wordToLetter = inputString.toLowerCase().charAt(i);
        if (map.containsKey(wordToLetter)) {
            int quantity = map.get(wordToLetter);
            map.put(wordToLetter,   quantity);
        } else {
            map.put(wordToLetter, 1);
        }
    }
    return map;
}
  

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

1. Имейте временный счетчик для пространства, вместо того, чтобы добавлять его на карту, увеличьте счетчик и после цикла добавьте его на карту

2. Другое альтернативное решение — удалить пробел, если он существует, и вставить его обратно, связав его с концом LinkedHashMap . Например if (map.containsKey(' ')) map.put(' ', map.remove(' ')); , решение Олега должно быть быстрее.

3. A TreeMap было бы более подходящим для этой ситуации. Можете ли вы использовать a TreeMap вместо этого или можете позволить себе преобразовать a TreeMap в LinkedHashMap ?

4. @YCF_L Вы всегда можете предоставить свой пользовательский компаратор, который сортирует пробелы в последнюю очередь…

5. Если ввод "de abc" , в каком порядке вы хотите получить результат? "D", "E", "A", "B", "C", " " ? Или "A", "B", "C", "D", "E", " " ? Если первое, см. Комментарии Олега и concision . Если второе, посмотрите два комментария Sweeper .

Ответ №1:

Это лучшее решение, основанное на комментариях:

 // Oleg's solution
public LinkedHashMap<Character, Integer> output() {
    LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
    int spaceCount = 0;
    for (int i = 0; i < inputString.length(); i  ) {
        char wordToLetter = inputString.toLowerCase().charAt(i);
        if (wordLetter == ' ') {
            spaceCount  ;
        } else if (map.containsKey(wordToLetter)) {
            int quantity = map.get(wordToLetter);
            map.put(wordToLetter, quantity   1);
        } else {
            map.put(wordToLetter, 1);
        }
    }
    if (spaceCount > 0) {
        map.put(' ', spaceCount);
    }
    return map;
}
  

Хитрость заключается в том, чтобы не добавлять запись для пробелов (если таковые имеются) на карту до самого конца. Это означает, что это будет последняя запись.

На самом деле мы можем оптимизировать это следующим образом:

         ...
        } else if (map.containsKey(wordToLetter)) {
            int quantity = map.get(wordToLetter);
            map.put(wordToLetter, quantity   1);
        } else {
            map.put(wordToLetter, 1);
        }
        ...
  

становится

         ...
        } else {
            int quantity = map.getOrDefault(wordToLetter, 0);
            map.put(wordToLetter, quantity   1);
        } 
        ...
  

Это более лаконично и сокращает количество поисковых запросов. Действительно, мы можем сделать еще лучше:

         ...
        } else {
            map.compute(wordToLetter, i -> (i == null) ? 1 : i   1);
        } 
        ...