我有一个对象列表。每个对象都有一个布尔重复变量。在我的算法结束时,我希望所有具有多个对象(由对象上的字符串标识符标识的重复项)具有boolean duplicate = true。我这样做了,但我想知道是否有办法更有效地做到这一点,理想情况下只有一个循环。
List<String> dupIds = new ArrayList<String>();
Map<String, MyObject> objMap = new HashMap<String, MyObject>();
for (MyObject o : objectList) {
if (objMap.containsKey(o.getId()) {
dupIds.add(o.getId());
} else {
objMap.put(o.getId(), o);
}
}
for (MyObject o : objectList) {
if (dupIds.contains(o.getId) {
o.setDuplicate(true);
}
}
希望这不是一个重复的问题,但我发现的大多数都不是这样做的,通常只是删除重复(我需要保留它们)或只标记副本(我需要标记副本加上原件)。
答案 0 :(得分:1)
这不是最有效的方法,但它摆脱了第二个循环:
Map<String, MyObject> objMap = new HashMap<String, MyObject>();
for (MyObject o : objectList) {
if (objMap.containsKey(o.getId()) {
objMap.get(o.getId()).setDuplicate(true);
o.setDuplicate(true);
} else {
objMap.put(o.getId(), o);
}
}
如果在地图中找到重复项,则会将当前对象和地图中的对象标记为重复。如果一个对象出现两次以上,您可能会多次在同一个对象上调用setDuplicate
,因此您可能需要在设置之前检查该标志是否已设置。
更新:
这是一个不会在同一个对象上多次调用setDuplicate
的解决方案:
Map<String, MyObject> objMap = new HashMap<String, MyObject>();
for (MyObject o : objectList) {
if (objMap.containsKey(o.getId()) {
MyObject other = objMap.get(o.getId());
if (other != null) {
othet.setDuplicate(true);
objMap.put(o.getId(), null);
}
o.setDuplicate(true);
} else {
objMap.put(o.getId(), o);
}
}
setDuplicate
到当前对象和地图中的对象,然后在地图中输入一个空值作为对象ID的值。 / LI>
setDuplicate
到当前对象。答案 1 :(得分:1)
我可能首先使用两个哈希集找到所有重复的键,然后在每个对象上设置布尔值。
它与你的解决方案(和Eran&#39; s)具有相同的渐近时间复杂度,这是O(n)
,但我发现这更容易理解(但这仅仅是品味问题,当然)。
Set<String> keys = new HashSet<>();
Set<String> duplicateKeys = new HashSet<>();
for (MyObject o : objectList) {
if (keys.contains(o.getId())
duplicateKeys.add(o.getId());
keys.add(o.getId());
}
for (MyObject o : objectList) {
o.setDuplicate(duplicateKeys.contains(o.getId()));
}