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