“容器”兩個字之所以打上引號,是因為這個類沒有實現 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.}