gpt4 book ai didi

java - 按值对并发映射条目进行排序

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:35:06 26 4
gpt4 key购买 nike

有没有什么方法可以创建 Map 的线程安全实现,以维护其条目按值排序?我知道我可以像这样创建一个线程安全的 Map

ConcurrentMap<String, Double> rankings = new ConcurrentHashMap<String, Double>();

然后我可以通过将条目传递给这样的实用方法来获取按值排序的条目:

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
@Override
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});

Map<K, V> result = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}

但我正在寻找的是一个线程安全的Map,它维护按值排序的条目,这样我就不必调用这样的方法如上所述,在每次插入/删除之后,为了保持条目按值排序。我想我正在寻找一种结合了 ConcurrentHashMapLinkedHashMap 行为的实现,但还没有找到。

ConcurrentSkipListMap几乎提供了我想要的,但它似乎只支持按键值排序。

最佳答案

考虑为此构建一个复合数据结构。在高层次上,执行以下操作。

首先,实现 Map.Entry 以保留键值对。该对的排序将首先按值,然后按键。

private static class InternalEntry<K extends Comparable<K>,
V extends Comparable<V>>
implements Comparable<InternalEntry<K, V>>,
Map.Entry<K, V> {
private final K _key;
private final V _val;

InternalEntry(K key, V val) {
_key = key;
_val = val;
}

public K getKey() {
return _key;
}

public V getValue() {
return _val;
}

public V setValue(V value) {
throw new UnsupportedOperationException();
}

public int compareTo(InternalEntry<K, V> o) {
int first = _val.compareTo(o._val);
if (first != 0) {
return first;
}
return _key.compareTo(o._key);
}
}

整个条目可以用作有序映射的

但是该映射不支持按键高效查找值。为此,引入另一个映射,将键映射到条目。

复合结构如下所示:

class OrderedByValue<K extends Comparable<K>, V extends Comparable<V>> {
private final Map<InternalEntry<K, V>, Boolean> _ordering =
new TreeMap<InternalEntry<K, V>, Boolean>();

private final Map<K, InternalEntry<K, V>> _lookup =
new HashMap<K, InternalEntry<K, V>>();

public V put(K key, V val) {
InternalEntry<K, V> entry = new InternalEntry<K, V>(key, val);
InternalEntry<K, V> old = _lookup.put(key, entry);
if (old == null) {
_ordering.put(entry, Boolean.TRUE);
return null;
}
_ordering.remove(old);
_ordering.put(entry, Boolean.TRUE);
return old.getValue();
}

@SuppressWarnings({"unchecked"})
public Iterable<Map.Entry<K, V>> entrySet() {
Iterable entries = Collections.unmodifiableSet(_ordering.keySet());
return (Iterable<Map.Entry<K, V>>) entries;
}
}

请注意,我没有提供实现完整 map 所需的所有代码——如果您需要其他方法的帮助,请告诉我。

如果需要支持 null 键/值,您还需要在 InternalEntry 的比较实现中执行一些特殊情况代码。

关于java - 按值对并发映射条目进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5942474/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com