Java 8 双消费者无法修改参数

Java 8 双消费者无法修改参数,java-8,immutability,collectors,Java 8,Immutability,Collectors,我为Java8流实现了一个收集器,当达到给定阈值时,该收集器将实体存储到存储库中 public BiConsumer<Tuple2<Integer,List<T>>, T> accumulator() { return (tuple, e) -> { List<T> list = tuple._2; list.add(e); if (list.size() >= this.thre

我为Java8流实现了一个收集器,当达到给定阈值时,该收集器将实体存储到存储库中

public BiConsumer<Tuple2<Integer,List<T>>, T> accumulator() {
    return (tuple, e) -> {
        List<T> list = tuple._2;
        list.add(e);
        if (list.size() >= this.threshold) {
            this.repository.save(list);
            this.repository.flush();
            list = new LinkedList<>();
        }
        tuple = new Tuple2<>(tuple._1 + 1, list);
    };
}
公共双消费者累加器(){
返回(元组,e)->{
列表=元组。\u 2;
列表.添加(e);
if(list.size()>=此.threshold){
this.repository.save(列表);
this.repository.flush();
列表=新的LinkedList();
}
tuple=新的Tuple2(tuple.\u 1+1,列表);
};
}
这不符合预期。元素e被添加到列表中,但在达到阈值后不会重置。此外,Integer保持为0,这是预期的,因为它是最终成员。 似乎我唯一的选择是使我的Tuple2可变并清空列表:-(
有没有关于如何使用不可变元组解决此问题的建议?

可以将lambda表达式视为一个函数(或方法)在这个例子中,它就像一个方法,有两个形式参数
tuple
e
,还有一些局部变量在它的主体中,包括
list

当您对形式参数或局部变量赋值时,该赋值是当前方法(或lambda主体)的局部赋值。在累加器返回后,外部不会看到任何变异或副作用,因此这些赋值不会影响正在收集的数据结构


我不完全确定您想做什么,但是您可以尝试编写一个普通的、可变的类,其中包含一个整数计数器(或其他什么),而不是使用元组(可能是不可变的,必须替换而不是变异的)和一个列表。累加器将添加到列表中,有条件地刷新和替换列表,并增加计数器。这些变异操作在收集器中是允许的,因为收集器框架小心地线程限制这些操作,所以您正在变异的对象不必是线程安全的。

这就是我现在正在做的。但是让我感觉脏兮兮的:-(我希望有一个干净的方法来解决这个问题。在Java中,给参数赋值对调用者没有任何影响。这就是所谓的“传递值”并且从一开始就是Java的原则。为什么你希望它在lambda表达式中有所不同?这根本不是真的。对象是通过引用提供给方法的。这就是为什么我可以从函数中修改元组列表的内容。什么不起作用(现在我看到了我的错误)是将一个新对象分配给引用,同时希望更改外部引用。否。对象引用是按值传递的。请不要再次开始旧的讨论。当您将不同的引用分配给参数时,调用方不会受到影响。调用方将始终引用它以前引用的同一对象,regardless调用的方法所做的事情。