“容器”两个字之所以打上引号,是因为这个类没有实现 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容器的使用,以便于您获取更多的相关知识。