兼具List和Map的“容器”类ListMap

“容器”两个字之所以打上引号,是因为这个类没有实现 Collection 接口。要写一个兼具 List 功能和 Map 功能的类,有几个困难,一 是 Java 不允许同时实现 List 和 Map 两个接口,二是这个 ListMap 结合了二 者的功能之后,产生了特殊的接口。例如 Collection 的 contains 方法,在 ListMap 中就需要衍生出 containsKey 和 containsValue 两个方法,分别判断 容器中是否存在指定的键和值。

下面是我的实现(有什么 BUG 欢迎指正):

1.package myCollections;2. 3.import java.util.*;4. 5./**6. * 兼具 List 和 Map 功能的容器类7. */8.@SuppressWarnings({"unchecked"})9.public class ListMap<K, V> {10. 11.    private List<Item> values = new ArrayList<Item>();12. 13.    /**14.     * 获取元素个数15.     *16.     * @return 元素个数17.     */18.    public int size() {19.        return values.size();20.    }21. 22.    /**23.     * 判断容器是否为空24.     *25.     * @return 如果为空则返回 true。26.     */27.    public boolean isEmpty() {28.        return values.isEmpty();29.    }30. 31.    /**32.     * 获得一个值迭代器33.     *34.     * @return 值迭代器35.     */36.    public IteraTor<V> iteraTor() {37.        return values().iteraTor();38.    }39. 40.    /**41.     * 获得一个值数组42.     *43.     * @return 值数组44.     */45.    public V[] toArray() {46.        Object[] arr = new Object[values.size()];47.        for (int i = 0; i < values.size(); i++) {48.            arr[i] = values.get(i).value;49.        }50.        return (V[]) arr;51.    }52. 53.    /**54.     * 检查指定的键是否存在55.     *56.     * @param key 键57.     *58.     * @return 如果存在则返回 true。59.     */60.    public boolean containsKey(K key) {61.        if (key == null) return false;62.        for (Item item : values) {63.            if (item.key.equals(key)) {64.                return true;65.            }66.        }67.        return false;68.    }69. 70.    /**71.     * 检查指定的值是否存在72.     *73.     * @param value 值74.     *75.     * @return 如果存在则返回 true。76.     */77.    public boolean containsValue(V value) {78.        for (Item item : values) {79.            if (item.value.equals(value)) {80.                return true;81.            }82.        }83.        return false;84.    }85. 86.    /**87.     * 通过键获得值88.     *89.     * @param key 键90.     *91.     * @return 值92.     */93.    public V get(K key) {94.        for (Item item : values) {95.            if (item.key.equals(key)) {96.                return item.value;97.            }98.        }99.        return null;100.    }101. 102.    /**103.     * 设置值。如果键不存在则添加。104.     *105.     * @param key   键106.     * @param value 值107.     *108.     * @return 原来的值。如果键不存在则返回 null。109.     */110.    // 这里要注意,key 必须是唯一的,所以如果 key 已经存在则做替换,否则做添加111.    public V put(K key, V value) {112.        for (Item item : values) {113.            if (item.key.equals(key)) {114.                V replaced = item.value;115.                item.value = value;116.                return replaced;117.            }118.        }119. 120.        Item item = new Item(key, value);121.        values.add(item);122.        return null;123.    }124. 125.    /**126.     * 删除键。值也会删除。127.     *128.     * @param key 键129.     *130.     * @return 如果键存在则返回 true。131.     */132.    public boolean remove(K key) {133.        for (Item item : values) {134.            if (item.key.equals(key)) {135.                values.remove(item);136.                return true;137.            }138.        }139.        return false;140.    }141. 142.    /**143.     * 删除指定位置的键和值144.     *145.     * @param index 位置146.     *147.     * @return 该位置的值148.     *149.     * @throws IndexOutOfBoundsException 如果位置超过范围150.     */151.    public V remove(int index) {152.        return values.remove(index).value;153.    }154. 155.    /**156.     * 清除容器中的所有键和值157.     */158.    public void clear() {159.        values.clear();160.    }161. 162.    /**163.     * 获取指定位置上的值164.     *165.     * @param index 位置166.     *167.     * @return 值168.     *169.     * @throws IndexOutOfBoundsException 如果位置超过范围170.     */171.    public V get(int index) {172.        return values.get(index).value;173.    }174. 175.    /**176.     * 设置指定位置的值177.     *178.     * @param index 位置179.     * @param value 新的值180.     *181.     * @return 旧的值182.     *183.     * @throws IndexOutOfBoundsException 如果位置超过范围184.     */185.    public V set(int index, V value) {186.        Item item = values.get(index);187.        V old_value = item.value;188.        item.value = value;189.        return old_value;190.    }191. 192.    /**193.     * 在指定位置添加一个新的键和值194.     *195.     * @param index 位置196.     * @param key   键197.     * @param value 值198.     *199.     * @throws IllegalStateException 如果键已经存在200.     */201.    public void add(int index, K key, V value) {202.        if (containsKey(key)) {203.            throw new IllegalStateException("key alreay exists.");204.        }205.        Item item = new Item(key, value);206.        values.add(index, item);207.    }208. 209.    /**210.     * 根据值查找所在的第一个位置211.     *212.     * @param value 值213.     *214.     * @return 值所在的第一个位置215.     */216.    public int indexOfValue(V value) {217.        for (int i = 0; i < values.size(); i++) {218.            Item item = values.get(i);219.            if (item.value.equals(value)) {220.                return i;221.            }222.        }223.        return -1;224.    }225. 226.    /**227.     * 根据键查找所在位置228.     *229.     * @param key 键230.     *231.     * @return 键所在位置232.     */233.    public int indexOfKey(K key) {234.        if (key == null) {235.            return -1;236.        }237.        for (int i = 0; i < values.size(); i++) {238.            Item item = values.get(i);239.            if (item.key.equals(key)) {240.                return i;241.            }242.        }243.        return -1;244.    } 245. 246.    /**247.     * 获取一个包含元素子集和的容器。容器的元素个数为 toIndex - fromIndex248.     *249.     * @param fromIndex 子集和的开始位置(含)250.     * @param toIndex   子集和的结束位置(不含)251.     *252.     * @return 包含元素子集和的容器253.     */254.    public ListMap subList(int fromIndex, int toIndex) {255.        ListMap<K, V> map = new ListMap<K, V>();256.        map.values.addAll(values.subList(fromIndex, toIndex));257.        return map;258.    }259. 260.    /**261.     * 获取值 List 对象262.     * @return 包含值的 List 对象263.     */264.    public List<V> values() {265.        List<V> list = new ArrayList<V>();266.        for (Item item : values) {267.            list.add(item.value);268.        }269.        return list;270.    }271. 272.    /**273.     * 获取包含键的 List 对象274.     * @return 包含键的 List 对象275.     */276.    public List<K> keys() {277.        List<K> list = new ArrayList<K>();278.        for (Item item : values) {279.            list.add(item.key);280.        }281.        return list;282.    }283. 284.    /**285.     * 对键进行从小到大排序286.     */287.    public void sortKey() {288.        Collections.sort(values, new ComparaTor<Item>() {289.            public int compare(Item i1, Item i2) {290.                Comparable c1 = (Comparable) i1.key;291.                Comparable c2 = (Comparable) i2.key;292.                if (c1 == null && c2 == null) return 0;293.                if (c1 == null) return -1;294.                if (c2 == null) return 1;295.                return c1.compareTo(c2);296.            }297.        });298.    }299. 300.    /**301.     * 对值进行从小到大排序302.     */303.    public void sortValue() {304.        Collections.sort(values, new ComparaTor<Item>() {305.            public int compare(Item i1, Item i2) {306.                Comparable c1 = (Comparable) i1.value;307.                Comparable c2 = (Comparable) i2.value;308.                if (c1 == null && c2 == null) return 0;309.                if (c1 == null) return -1;310.                if (c2 == null) return 1;311.                return c1.compareTo(c2);312.            }313.        });314.    }315. 316.    /**317.     * 对容器元素进行倒排318.     */319.    public void reverse() {320.        Collections.reverse(values);321.    }322. 323.    /**324.     * 内部类325.     */326.    private class Item {327. 328.        public K key;329. 330.        public V value;331. 332.        public Item(K key, V value) {333.            if (key == null) {334.                throw new NullPointerException("key cannot be null.");335.            }336.            this.key = key;337.            this.value = value;338.        }339.    }340.}

你在无垠的海边第一次听到了自己心跳的声音,

兼具List和Map的“容器”类ListMap

相关文章:

你感兴趣的文章:

标签云: