我已经阅读了很多关于实现Map
和List
接口的数据结构的主题。
到处都是LinkedHashMap或SortedMap就足够了。
但是我的情况略有不同,因为我不仅需要保持按键的排序顺序或排序地图,还需要对按键顺序进行随机更改。
允许List
使用方法add(int index, E element)
允许这样做,但Map
的实现不支持这样的方法。
应该提到的是,我需要的数据结构主要用作地图。
例如,地图如下所示:
我可能需要将第i对移动到第j个位置,具体取决于用户操作:
我有一个想法,就是将LinkedList和HashMap结合起来,并在它们之间同步插入和删除。因此Map可以按任何顺序存储元素,同时List中的元素可以按我的要求排序。
但我认为这不好。这种结构需要几乎两倍的内存并且在Collection Framework中严重集成,因为名称冲突会阻止单个类实现List和Map。
所以我的问题是:用Java描述的特性实现数据结构的最佳方法是什么?
答案 0 :(得分:1)
如果你需要对键值映射进行O(1)查找,以及不支持像SortedMap这样的不可变性的可自定义排序顺序,那么你可以创建一个使用Map和List的包装类,像这样:
class MapList {
Map<K,V> map = new HashMap<K,V>();
List<K> keysList = new ArrayList<K>();
public void put(K key, V val) {
if (!map.contains(key)) {
keysList.add(key);
}
map.put(key, val);
}
public void swap(int key1pos, int key2pos) {
keysList.set(key1pos, keysList.set(key2pos, keysList.get(key1po)));
}
// Getter methods, size, etc...
}
我认为您无法满足对具有此类要求的自定义类的需求。通常认为密钥在集合API中是不可变的
答案 1 :(得分:0)
如果排序很重要,那么如何创建一个带有订单字段的通用密钥对象类,例如:
public class MyKey<K> implements Comparable {
private int order;
private K key;
/* getters & setters */
/* compareTo() */
}
compareTo()
方法按订单字段值排序。然后把它放在你的密钥类型周围。例如:如果您要存储整数 - >整数地图:
Map<MyKey<Integer>,Integer> myMap = /*.. */;
然后,只要您需要重新排序密钥,只需更改订单字段值即可。然后,您可以使用地图keySet()
加Collections.sort()
或TreeSet
这绝不是一个有效的解决方案 - 但它可能符合您的目的