持有对象
通常程序总是根据运行时才知道的某些条件去创建新对象。在此之前,你不会知道所需对象的数量,甚至不知道确切的类型。
在java中,容器类是可以显著增强编程能力的基本工具
一、泛型和类型安全的容器
@SuppressWarnings注解及其参数表示有关“不受检查的异常”的警告信息应该被一直通过使用泛型,可以在编译器防止将错误类型的对象放置到容器中。
二、基本概念
java容器类库的用途是“保存对象”,划分为两个不同的概念:
1,collection一个独立元素序列,这些元素都服从一条或多条规则。list必须按顺序保存元素,set不能有重复元素,queue按照排队规则确定对象产生的顺序(通常与被插入顺序相同)
2,map一组成对的“键值对”对象,允许你使用键来查找值。映射表允许我们使用另一个对象来查找某个对象,它也被称为关联数组,它将某些对象与另外一些对象关联在一起,或者被称为字典。
Collection接口概括了序列的概念:一种存放一组对象的方式。任何继承自Collection的类的对象都可以正常工作。所有的Collection都可以用foreach语法遍历。list不关心是否重复,set只有不存在的情况下才添加。
三、添加一组元素
在java.util包中的Array和Collections类中欧都有很多实用方法,可以在一个Collection中添加一组元素。
Arrays.asList()方法接受一个数组或是一个用逗号分隔的元素列表(使用可变参数),并将其转换为一个List对象。
Collections.addAll()方法接受一个Collection对象,以及一个数组或是一个用逗号分割的列表,将袁术添加到Collection中。
Map除了用另一个Map外,Java标准类库没有提供任何其他任何自动初始化它们的方式。
四、容器的打印
Collections在每个槽中只能保存一个元素。此容器包括:List以特定顺序保存一组元素,Set元素不能重复,Queue只允许容器的一端插入对象,从另一端溢出对象。
Map在每个槽内保存了连个对象,即键与之相关联的值。
HashSet是最快的获取元素符方式,存储顺序并无实际意义;TreeSet,按照比较对象的升序顺序保存对象;LinkedHashSet按照被添加的顺序保存对象。
Map(也被称为关联数组)使得你可以用键来查找对象,就像一个简单的数据库。键所关联的对象称为值,对于每一个键,Map只接受存储一次。
你不必制定Map的容器尺寸大小,它自己会自动调整尺寸。Map还知道如何打印自己,它会显示相关联的键和值。键和值在Map中的保存顺序并不是它们的插入顺序。
五、List
List承诺可以将袁术维护在特定的序列中。List接口在Collection的基础上添加了大量的方法,使得可以在List的中间插入和移除元素。
基本的ArrayList,它长于随机访问元素,但是在List的中间插入和移除元素时较慢。
LinkedList它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序访问。
LinkedList在随机访问方面相对较慢,但是它的特性集较ArrayList更大。
六、迭代器
任何容器类,都必须有某种方式可以插入元素并将它们再次取回。持有事物是容器最基本的工作。
迭代器是一个对象,它的工作是遍历并选择序列中的对象,使程序员不必知道或关心该序列底层的结构。此外,迭代器通常被称为轻量级对象:创建它的代价小。
java的Iterator只能单向移动,只能用来:1,使用方法iterator()要求容器返回一个Iterator,Iterator将返回准备好返回序列的第一个元素。2,使用next()获得序列中的下一个元素。
3,使用hasNext()检查序列中是否还有元素。4,使用remove()将迭代器新近返回的元素删除。
ListIterator是一个更加强大的Iterator的子类型,它只能用于各种List类的访问。尽管Iterator只能向前 移动,但是ListIterator可以双向移动。
七、LinkedList
LinkedList也像ArrayList一样实现了基本的List接口,但是它执行某些操作(在List的中间插入和移除)时比ArrayList更高效,但在随机访问操作方面要逊色一些。LinkedList还添加了可以使其用作栈,队列或双端队列的方法。
八、Stack
栈通常是指先进后出的容器,伊欧诗栈也被称为叠加栈,因为最后一个亚茹栈的元素,第一个弹出栈。LinkedList具有能够直接实现栈的所有功能的方法,因此可以直接将LinkedList作为栈使用。
九、Set
Set不保存重复的元素。HashSet专门对快速查找进行了优化。Set具有与Collection完全一样的接口。实际上Set就是Collection,只是行为不同。Set是基于对象的值来确定归属性的。
HashSet出于速度原因,使用了散列。TreeSet将元素存储在红-黑树数据结构中。
十、Map
将对象映射到其他对象的能力是一种解决编程问题的杀手锏,Map可以很容易的解决该问题。
通过containsKey()和containsValue()方便查看是否包含某个键或某个值。
Map与数组和其他的Collection一样,可以很容易地扩展到多维,而我们只需将其值设置为Map,能够很容易地将容器组合起来从而快速地生成强大的数据结构。
十一、Queue
对列是一个典型的先进先出(FIFO)容器,即从容器的一端放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。队列常被当做一种可靠的将对象从程序的某个区域传输到另一个区域的途径。
LinkedList提供了方法支持队列的行为,并且实现了Queue接口,因此LinkedList可以用作Queue的一种实现。LinkedList向上可以转型为Queue。
注意:与Queue相关的方法提供了完整而独立的功能。
十二、Collection和Iterator
Collection是描述所有序列容器的共性的根接口,另外java.util.AbstractCollection提供了Collection的默认表现,使得你可以创建AbstractCollection的子类型。
当你实现一个不是Collection的外部类时,由于让它去实现Collection接口可能非常困难或麻烦,因此使用Iterator就会变得非常吸引人。
十三、Foreach与迭代器
Foreach可以用于数组和任何Collection对象。Iterable接口包含一个能够产生Iterator的iterator()方法,并且,Iterable接口被foreach用来在序列中移动。如果你创建了任何实现Iterable的类,都可以将它用于foreach语句中。
Foreach可以用于数组或其他任何Iterable,但是不存在任何从数组到Iterable的自动转换。
十四、总结
java提供了大量持有对象的方式。
1,数组将数字与对象联系起来。它保存类型明确的对象,查询对象时,不需要对结果做类型转换。它可以是多维的,可以保存基本类型的数据。但是,数组一旦生成,其容量就不能改变。
2,Collection保存打你的元素,而Map保存相关联的键值对。有了Java的泛型,你就可以指定容器中存放的对象类型,因此你就不会将错误类型的对象放置到容器中,并且在从容器中获取元素时,不必进行类型转换。
各种Collectino和各种Map都可以在你向其中添加更过的元素时,自动调整其尺寸。容器不能持有基本类型,但是自动包装机制会仔细执行基本类型到容器中所持有的包装器类型之家你的双向转换。
3,像数组一样,List也建立数字索引与对象的关联,因此,,数组和List都是排好序的容器。List能够自动扩充容量。
4,如果要进行大量的随机访问,就使用ArrayList,如果要经常从表中加你插入或删除元素,就使用LinkedList
5,各种Queue以及栈的行为,由linkedList提供支持。
6,Map是一种将对象(非数字)与对象相关联的设计。HashMap设计用来快速访问,而TreeMap保持键始终处于排序状态,所以没有HashMap块。LinkedHashMap保持元素插入的顺序,但是也通过提供散列提供快速访问能力。
7,Set不接受重复元素。HashSet提供最快的查询速度,而TreeSet保持元素处于排序状态。LinkedHashSet插入顺序保存元素。
8,新程序中不应该使用过时的Vector,HashTable和Stack。
除了TreeSet之外的所有Set都具有与Collectino完全一样的接口。
List和Collection存在明显的不同,尽管List所要求的方法都在Collection中。
在Queue接口中的方法都是独立的,在创建具有Queue功能的实现时,不需要使用Collection方法。
Map和Collection之间的唯一重叠就是Map可以使用entrySet()和values()方法来产生Collection。
四种容器:Map,List,Set,Queue。点线框表示接口,实心箭头表示某个类可以生产箭头所指向类的对象。java容器简图如下(只包含一般情况下遇到的接口和类):