Java 将未修改列表中的元素包含在带有流的二维列表中的修改列表中

Java 将未修改列表中的元素包含在带有流的二维列表中的修改列表中,java,list,java-8,java-stream,Java,List,Java 8,Java Stream,我问了一个关于在1D列表中做同样的事情的问题,我认为将答案应用到2D列表是很容易的,但事实并非如此 根据答案的代码,我提出了以下解决方案: //list is of type ArrayList<List<Integer>> list.stream() .map(l -> Stream.concat( l.subList(0, l.size() - 1).stream().map(i -> i - 2),

我问了一个关于在1D列表中做同样的事情的问题,我认为将答案应用到2D列表是很容易的,但事实并非如此

根据答案的代码,我提出了以下解决方案:

//list is of type ArrayList<List<Integer>>
list.stream()
        .map(l -> Stream.concat(
                l.subList(0, l.size() - 1).stream().map(i -> i - 2),
                Stream.of(l.get(l.size() - 1)).collect(Collectors.toList())
        ))
        .collect(Collectors.toList());
//列表的类型为ArrayList
list.stream()
.map(l->Stream.concat(
l、 子列表(0,l.size()-1).stream().map(i->i-2),
Stream.of(l.get(l.size()-1)).collect(Collectors.toList())
))
.collect(Collectors.toList());

我得到编译时错误
无法为map推断类型参数(函数括号有问题。更改此错误:

list.stream()
    .map(l -> Stream.concat(
            l.subList(0, l.size() - 1).stream().map(i -> i - 2),
            Stream.of(l.get(l.size() - 1)).collect(Collectors.toList())
    ))
    .collect(Collectors.toList());
为此:

list.stream()
    .map(l -> Stream.concat(
            l.subList(0, l.size() - 1).stream().map(i -> i - 2),
            Stream.of(l.get(l.size() - 1))).collect(Collectors.toList())
    )
    .collect(Collectors.toList());
缩进在这里很重要,可以提高代码的可读性。我将按如下方式重新缩进第二个代码段:

list.stream()
    .map(l -> Stream.concat(
            l.subList(0, l.size() - 1).stream().map(i -> i - 2),
            Stream.of(l.get(l.size() - 1)))
        .collect(Collectors.toList()))
    .collect(Collectors.toList());
或者更好,我会将修改内部列表的逻辑移到一个helper方法:

public final class Utility {
    private Utility() { }

    public static List<Integer> modifyAllButLast(List<Integer> list) {
        return Stream.concat(
                l.subList(0, l.size() - 1).stream().map(i -> i - 2),
                Stream.of(l.get(l.size() - 1)))
            .collect(Collectors.toList());
    }
}

注意:无需将helper方法移动到一个新的
实用程序
类,您甚至可以让它成为一个非静态方法。在这种情况下,只需相应地更改
实用程序::modifyAllButLast
方法引用。

这可能不是连接两个列表的最优雅的方式,但它可以做到这一点

list.stream()
    .map(integerList -> {
        List<Integer> toReturn = integerList
                .subList(0, integerList.size() - 1)
                .stream()
                .map(i -> i - 2)
                .collect(Collectors.toList());
        toReturn.add(integerList.get(integerList.size() - 1));
        return toReturn;
    })
    .collect(Collectors.toList());
list.stream()
.map(整数列表->{
列表返回=整数列表
.subList(0,integerList.size()-1)
.stream()
.map(i->i-2)
.collect(Collectors.toList());
添加(integerList.get(integerList.size()-1));
回归回归;
})
.collect(Collectors.toList());
让我们一步一步地修复错误 将两个流合并在一起,但将其中一个合并为
列表
而不是

结果不符合预期。我们预期它会返回一个
列表
,但它会返回一个
列表
。我们可以将相关流收集到
列表
,如下所示:

list.stream().map(l -> Stream.concat(
    l.subList(0, l.size() - 1).stream().map(i -> i - 2),
    Stream.of(l.get(l.size() - 1))
)).collect(Collectors.toList());
list.stream().map(main -> 
    Stream.concat(
        main.subList(0, main.size() - 1).stream().map(i -> i - 2),
        Stream.of(main.get(main.size() - 1))           
    ).collect(Collectors.toList())
//   ^--- collecting Stream<Integer> to List<Integer>
).collect(Collectors.toList());
list.stream().map(l -> Stream.concat(
    l.subList(0, l.size() - 1).stream().map(i -> i - 2),
    Stream.of(l.get(l.size() - 1))
)).collect(Collectors.toList());
list.stream().map(main -> 
    Stream.concat(
        main.subList(0, main.size() - 1).stream().map(i -> i - 2),
        Stream.of(main.get(main.size() - 1))           
    ).collect(Collectors.toList())
//   ^--- collecting Stream<Integer> to List<Integer>
).collect(Collectors.toList());
list.stream().map(main ->
    main.stream().collect(collectingAndThen(toList(), it -> {
        // v--- replacing all items in list except the last one 
        it.subList(0, it.size() - 1).replaceAll(item -> item - 2);
        return it;
    }))
).collect(Collectors.toList());