Код выкидывает исключение 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)" )

→ Ссылка