java容器
我曾经想去画出java容器的类图,但是我后来发现整个java容器的实现相当的复杂,其中包括很多接口和抽象类。 这里我来把一些常见的java容器梳理一下。
Collection
这是一个接口,在java的类图中属于比较底层的,它的API有:
add() 将一个新元素放入Collection中
Collection.addAll() 它接受另一个Collection作为对象
Collections.addAll() 它接受两个collection作为参数,另外它还可以接受可变参数
List 它也是一个接口,继承自Collection,List在Collection基础上添加了大量的方法,它以特定的顺序保 存一组元素,它的API有:
contains() 确定某个对象是否在列表中 remove() 参数是某个对象的引用 indexOf() 参数也是对象的引用,返回索引编号 subList(a,b) 创造一个子List,起始于a,终止于b的前一个元素 containsAll() 是否包含参数List中的所有元素 retainAll() 交集操作,它接收一个参数List。 removeAll() 删除参数List中的所有元素 set() 与replace()一样 addAll() 重载了collection方法,能够在List中间插入,第一个参数就是插入的索引位置 isEmpty() 判空 clear() 清空List toArray() 将List转化为数组,这是一个重载方法,所以Collection也有此方法
上面有很多基于equals()方法,List有两种基本形式,它们都间接继承自List:
ArrayList 长于随机访问元素,但是在List中间插入和移除元素较慢
LinkedList 它通过较低的代价在List中进行插入和删除操作,但是随机访问比较慢,有API:
getFirst()与element() 返回列表的头,但是不移除他们,列表为空时抛出异常 peek() 与上面相同,在列表为空时返回null remove()与removeFirst() 移除并返回列表的头,列表为空时抛出异常 poll() 与上面相同,在列表为空时返回null addFirst(),add(),addLast() 将元素插入到列表的尾端 removeLast() 移除并返回列表的最后一个元素
Stack也是间接继承自List,但是我们一般不太使用:
s.empty(); 测试堆栈是否为空。(和C++一样) s.peek(); 查看栈顶对象而不移除它。(s.top() (C++)) s.pop(); 移除栈顶对象并作为此函数的值返回该对象。 s.push(); 把项压入栈顶。(和C++一样)
- Set不保存重复的元素,它也是一个接口,继承自Collection,但是它并没有添加额外的功能,几乎就和Collection 接口一样。它也有两种基本形式:
HashSet 它使用散列的方式来存储元素
TreeSet 它将元素存储在红黑树数据结构中,它会将Set中的元素按顺序储存起来
Set的API与List几乎相同
Queue是一个典型的先进先出(FIFO)的容器接口,其实上文中的LinkedList就实现了Queue的接口,我们来看 看Queue的API:
offer() 将一个元素插入到队尾,或者返回false peek()与element() 不移除的情况下返回队头,后者在队列为空时抛出异常 poll()与remove() 移除并返回队头,后则在队列为空时抛出异常
实际上,Queue接口窄化了LinkedList,因为后者继承自上述两个接口。PriorityQueue中的默认排序是队列的自然 序列,如升序和字典序。
迭代器Iterator 它有三个方法:
next() 获得序列中的下一个元素 hasNext() 检查序列中是否还有元素 remove() 将迭代器新近返回的元素删除
我们有时候要尽量使用Iterator,因为它能够将遍历序列的操作与序列底层的结构分离,所以可以这么说:迭代器统一 了我们对容器的访问方式。
Map
将对象映射到其他对象上的能力是一种解决编程问题的杀手锏,它也是一个比较底层的接口。它的API:
put() 将一对key和value放入Map中
get() 通过一个key取得value值
containsKey()与containsValue() 测试Map中是否含有这个key和value
keySet() 返回键值组成的Set
values() 返回values的Collection
上面我只是将常用容器的继承关系和api分析了一遍,还需要深入分析他们和他们的线程安全性,期待进一步的学习