您的位置:首页 > 编程语言 > Java开发

#Java 核心技术卷一阅读笔记# 第九章 集合

2017-10-01 10:02 281 查看

9.1 Java集合框架

Java的集合类库是将接口与实现相分离的。以队列为例,库中只有Queue接口,而具体实现分别是ArrayDeque和LinkedList两类。

ArrayDeque

是以循环数组作为实现的,即数组的任意一点都能被看做是起点或终点。

它实现了Deque接口和Queue接口,故即可以作为双端队列(首尾可添加或删除元素),也可以作为栈使用(Java不推荐使用Stack类),ArrayDeque作为队列使用时性能好于LinkedList。但是循环数组容量有限,如果要储存的对象无数量上限,则最好使用LinkedList。

以下是对此类的源码解析以及官方说明

http://www.cnblogs.com/CarpenterLee/p/5468803.html

http://docs.oracle.com/javase/8/docs/api/java/util/ArrayDeque.html

LinkedList

是以双向链表作为实现的。

它实现了Deque接口和Queue接口,可看做顺序容器,也可以作为队列、栈使用。需要频繁的进行删除与插入操作时推荐使用LinkedList

http://www.cnblogs.com/CarpenterLee/p/5457150.html

http://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html

在构建集合对象时,可用接口对象变量作为存放集合对象引用的容器,在new后指出具体的实现类型。

Queue<String> queue = new LinkedList<>();
...


所有的集合类的基本接口是Collection接口,在这个接口中没有提供任何直接的实现,而是在它的子接口中提供(如SET/List…),它的超接口是Iterable,即提供一个iterator< E> iterator()方法,返回一个实现了intera
4000
tor接口的对象。

迭代器

iterator接口的方法是:



使用foreach语句可以逐个访问集合中的元素

collection<String> c = ...;
Iterator<String> itr = c.iterator();
while(itr.hasNext())
{
String s = itr.next();
....
}


等同于

for(String s : c)
{....}


foreach可用于所有集合。不同集合中访问元素的顺序不同,如ArrayList是顺序访问,而HashSet是随机。

迭代器的位置是处在两个元素之间,next()是返回迭代器略过的最近一个元素的引用,而remove()删除的是上次调用next()返回的元素,两种方法互相关联,不能连续调用remove(),需先调用next()略过待删除的元素。

AbstractCollection类,抽象了size()和iterator(),为其他方法提供了泛型方法,方便类的实现,所以一个具体的集合类扩展于AbstactCollection类。

集合框架接口



集合有两大基本接口:Collection 和Map,一个元素集合,一个是键值对集合;其中List和Set接口继承了Collection接口,一个是有序元素集合,一个是无序元素集合,且不许加入重复元素;而ArrayList和 LinkedList 实现了List接口,HashSet实现了Set接口,这几个都比较常用;HashMap 和HashTable实现了Map接口,并且HashTable是线程安全的,但是HashMap性能更好。

9.2 具体的集合

1.实现List接口的类

a.LinkedList

LinkedList是一个有序集合,其有一个方法add(Object),是在链表末尾加上元素。当需要在链表中某位值插入元素时,需要依赖ListIterator接口。

ListIterator扩展了Iterator,方法如下:



LinkedList中有一个ListIterator(),返回一个实现了ListIterator接口的对象,新对象指向第一个元素开头

,add插入元素的位置在迭代器所在位置之处,而这个接口新添加了previous()和hasPrevious()两个方法,支持逆序遍历数组。set()可以将上一次调用next或previous经过的位置的元素替换

List<String> ll = new LinkedList<>();
ll.add("World!");
ListIterator<String> lI = ll.listIterator();
lI.add("Hello");


拥有n个结点的链表拥有n+1个迭代器位置:

劣势:当要查看链表中的第n个元素时,需要从头开始,略过n-1个元素,所以当程序需要用整数索引访问元素时,应该使用ArrayList。在需要频繁的插入和删除元素的程序中使用LL。

b.ArrayList

ArrayList也实现了List接口。List接口描述了一个有序集合,有两种方式访问元素:一是用迭代器,二是用get和set方法,其中LL不适合第二种,但对ArrayList很有用。

Vector类的所有方法都是同步的,而ArrayList不是

2.实现了SET接口的类

a.HashSet

其中元素无序,但是能快速的查找元素,其用链表数组表示,储存不重复的元素。

b.TreeSet

有序集合,实现了SortedSet接口,其用红黑树表示。用迭代器访问元素时按照自然排序或给出的比较器方法排序。

HashSet效率较高

3.优先队列

用二叉堆实现。

优先队列和TreeSet的不同之处在于:优先队列的迭代不是按照元素的排列顺序访问的,而remove却能删除最小元素(因为堆的结构,根节点为最大值,而最小值在底层)

9.3 映射(Map)

映射是用来保存键值对,两个通用映射:HashMap和TreeMap,第一个是无序储存元素,第二个是用键对元素进行整体排序。

不能对同一个键存放两个值,当使用put(key,val),key如果已存在,则将新值覆盖住旧值,返回旧值。

映射视图:键合集、值合集、键/值对集,不能像集中添加对象,只能删去

Set< K> keySet()

Collection< V> values()

Set

for(Map.Entry<String,Employee> e:staff.entrySet())
{
String k = e.getKey();
String v = e.getValue();
...
}


LinkedHashMap/LinkedHashSet用来记住元素的插入次序

集合与数组的转换

String[] values = ...;
HashSet<String> set = new HashSet<>(Arrays.asList(values));

set.toArray(new String[set.size()])
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: