数据结构像Map一样工作,但允许随机更改键顺序

时间:2013-04-10 22:05:54

标签: java list data-structures map

我已经阅读了很多关于实现MapList接口的数据结构的主题。 到处都是LinkedHashMap或SortedMap就足够了。
但是我的情况略有不同,因为我不仅需要保持按键的排序顺序或排序地图,还需要对按键顺序进行随机更改。 允许List使用方法add(int index, E element)允许这样做,但Map的实现不支持这样的方法。 应该提到的是,我需要的数据结构主要用作地图。 例如,地图如下所示:

  1. 键1 - >价值1
  2. 键2 - >价值2
  3. 键3 - >价值3
  4. 键4 - >价值4
  5. 我可能需要将第i对移动到第j个位置,具体取决于用户操作:

    1. 键1 - >价值1
    2. 键4 - >值4 [j]
    3. 键3 - >价值3
    4. 键2 - >价值2 [i]

    5. 我有一个想法,就是将LinkedList和HashMap结合起来,并在它们之间同步插入和删除。因此Map可以按任何顺序存储元素,同时List中的元素可以按我的要求排序。
      但我认为这不好。这种结构需要几乎两倍的内存并且在Collection Framework中严重集成,因为名称冲突会阻止单个类实现List和Map。
      所以我的问题是:用Java描述的特性实现数据结构的最佳方法是什么?

2 个答案:

答案 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

获取已排序的密钥集

这绝不是一个有效的解决方案 - 但它可能符合您的目的