兼具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 - 

fromIndex
248.     *
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.}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索return
, key
, item
, returnning
, public
, value
, values
, 子集和的小问题
, key位置
, value值
return值
list容器、go list容器、c list容器、java list容器、list容器的使用,以便于您获取更多的相关知识。

时间: 2024-11-05 19:30:48

兼具List和Map的“容器”类ListMap的相关文章

google map-baidu map 中RoutePlanSearch 类,在谷歌 map 中叫什么

问题描述 baidu map 中RoutePlanSearch 类,在谷歌 map 中叫什么 10C 百度map中是这么写的:RoutePlanSearch rps = RoutePlanSearch . newInstance():我应该在google map中怎么写??? 解决方案 对了,忘了说,,,是android开发

Javascript实现的Map集合工具类完整实例_javascript技巧

本文实例讲述了Javascript实现的Map集合工具类.分享给大家供大家参考.具体如下: var Map = function(){ // 构造entry实体 var Entry = function(key, value){ this.key = key; this.value = value; } this.entries = new Array(); // 构造put方法在数组中放入一个Entry this.put = function(key, value){ // 数组中已存在就不放

JAVA集合框架之Map接口实现类

java.util.HashMap<K,V> 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同.)此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能.迭代 collection 视图所需的时间与 HashMap 实例的"容量"(桶的

Cocos2d-x3.0模版容器详解之二:cocos2d::Map&lt;K,V&gt;

1.概述 版本: v3.0 beta 语言: C++ 定义在 "COCOS2DX_ROOT/cocos/base" 路径下的 "CCMap.h" 的头文件中. ? 1 2 template         <         class         K,         class         V> class         CC_DLL Map; cocos2d::Map<K,V> 是一个内部使用了 std::unordered_

C++中 set,multiset,map,multimap 关联容器实例教程

测试环境:windows 7 vs2010 内部元素有序排列,新元素插入的位置取决于它的值,查找速度快. 除了各容器都有的函数外,还支持以下成员函数: find: 查找等于某个值的元素(x小于y和y小于x同时不成立即为相等)lower_bound: 查找某个下界upper_bound: 查找某个上界equal_range: 同时查找上界和下界count:计算等于某个值的元素个数(x小于y和y小于x同时不成立即为相等)insert: 用以插入一个元素或一个区间 在学习关联容器之前,我们先要学习pa

方法-用SQL语句查询User表中newsh属性为“政治类新闻”和“娱乐类新闻”的人数放入MAP中

问题描述 用SQL语句查询User表中newsh属性为"政治类新闻"和"娱乐类新闻"的人数放入MAP中 用SQL语句查询User表中newsh属性为"政治类新闻"和"娱乐类新闻"的人数放入MAP中问题一:整个方法该如何实现问题二:SQL语句怎么写 参考用例 类似这样的方法 新手不知道该怎么改动成自己需要的方法求助各位大神 public Map<String Long> totalInventory(int year

【温故而知新】C和C++5:STL容器技术综述

容器类是可以包含其他对象的类.STL中提供的较为常用的容器类有向量.链表.队列.集合和图等,每一种容器类都是一个模板,可以包含各种类型的对象.这些容器可以分为序列式和关联式两大类. 序列式容器主要有: 1.vector:向量类,可以认为是一种容量可变的数组,可以提供对元素的随机访问,而且可以在序列尾部快速插入和删除数据,并且在需要的时候可以方便地改变容器的大小: 2.list:双向链表类,不支持随机访问的数组类,遍历链表的元素需要从某个端点开始向前或向后遍历: 3.queue:队列,实现先进先出

java反射技术与类使用示例_java

复制代码 代码如下: package com.java.db;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Arrays;import java.util.

cocos2d::Map

v3.0 beta加入 定义在"COCOS2DX_ROOT/cocos/base"的"CCMap.h"头文件中. template <class K, class V> class CC_DLL Map; cocos2d::Map<K,V>是使用std::unordered_map作为底层结构的关联式容器. 而std::unordered_map是一个存储键值对的关联式容器,它可以通过它们的键快速检索对应的值. 使用unordered_map