我有一些从不同公司收集的数据点,由 companyId 标识,每个数据点的名称属性在一家公司或不同公司之间可能重复。问题是按属于的名称属性对所有数据点进行分组到不同的公司,这意味着如果其公司已经存在于组中,我们将忽略该数据点。
例如数据点是:
companyId 数据点名称
1--------------------A
1--------------------A
1--------------------B
2--------------------A
3--------------------B
结果是:
数据点名称 组
A=================(1,A)(2,A)
B=================(1,B)(2,B)
我们可以看到来自公司 1 的第二个数据点 A 被忽略了。
据我所知,有两种方法可以进行重复数据删除工作。
1.建立一个Map<String(data point name), Set<Long(companyId)>>
Map<String, Set<Long>> dedup = new HashMap<>();
for(DataPoint dp : datapoints){
String key = dp.getName();
if(!dedup.contains(key)){
dedup.put(key, new HashSet<Long>());
}
if(dedup.get(key).contains(dp.getCompanyId()){
continue;
}
dedup.get(key).add(dp.getCompanyId());
}
2.建大Set<String>
Set<String> dedup;
for(DataPoint dp : datapoints){
String key = dp.getName() + dp.getCompanyId();
if(dedup.contains(key)){
continue;
}
dedup.add(key);
}
那么哪个更好或者更合适呢?
最佳答案
方法 (1) 更好,因为方法 2 会破坏类型信息。
如果您想要一个经过良好测试的稳健实现并具有许多附加功能,那么已经有现成的集合可用于此类情况。
Guava :https://google.github.io/guava/releases/21.0/api/docs/com/google/common/collect/HashMultimap.html
Eclipse 集合: https://www.eclipse.org/collections/
如果你只是想要一个简单的实现,你可以按照你的方法(1)自己做。
结果是这样的:
{
"A": [1, 2],
"B": [1, 2]
}
我不喜欢方法 2 的几个原因:
- 该方法不可靠。如果公司名称以数字结尾,则可能存在错误的重复数据删除。因此,您可能需要像这样添加一个特殊字符:
<id>~<name>
- 如果以后需要再考虑一个参数,那就更乱了。你可能需要做
<id>~<name>~<pincode>
等等, - 在方法 1 中,如果您实现单独基于 companyId 字段的散列码和 equals,那么您可以直接放置公司 bean 更加方便
关于java - 使用大集合或带有集合的等效 map 好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54038710/