Код выкидывает исключение UnsupportedOperationException
Программа получает на ввод 10 слов и считает количество букв в них. На строке map.put(ch, map.get(ch) + 1); компилятор выбрасывает исключение UnsupportedOperationException
Подскажите, пожалуйста, что я сделал неправильно?
import java.util.*;
public class Solution {
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(System.in);
// Алфавит
List<Character> alphabet = new ArrayList<>(Arrays.asList(
'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж',
'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о',
'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц',
'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я'));
// Ввод строк
List<String> list = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
String line = scan.nextLine();
list.add(line.toLowerCase());
}
Map<Character, Integer> map = Map.ofEntries(
Map.entry('а', 0),
Map.entry('б', 0),
Map.entry('в', 0),
Map.entry('г', 0),
Map.entry('д', 0),
Map.entry('е', 0),
Map.entry('ё', 0),
Map.entry('ж', 0),
Map.entry('з', 0),
Map.entry('и', 0),
Map.entry('к', 0),
Map.entry('л', 0),
Map.entry('м', 0),
Map.entry('н', 0),
Map.entry('о', 0),
Map.entry('п', 0),
Map.entry('р', 0),
Map.entry('с', 0),
Map.entry('т', 0),
Map.entry('у', 0),
Map.entry('ф', 0),
Map.entry('х', 0),
Map.entry('ц', 0),
Map.entry('ч', 0),
Map.entry('ш', 0),
Map.entry('щ', 0),
Map.entry('ъ', 0),
Map.entry('ы', 0),
Map.entry('ь', 0),
Map.entry('э', 0),
Map.entry('ю', 0),
Map.entry('я', 0)
);
// for every words in list
for (int i = 0; i < list.size(); i++) {
// division word to letters
char[] chars = list.get(0).toCharArray();
// for every letters in word
for (char ch : chars) {
// for every letters in alphabet
for (int j = 0; j < alphabet.size(); j++) {
// if letter in word *equals* letter in alphabet
if (ch == alphabet.get(j)) {
map.put(ch, map.get(ch) + 1);
}
}
}
}
for (Map.Entry<Character, Integer> entry : map.entrySet()) {
char key = entry.getKey();
int value = entry.getValue();
System.out.println(key + " - " + value);
}
}
}
Ответы (2 шт):
Тут проблема с Map.entry об этом вы можете прочитать тут. Но если вкратце, то Map.entry возвращает неизменяемый Map.Entry, и попытки изменить его, приводят к ошибке UnsupportedOperationException.
Можно же проще инициализировать Map. Например вот так:
Map<Character, Integer> map = new HashMap<>();
//s = 'а', где а - русская, тут легко ошибиться и поставить латинскую)
for(char s = 'а'; s <= 'я'; s++)
map.put(s, 0);
Так же я думаю на строчке:
char[] chars = list.get(0).toCharArray();
Вместо 0 должен стоять индекс i.
И небольшой совет можно сделать alphabet в виде строки и использовать функцию indexOf. А если у вас alphabet не будет расширяться и в нем должны быть только русские буквы, то можно просто делать проверку символа на >= 'а' && <= 'я', но тогда неудобно будет расширять алфавит.
Я вообще не понял, зачем здесь какие-то словари? Вы хотите посчитать количество русских букв в строках? Для этого не нужно сообщать компьютеру о том, что русские буквы существуют, он и так это знает. Тем более это не нужно делать дважды.
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Solution {
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(System.in);
List<String> list = new ArrayList<>();
for (int i = 0; i < 10; i++) list.add(scan.nextLine());
Map<Character, Long> result = list.stream()
.map(String::toLowerCase)
.flatMapToInt(String::chars)
.filter(ch->ch>='а'&&ch<='я')
.mapToObj(ch->(char)ch)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(result);
}
}
А если закоментировать строку ".filter(ch->ch>='а'&&ch<='я')", то посчитаете вообще все символы, которые будут в данной строке (приведенные к нижнему регистру, за что отвечает строка ".map(String::toLowerCase)" )