Охватывающая область должна быть окончательной с потоками Java

#java

#java

Вопрос:

При попытке подсчитать количество символов в строке с использованием потоков я получаю сообщение об ошибке «Локальная переменная, определенная в объемлющей области, должна быть окончательной или фактически окончательной» Что вы используете в качестве обходного пути в этом случае? Должен ли я просто делать это отдельно, не зацикливая его? Я студент, и задача — расшифровать шифр Цезаря, поэтому анализ частоты является частью этого.

Спасибо.

 public static int[] freqAnalyse(String text) {
    int[] frequencies = new int[26];
    String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    text = text.toUpperCase();
    for(int i = 0; i < 26; i  ) {
        frequencies[i] = (int) text.chars().filter(k -> k == alphabet.charAt(i)).count();
    }
    return frequencies;
}
  

Редактировать
Это работает, это плохая практика или просто то, что нужно?
Спасибо.

 public static int[] freqAnalyse(String text) {
        int[] frequencies = new int[26];
        String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        text = text.toUpperCase();
        for(int i = 0; i < 26; i  ) {
            final int j = i;
            frequencies[j] = (int) text.chars().filter(k -> k == alphabet.charAt(j)).count();
        }
        return frequencies;
    }
  

Ответ №1:

Самый простой обходной путь — скопировать i в новую переменную.

  final int ii = i;
 frequencies[i] = (int) text.chars().filter(k -> k == alphabet.charAt(ii)).count();
  

В качестве альтернативы вы можете просто сохранить переменную для этого символа:

 final char ch = alphabet.charAt(i);
frequencies[i] = (int) text.chars().filter(k -> k == ch).count();
  

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

1. Проработал секунду, прежде чем увидеть это, отредактировал его как таковой. Спасибо 🙂

Ответ №2:

В этих случаях вы также можете полностью игнорировать переменную count i , используя iterator . Вот другой способ сделать это:

         int[] frequencies = new int[26];
        String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        text = text.toUpperCase();
        for (char c : alphabet.toCharArray()) {
            frequencies[c-'A'] = (int)text.chars().filter(value -> value == c).count();
        }
  

Использование только строки stream one:

     String upperCase = text.toUpperCase();
    alphabet.chars().forEach(ch -> frequencies[ch-'A'] = (int)upperCase.chars().filter(value -> value == ch).count());  
  

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

1. Idk, почему я не подумал о вашей части 1, хотя мне нравится один лайнер. Нужно лучше использовать такие потоки. Спасибо 🙂

Ответ №3:

Может быть, вы можете попробовать сделать что-то вроде этого :

 public static int[] freqAnalyse(String text) {
    int[] frequencies = new int[26];
    String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    text = text.toUpperCase();
    for(int i = 0; i < 26; i  ) {
        final char c = alphabet.charAt(i);
        frequencies[i] = (int) text.chars().filter(k -> k == c).count();
    }
    return frequencies;
}