java - 只有一个具有自定义构造函数逻辑的对象在循环中被完全初始化
问题描述
我正在尝试使用以下代码将一个对象映射到另一个对象(Record
-> ):ParsedAddress
public class ParsedAddress extends Address {
private static final Map<Field, Consumer<String>> MAPPINGS = new EnumMap<>(Field.class);
public ParsedAddress(final Record record, final List<Field> order) {
super();
this.mapFields(record, order);
}
private void mapFields(final Record record, final List<Field> order) {
this.setupMapping();
for (final Map.Entry<Field, Consumer<String>> mapping : MAPPINGS.entrySet()) {
final Field field = mapping.getKey();
final String value = record.getField(field, order);
final Consumer<String> setter = mapping.getValue();
setter.accept(value);
}
}
private void setupMapping() {
if (!MAPPINGS.isEmpty()) return;
MAPPINGS.put(SALUTATION, this::setSalutation);
MAPPINGS.put(FIRST_NAME, this::setFirstName);
MAPPINGS.put(SURNAME, this::setSurname);
// etc...
}
}
(Address
是一个包含所有映射字段的数据对象。)
我这样调用构造函数:
records.stream()
.map(record -> new ParsedAddress(record, ORDER))
.collect(toUnmodifiableList());
但只有第一个“记录”被映射。结果集合包含一个ParsedAddress
具有所有数据的集合(因此逻辑工作正常)和ParsedAddress
具有null
字段的 es。
我对其进行了调试,并设法将问题缩小到了setter.accept(value)
一线。无论是在流还是循环中调用构造函数,它的工作原理都是一样的。
是关于对象初始化的吗?但是,为什么只有一个对象映射成功,而其他对象却没有呢?
编辑:Record
该类仅包含要映射的数据。这是getField
方法:
public String getField(final Field field, final List<Field> order) {
final int index = order.indexOf(field);
return index == -1 ? null : this.data.get(index);
}
解决方案
这里的问题是MAPPINGS
地图是延迟加载的静态地图,但this
关键字不是。
这导致映射只填充一次,但引用了到达它的第一个对象的公共设置器(延迟加载映射的对象)。
因此,每个消费者MAPPINGS
都是同一个对象(延迟加载地图的对象)的公共设置器。
那很有趣!
推荐阅读
- c# - 运行 asp.net mvc 项目时出现错误“无法启动 iisexpress Web 服务器”
- python - 有什么方法可以提高通过 Magento REST API 调用获取产品的性能?
- cordova - 从 Phonegap 应用程序访问时未保存会话状态
- c# - 具有子集合的实体在 WCF 中导致问题:如果您使用 DataContractSerializer,请考虑使用 DataContractResolver
- c++ - GetWindowText 为另一个进程返回空字符串
- java - OFDM以不同频率发送和接收多个音调
- scala - 在 Scala 程序中减少 Spark 的日志输出
- java - JDBC 连接池不返回连接,Web 应用程序挂起
- javascript - 如何使用 Shrimpy Universal Crypto Exchange API 连接到 Binance?
- polymer - 如果不包含任何自定义组件,如何在聚合物中使用 wct 测试服务文件