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返回)。