Есть несколько проблем
stringList
- это List<char[]>
(список массива символов), но вы на самом деле хотите List<Character>
(список отдельных символов) - Выражение
trmap.containsKey(i) ? trmap.put(i, trmap.get(i)+1) : trmap.put(i,1)
возвращает целочисленное значение, но .forEach
не ожидает тип возвращаемого значения
Чтобы преобразовать String
в список символов, необходимо выполнить List<Character> stringList = s.chars().mapToObj(c -> (char) c).collect(Collectors.toList());
Затем вы можете использовать более длинную форму if/else
для вычисления количества:
stringList.forEach(i -> {
if (trmap.containsKey(i)) {
trmap.put(i, trmap.get(i) + 1);
} else {
trmap.put(i, 1);
}
});
Если вы хотите использовать больше потоков, вы можете использовать Collections.toMap(..)
коллектор
Map<Character,Integer> counts = s.chars().mapToObj(c -> (char) c)
.collect(Collectors.toMap(
Function.identity(),
c -> 1,
(v1,v2) -> v1+v2
);
Что делают параметры toMap
:
Function.identity()
говорит использовать текущий символ в потоке в качестве значения ключа c -> 1
говорит, чтобы сопоставить символ целочисленному значению 1
и сохранить его как значение на карте (v1,v2) -> v1+v2
Является функцией разрешения конфликтов. Поэтому, если мы обрабатываем поток и встречаемся с символьным ключом, который уже находится на карте, запустите эту функцию, чтобы вычислить обновленное значение для сохранения на карте. v1
представляет текущий счетчик на карте, v2
представляет 1
, которому вы сопоставили символ во втором аргументе, поэтому v1+v2
вернет сумму этих двух чисел и сохранит ее на карте под персонаж. Это может быть далее сокращено как Integer::sum