ConcurrentSkipListMap为何可存非Comparable键?与TreeMap行为差异答疑
TreeMap与ConcurrentSkipListMap的非Comparable键行为差异
首先明确一点:TreeMap和ConcurrentSkipListMap的排序规则是完全一致的:
根据键的自然排序或创建映射时提供的Comparator排序,具体取决于使用的构造方法。
从设计逻辑来看,作为NavigableMap的实现类,ConcurrentSkipListMap和TreeMap一样都是维持内部有序的。如果没有指定自定义的Comparator,非Comparable类型的键根本没法让它保持稳定的顺序。
但这里有个非常容易让人困惑的差异:当存入非Comparable的键时,TreeMap会直接抛出ClassCastException,而ConcurrentSkipListMap却能正常执行!来看下面的示例代码:
// TreeMap存入非Comparable键会抛出异常 TreeMap<ArrayList, Integer> m = new TreeMap<>(); m.put(new ArrayList(), 6); // 抛出ClassCastException - ArrayList未实现Comparable // ConcurrentSkipListMap存入非Comparable键却正常执行 ConcurrentSkipListMap<ArrayList, Integer> lst = new ConcurrentSkipListMap<>(); lst.put(new ArrayList(), 6); // 执行正常!
这种差异确实有点反直觉,毕竟两者的有序性设计逻辑是一致的,但ConcurrentSkipListMap基于跳表的并发插入实现机制,导致它没有在put操作时立即校验键的Comparable特性,而是把这个校验延迟到了后续需要排序或比较的操作中。
内容的提问来源于stack exchange,提问作者Code Complete
相关产品推荐
相关产品推荐

