没有重复的集合(基于 id)但保留最高版本号
Collection without duplicates (based on id) but keeps the highest version number
这似乎应该有一个标准的解决方案,但我找不到我要找的东西。手动实现并不难,但也许我的工具箱中缺少一个工具?
在伪代码中,我想要一个类似集合的集合,给定现有条目
{id_1, v_1}, {id_2, v_2}
用
调用addAll()
{id_1, v_2}, {id_2, v_1}
将剩下
{id_1, v_2}, {id_2, v_2}
即原来的 id_1 被更新的版本取代;原来的 id_2 仍然存在,因为它比传入的更新。
我浏览了 Guava,但没有发现任何问题。我对 Apache 集合不是很熟悉,也许可以从中构建一些东西?
谢谢大家
将对列表按版本号升序排序,然后 put
按此顺序排列成 java.util.HashSet
.
您可以包装地图并提供其他方法来检查项目版本。
这里是put
方法,例如
class MyMap<ID, E> extends HashMap<ID, E extends Versioned & HasId<ID>> {
public void put(E elem) {
if (containsKey(elem.getId()) {
E exist = get(elem.getId());
if (elem.version.isGreater(exist.version)) super.put(elem.getId(), elem);
} else {
super.put(elem.getId(), elem);
}
}
我建议使用 Map 而不是 Set,因为 this 问题。
为了避免扩展 Map
,您可以非常简单地发展自己的:
class KeepBestMap<K, V> {
final Map<K, V> map;
final Comparator<V> compare;
public KeepBestMap(Map<K, V> map, Comparator<V> compare) {
this.map = map;
this.compare = compare;
}
public KeepBestMap(Comparator<V> compare) {
this(new HashMap<>(), compare);
}
public KeepBestMap() {
// A null compare will assume objects are comparable.
this(null);
}
public Map<K, V> getMap() {
return map;
}
public V put(K key, V value) {
// Put the new one in - note the old one.
V replaced = map.put(key, value);
if (replaced != null) {
// Decide which to keep.
// If compare not supplied assume items are Comparable.
if ((compare != null
? // Use it.
compare.compare(replaced, value)
: // Assume values are comparable - if they are not then an exception will be thrown (like TreeMap).
((Comparable<V>) replaced).compareTo(value)) > 0) {
// Put the old one back in.
map.put(key, replaced);
// Didn't actually replace it in the end.
replaced = null;
}
}
return replaced;
}
}
这似乎应该有一个标准的解决方案,但我找不到我要找的东西。手动实现并不难,但也许我的工具箱中缺少一个工具?
在伪代码中,我想要一个类似集合的集合,给定现有条目
{id_1, v_1}, {id_2, v_2}
用
调用addAll()
{id_1, v_2}, {id_2, v_1}
将剩下
{id_1, v_2}, {id_2, v_2}
即原来的 id_1 被更新的版本取代;原来的 id_2 仍然存在,因为它比传入的更新。
我浏览了 Guava,但没有发现任何问题。我对 Apache 集合不是很熟悉,也许可以从中构建一些东西?
谢谢大家
将对列表按版本号升序排序,然后 put
按此顺序排列成 java.util.HashSet
.
您可以包装地图并提供其他方法来检查项目版本。
这里是put
方法,例如
class MyMap<ID, E> extends HashMap<ID, E extends Versioned & HasId<ID>> {
public void put(E elem) {
if (containsKey(elem.getId()) {
E exist = get(elem.getId());
if (elem.version.isGreater(exist.version)) super.put(elem.getId(), elem);
} else {
super.put(elem.getId(), elem);
}
}
我建议使用 Map 而不是 Set,因为 this 问题。
为了避免扩展 Map
,您可以非常简单地发展自己的:
class KeepBestMap<K, V> {
final Map<K, V> map;
final Comparator<V> compare;
public KeepBestMap(Map<K, V> map, Comparator<V> compare) {
this.map = map;
this.compare = compare;
}
public KeepBestMap(Comparator<V> compare) {
this(new HashMap<>(), compare);
}
public KeepBestMap() {
// A null compare will assume objects are comparable.
this(null);
}
public Map<K, V> getMap() {
return map;
}
public V put(K key, V value) {
// Put the new one in - note the old one.
V replaced = map.put(key, value);
if (replaced != null) {
// Decide which to keep.
// If compare not supplied assume items are Comparable.
if ((compare != null
? // Use it.
compare.compare(replaced, value)
: // Assume values are comparable - if they are not then an exception will be thrown (like TreeMap).
((Comparable<V>) replaced).compareTo(value)) > 0) {
// Put the old one back in.
map.put(key, replaced);
// Didn't actually replace it in the end.
replaced = null;
}
}
return replaced;
}
}