我有 2 个哈希图
HashMap<DedupeTableEntity,List<DedupeTableEntity>> deltaHashmap
HashMap<DedupeTableEntity,List<DedupeTableEntity>> existingHashmap
DedupeTableEntity 有 id、国家/地区、entity_flag 作为属性
我想迭代 delta 哈希映射的值(两个哈希映射 只有 1 个键和该键下的值列表)
如果有 2 个属性,则检查该对象是否在现有哈希映射中 匹配(国家/地区和 ID)
如果存在
从中获取该对象(实体标志)的属性值 并替换现有的hashmap的属性(实体标志)值 Delta 哈希图中的相同对象
public void compareTwoHashmaps(HashMap<DedupeTableEntity,List<DedupeTableEntity>> deltaHashmap
, HashMap<DedupeTableEntity,List<DedupeTableEntity>> existingHashmap){
//iterate through deltahashmap values
return deltaHashmap.values().stream()
.flatMap(Collection::stream)
.filter(c -> (existingHashmap.values().stream().flatMap(Collection::stream).filter(e->e.getId().equals(c.getId()) && e.getObjectCountry().equals(c.getObjectCountry())))
.map(k-> k.setEntityFlag(existingHashmap.values().stream().flatMap(Collection::stream).filter(e->e.getId().equals(k.getId()) && e.getObjectCountry().equals(k.getObjectCountry())).map(r ->r.getEntityFlag()).toString()));
}
这就是我到目前为止所得到的。但有一个错误我不知道如何纠正
如有任何帮助,我们将不胜感激
existingHashmap
对 deltaHashmap
中的每个元素执行线性扫描是极其浪费的。map
不适用于对流中的每个元素执行操作。 map
用于更改 Stream 中返回的元素。要执行操作,您应该使用 forEach。我首先会通过用于匹配的属性来映射
existingHashMap
的值。实现复合键的一种简单方法是定义一个 record 类。这种通过可匹配属性进行的映射允许更快地搜索匹配项,而无需针对 deltaHashmap 中的每个值检查现有Hashmap 的每个值。 (记录类根据其成员自动定义 equals、hashCode 和 toString 方法。)
此处不应使用 map
,因为它返回一个值,但没有可返回的值。您正在实体中设置属性。这样做不会返回任何内容。
public void compareTwoHashmaps(
HashMap<DedupeTableEntity,List<DedupeTableEntity>> deltaHashmap,
HashMap<DedupeTableEntity,List<DedupeTableEntity>> existingHashmap) {
record Identifiers(String id, String country) {
static Identifiers of(DedupeTableEntity entity) {
return new Identifiers(entity.getId(),
entity.getObjectCountry());
}
}
Map<Identifiers, DedupeTableEntity> allExisting =
existingHashmap.values().stream().flatMap(Collection::stream)
.collect(Collectors.toMap(Identifiers::of, e -> e));
deltaHashmap.values().stream().flatMap(Collection::stream)
.forEach(delta -> {
DedupeTableEntity existing =
allExisting.get(Identifiers.of(delta));
if (existing != null) {
delta.setEntityFlag(existing.getEntityFlag());
}
});
}
流中似乎有一些不正确的括号。还有一些可能的重复代码,我试图减少它们。我还做了一些提取,最终得到了这个:
public void updateFlag(
Map<DedupeTableEntity, List<DedupeTableEntity>> deltaHashmap,
Map<DedupeTableEntity, List<DedupeTableEntity>> existingHashmap
) {
deltaHashmap.values().stream()
.flatMap(Collection::stream)
.forEach(k -> extractFlag(existingHashmap, k)
.ifPresent(k::setEntityFlag));
}
private Optional<String> extractFlag(Map<DedupeTableEntity, List<DedupeTableEntity>> existingHashmap, DedupeTableEntity k) {
return existingHashmap.values().stream()
.flatMap(Collection::stream)
.filter(e -> equalsByIdAndCountry(k, e))
.findFirst().map(DedupeTableEntity::getEntityFlag);
}
private boolean equalsByIdAndCountry(DedupeTableEntity c, DedupeTableEntity e) {
return e.getId().equals(c.getId()) && e.getObjectCountry().equals(c.getObjectCountry());
}
我没有任何数据来测试它是否真的正确,所以我把它留给你。
您的代码包含一些错误:
包含返回语句的固定版本:
public HashMap<DedupeTableEntity,List<DedupeTableEntity>> compareTwoHashmaps(
HashMap<DedupeTableEntity,List<DedupeTableEntity>> deltaHashmap,
HashMap<DedupeTableEntity,List<DedupeTableEntity>> existingHashmap) {
deltaHashmap.values().stream()
.flatMap(Collection::stream)
.filter(c -> existingHashmap.values().stream()
.flatMap(Collection::stream)
.anyMatch(e -> e.getId().equals(c.getId()) && e.getObjectCountry().equals(c.getObjectCountry())))
.forEach(k -> {
Optional<String> entityFlag = existingHashmap.values().stream()
.flatMap(Collection::stream)
.filter(e -> e.getId().equals(k.getId()) && e.getObjectCountry().equals(k.getObjectCountry()))
.map(r -> r.getEntityFlag())
.findFirst();
entityFlag.ifPresent(k::setEntityFlag);
});
return deltaHashmap;
}