我从CompanyId标识的不同公司收集了一些数据点,每个数据点的name属性可能在一个公司或不同公司之间重复,问题是将所有数据点按其所属的name属性分组转移给不同的公司,这意味着如果其公司已存在于组中,我们将忽略数据点。
例如,数据点是:
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);
}
那哪个更好或更合适?
答案 0 :(得分:6)
方法(1)更好,因为方法2破坏了类型信息。
如果您想要一个经过测试的可靠实现并具有许多其他功能,则已经有适合这些情况的现成集合。
番石榴: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 :(得分:4)
最简单的方法(1)是:
Map<String, Set<Long>> dedup =
datapoints.stream().collect(
groupingBy(
DataPoint::getName,
mapping(DataPoint::getCompanyId, toSet()));
最简单的方法(2)是:
Set<String> dedup =
datapoints.stream()
.map(d -> d.getName() + d.getCompanyId())
.collect(toSet());
您选择的内容取决于您要执行的操作,因为它们会产生不同类型的数据,并可能产生不同的结果。