我为java 8流实现了一个收集器,当达到给定的阈值时,它将实体存储到存储库。
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被添加到列表中,但在达到阈值后不会重置。整数也保持在0,这是自最终成员以来的预期。 因为看起来我唯一的选择是使我的Tuple2可变并清空列表:-( 有关如何使用不可变元组解决这个问题的任何建议吗?
答案 0 :(得分:1)
lambda表达式可以被认为是一个没有名称的函数(或方法)。在这个例子中,它就像一个方法,它有两个形式参数tuple
和e
,还有一些局部变量,包括list
。
当您对形式参数或局部变量进行赋值时,该赋值对于当前方法(或lambda体)是本地的。累加器返回后,外部不会看到任何突变或副作用,因此这些分配不会影响您收集的数据结构。
我不完全确定你要做什么,但是你可能会尝试编写一个包含整数计数器的普通可变类,而不是使用元组(可能是不可变的,必须替换而不是变异)。 (或其他)和清单。累加器将添加到列表中,有条件地刷新并替换列表,并递增计数器。这些变异操作在收集器中是允许的,因为收集器框架仔细地线程限制了这些操作,因此您正在变异的对象不需要是线程安全的。
答案 1 :(得分:-3)
它不工作的原因仅仅是我为参考“元组”分配了一个新值。这是一个call-by-reference方法参数,因此是对我可以修改的外部对象的引用。但我无法修改外部引用本身。
因此,当我为tuple分配一个新实例时,我得到一个新对象,该对象与最初作为函数参数移交的对象无关。
这是 - 可耻的 - 我应该知道的事情。