Java stream - Невозможно изменить содержимое списка с помощью forEach - PullRequest
0 голосов
/ 10 апреля 2020

Я должен реализовать метод map() ниже, который получает список массивов и объект Function<T, R> и возвращает список массивов, состоящий из результатов применения функции к заданным элементам.

следующий код печатает 1,2,3 вместо квадратов этих чисел. Почему код не работает? Мне нужна причина неудачи, а не правильные решения.

import java.util.ArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Mapper {
    public static ArrayList<Integer> map(ArrayList<Integer> nums, Function<Integer, Integer> mapper) {
        ArrayList<Integer> result = new ArrayList<>(nums);
        result.forEach(e -> e = mapper.apply(e));
        return result;
    }

    public static void main(String [] args){
        ArrayList<Integer> nums = IntStream.rangeClosed(1, 3).boxed().collect(Collectors.toCollection(ArrayList::new));
        ArrayList<Integer> squares = Mapper.map(nums, z -> z * z);
        squares.forEach(System.out::println);
    }
}

Ответы [ 3 ]

3 голосов
/ 10 апреля 2020

Это потому, что в result.forEach(e -> ... ) e это не ссылка на элемент списка, а значение целого числа из списка. Думайте об этой строке как об эквивалентной:

for (int e : nums) {
  e = e * e;
}

Это также не обновит элементы в коллекции num.

0 голосов
/ 10 апреля 2020

Это потому, что в result.forEach(e -> ... ), где «e» не является ссылкой на элемент, вместо этого это ссылка на значение.

import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.function.*;
import java.util.stream.*;

public class Mapper {
    public static List<Integer> map(List<Integer> numbers, Function<Integer, Integer> mapper) {
        return numbers.stream()
            .map(mapper)
            .collect(Collectors.toList());
    }

    public static void main(String [] args){
        List<Integer> numbers = new ArrayList<>(Arrays. asList(1, 2));
        map(numbers, number -> number * number).forEach(System.out::println);
    }
}
0 голосов
/ 10 апреля 2020

В вашем случае map будет более уместным:

public static ArrayList<Integer> map(ArrayList<Integer> nums, Function<Integer, Integer> mapper) {
    return nums.stream()
        .map(mapper)
        .collect(Collectors.toList());
}
...