我是java的新手。 我想按值对并发哈希映射进行排序。我在这里找到了一种方法 - sort concurrent map entries by value
有更简单的方法吗?有人可以用一个例子解释一下吗?
感谢。
答案 0 :(得分:4)
另一个解决方案是切换到使用Java 6中添加的ConcurrentSkipListMap
。引用Javadocs:
此类实现SkipLists的并发变体,为containsKey,get,put和remove操作及其变体提供预期的平均log(n)时间成本。插入,删除,更新和访问操作由多个线程安全地同时执行。迭代器是弱一致的,在迭代器创建时或之后的某个时刻返回反映地图状态的元素。它们不会抛出ConcurrentModificationException,并且可能与其他操作同时进行。升序键有序视图及其迭代器比降序视图快。
SkipLists是平衡树的概率替代品。它们与树具有相同的O
,但通常它们的实现明显更简单。如果您的大多数操作都是哈希表查找(根据定义O(1)
),那么您将看到适当的表大小的性能不同,但如果您需要经常排序,这可能是一个更好的解决方案。
我只希望Java提供这种优秀数据结构的非并发版本。
答案 1 :(得分:2)
根据你的用例,我会创建另一个代表你的数据结构的类,它由一个hashmap和一个列表组成,用于维护值的排序。
有关此内容的更多详情:
Sort a Map<Key, Value> by values (Java)
Sorting HashMap by values
http://www.coderanch.com/t/382750/java/java/Sorting-HashMap-values
您还可以扩展ConcurrentHashMap以覆盖entrySet和keySet方法,以按值的顺序返回条目/键。
public class OrderedValueHashMap<K,V extends Comparable<V>> extends ConcurrentHashMap<K, V> {
@Override
public Set<Map.Entry<K, V>> entrySet() {
Set<Map.Entry<K, V>> orderedValueEntrySet = new TreeSet<Map.Entry<K,V>>(new Comparator<Map.Entry<K,V>>() {
@Override
public int compare(java.util.Map.Entry<K, V> o1,
java.util.Map.Entry<K, V> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
orderedValueEntrySet.addAll(super.entrySet());
return orderedValueEntrySet;
}
@Override
public Set<K> keySet() {
Set<K> orderedKeySet = new LinkedHashSet<K>();
for(Map.Entry<K, V> e : entrySet()) {
orderedKeySet.add(e.getKey());
}
return orderedKeySet;
}
}
如果您经常调用方法keySet / entrySet,则上述解决方案不是最佳,因为它会对每次调用的条目进行排序。您可能希望缓存这些结果,以避免在地图的内部状态未发生更改时重新计算。
上述示例运行如下:
public static void main(String[] args) {
ConcurrentHashMap<String,Integer> map = new OrderedValueHashMap<String,Integer>();
map.put("a", 3);
map.put("b", 7);
map.put("c", 1);
map.put("q", 2);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry);
}
for (String key : map.keySet()) {
System.out.println(key);
}
}
输出:
c=1
q=2
a=3
b=7
c
q
a
b
答案 2 :(得分:1)
有更简单的方法吗?
据我所知,没有。
当然,没有办法对就地哈希映射进行就地排序。 CHM本质上是无序的,因此您必须将条目放入不同的数据结构中以表示条目的有序性。
如果您告诉我们您的要求是什么,也许我们可以提出另一种策略。