Сумма элементов при дубликате ключа с помощью Stream
Помогите пожалуйста. Мне из стрима необходимо получить Map, в котором в качестве ключа будет находиться остаток от деления, а в качестве value будет сумма чисел для которых этот остаток получился. Делитель дан заранее. вот мой код:
int a = 2; делитель
List<Integer> list = Arrays.asList(1, 2, 3 ,4, 5);
Map<Integer, Integer> map = new HashMap<>();
map = list.stream()
.collect(Collectors.groupingBy(x -> list.get(x) % a,Collectors.summingInt(list::get)));
System.out.println(map);
но у меня появляется ошибка java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5.
Объясните почему она появляется и что мне надо подкорректировать. ТАкже подскажите каким образом я бы мог использовать метод getOrDefault
Ответы (1 шт):
В Collectors.groupingBy передается функция. Её описание говорит, что она преобразует входящие элементы в ключи. Поскольку это не индексы, а сами элементы, попытка получить элемент по индексу 5 заканчивается неудачей. Был бы у вас Arrays.asList(20);, то получили бы ошибку Index 20 out of bounds for length 5. Думаю логика понятная.
Вторая функция Collectors.summingInt принимает по описанию функцию преобразования элемента в int. Поскольку у вас опять же это не индекс, то вам просто надо преобразовать элемент Integer к int.
Советую вам выполнить и понять следующий код:
public static void main(String[] args){
int a = 2;
List<Integer> list = Arrays.asList(1, 10, 3, 12, 5);
Map<Integer, Integer> map = new HashMap<>();
map = list.stream()
.collect(Collectors.groupingBy(x -> {
System.out.println("получен элемент для преобразования в ключ: " + x +"; ключ " + x % a + ";");
return x % a;
}, Collectors.summingInt(x -> {
System.out.println("получен элемент для последующего сложения: " + x);
return x.intValue();
})));
System.out.println(map);
}
Итог:
map = list.stream()
.collect(Collectors.groupingBy(x -> x % a, Collectors.summingInt(Integer::intValue)));