Java 8 双消费者无法修改参数
我为Java8流实现了一个收集器,当达到给定阈值时,该收集器将实体存储到存储库中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
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调用的方法所做的事情。