Java 在一个循环中,只有一个具有自定义构造函数逻辑的对象被完全初始化

Java 在一个循环中,只有一个具有自定义构造函数逻辑的对象被完全初始化,java,Java,我试图用以下代码将一个对象映射到另一个对象(Record->ParsedAddress): 公共类ParsedAddress扩展地址{ 私有静态最终映射映射=新EnumMap(Field.class); 公共服务(最终记录、最终列表顺序){ 超级(); 此.mapFields(记录、顺序); } 私有void映射字段(最终记录、最终列表顺序){ 这是setupMapping(); for(最终映射.Entry映射:MAPPINGS.entrySet()){ final Field=mapping

我试图用以下代码将一个对象映射到另一个对象(
Record
->
ParsedAddress
):

公共类ParsedAddress扩展地址{
私有静态最终映射映射=新EnumMap(Field.class);
公共服务(最终记录、最终列表顺序){
超级();
此.mapFields(记录、顺序);
}
私有void映射字段(最终记录、最终列表顺序){
这是setupMapping();
for(最终映射.Entry映射:MAPPINGS.entrySet()){
final Field=mapping.getKey();
最终字符串值=record.getField(字段,顺序);
最终使用者setter=mapping.getValue();
接受(值);
}
}
私有void setupMapping(){
如果(!MAPPINGS.isEmpty())返回;
put(称呼,this::setValutation);
put(FIRST_NAME,this::setFirstName);
put(姓氏,this::setSurname);
//等等。。。
}
}
Address
是包含所有映射字段的数据对象。)

我这样调用构造函数:

records.stream()
.map(记录->新建解析数据地址(记录,订单))
.collect(toUnmodifiableList());
但只有第一条“记录”被映射。结果集合包含一个包含所有数据的
ParsedAddress
(因此逻辑正常工作)和一个包含
null
字段的
ParsedAddress
E


我调试了它,并设法将问题缩小到
setter.accept(value)
行。无论构造函数是在流中调用还是在循环中调用,其工作原理都完全相同

是关于对象初始化的吗?但是,为什么只有一个对象映射成功,而其他对象映射不成功

编辑:
记录
类仅包含要映射的数据。下面是
getField
方法:

公共字符串getField(最终字段,最终列表顺序){
最终int索引=order.indexOf(字段);
返回索引==-1?空:this.data.get(索引);
}

这里的问题是
映射是一个延迟加载的静态映射,而
this
关键字不是

这会产生一个映射,该映射只填充一次,但引用了到达它的第一个对象(懒洋洋加载映射的对象)的公共setter

因此,
MAPPINGS
中的每个使用者都是同一对象的公共setter(懒散加载映射的对象)


真有趣

什么是
Record
class?
record.getField()做什么?也许它会将该字段作为“奖金”从列表中删除?@Amongalen,不,它不会修改数据。我用一个片段更新了这个问题
ORDER
对于整批对象都是完全相同的静态实例,因此这不是在条件下返回
null
的问题。
记录的类型是什么?@Taschi,您的意思是
记录中要映射的数据
?它们都是简单的字符串,保存在
java.util.List
中。“无论是在流还是在循环中调用构造函数,其工作原理都完全相同。”-这是什么意思?应该是那样的,不是吗?代码中没有任何看起来不正确的内容。它需要调试-在
setter.accept(value)上设置断点并检查所有变量。基于您提供的代码,我们无法为您提供更多帮助。您能分享一下您是如何解决这一问题的吗?通过使其非静态或其他方式?@Amongalen,我将
MAPPINGS
转换为实例变量。因为它无论如何都需要保存对当前对象的引用,所以我认为它对内存的影响很小,因为
EnumMap
s无论如何都是基于数组的。我可以想象,另一种选择是将方法引用转换为lambda,该lambda将获得
this
作为参数,但我看不出这有什么好处,因为必须有(
MAPPINGS.size()
*无论如何创建的
消费者
的(
记录
个)实例(从所述lambda返回)。