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

java编程思想读书笔记----第十一章 持有对象

2017-03-03 11:04 176 查看
  java提供了一套容器类,用来解决在任意时刻任意位置,创建任意数量的对象的问题,其中基本的类型是List,Set,Queue,Map,这些对象称为集合类,但java类库中用Collection来指代该类库中的一个特殊子集,所以可以称之为容器。



1、泛型和类型安全的容器

  通过使用泛型,你不仅知道编译器将会检查你放置到容器中的对象类型,而且在使用容器中的对象时,可以使用更加清晰的语法。向上转型也可以像作用与其他类型一样作用于泛型。

2、基本概念

  java容器的作用是保存对象,可以划分为两个不同的概念:

Collection 一个独立元素的序列,这些序列都服从一条或多条规则。List必须按照插入顺序保存元素,而Set不能有重复元素,Queue按照排队规则确定对象的产生顺序。

Map 一组“键值对”对象,又称关联数组,字典。

  可以通过下面这种方式创建一个List

List<String> list=new ArrayList<String>();


  通常都是使用具体的类实现接口。但并不总是这样,因为某些类具有额外的功能,例如,LinkedList具有List未包含的方法,而TreeMap也具有Map中未包含的方法。

  Collection接口概括了序列的基本概念–一种存放一组对象的方式。ArrayList是最基本的序列类型。

  在java.util包中的Collections和Arrays都有很多实用方法,可以在Collection中增加一组序列。Arrays.asList()接受一个数组或者元素列表(可变参数),并将其转换成数组。Collections.addAll() 接收一个Collection对象,以及一个数组或者元素列表,并将其添加到Collection对象。Arrays.asList()只会创建参数中有的类型的容器,而Collections.addAll()会根据第一个参数了解到目标类型是什么。 Collection.addAll()只接收一个Collection对象,运行起来较快。

  Map更加复杂,除了用另一个Map之外,并没有其它初始化的方式。

3、容器的打印

  必须使用Arrays.toString()来产生数组的可打印表示,容器无需任何帮助。

  ArrayList和LinkedList都是List类型,它们按照插入的顺序保存元素。

  HashSet、TreeSet和LinkedHashSet都是Set类型,每个相同的项只保存一次。HashSet使用相当复杂的方式存储元素,该方式是最快的获取元素方式。TreeSet按照比较结果的升序排列。LinkedHashSet按照添加的顺序保存对象。

  HashMap、TreeMap和LinkedHashMap都是Map类型,Map类型的key是不同的。和Set类似,HashMap提供了最快的查找速度,没有按照明显的顺序排列,TreeMap按照比较结果的升序保存键,LinkedHashMap按照插入的顺序保存键。

4、List

  有两种类型的List,基本的ArrayList,它长于随机访问,但是在List的中间插入和移除元素较慢。LinkedList,它在List中间插入和移除元素代价较低,提供了优化的顺序访问,在随机访问方面比较慢,但是特性集比List大。

  subList()产生子列表,其幕后就是初始列表,对所返回的列表的修改都会映射到初始列表中。

5、迭代器

  迭代器是一个对象,它的工作是遍历并选择序列中的对象,使用者不必关心该序列的底层实现。迭代器是一个轻量级对象,创建它的代价小。因此,迭代器有着很多奇怪的限制。例如,java中的Iterator只能单向移动。

  ListIterator是一个更强大的迭代器,它只能用于List类型的序列,它可以双向移动,它还可以产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引, 并且可以使用set()替换访问过的最后一个元素。

6、LinkedList

  LinkedList还添加了可以使其用作栈、队列或双端队列的方法。这些方法有些彼此之间只是名字有所差异,以使得这些名字在特定的上下文中更加适用(特别是Queue)。例如,getFirst()和element()完全一样,它们都返回列表的头,而并不移除元素,如果 list为null,则抛出NoSuchElementException。peek()和两个方法稍有差异,它在列表为空时返回null。

  removeFirst()和remove()相同,它们移除并返回列表的头,如果 list为null,则抛出NoSuchElementException。poll()在 列表为空时返回null。

  addFirst()与add()和addLast()相同,它们将一个元素插入列表的顶(尾)部。

  removeLast()移除并返回最后一个元素。

7、Stack

  栈是指“后入先出”(LIFO)的容器,push()接收元素,peek()提供栈顶元素,但不移除。pop()返回并移除栈顶元素。

8、Set

  Set不保存重复的元素,它具有与Collection完全相同的接口不具有额外的功能。

9、Map

10、Queue

  队列是典型的先进先出(FIFO)的容器,即从容器的一端进入,从另一端取出,并且事物放入容器的顺序和取出的顺序是相同的。

  offer()方法是与队列相关的方法,它在允许的情况下将,将一个元素插入到队尾,或者返回false。peek()和element()都在不移除的情况下返回队头,peek()在队列为空时会返回NULL, element()会抛出异常。poll()和remove()会移除并返回队头。

11、Collection和Iterator

  Collection是描述所有序列容器的共性的根属性接口,如果一个方法接受一个Collection类,则该方法可以用于所有实现了Collection接口的类。而在java中实现Colletion就意味着需要提供iterator()方法。Collection类也是Iterator类。

  当要实现一个不是Collection类的外部类时,实现Collection接口可能会非常麻烦或者复杂,让它去实现Iterator类就变得很有必要。

12、foreach和迭代器

  foreach之所以能工作,是因为Iterator接口,该接口包含一个能生成Iterator类的iterator()方法。如果创建了任何实现了Iterator接口的类,都可以用于foreach中。

  foreach用于数组和其他各种Iterator,但这不意味着数组也是Iterator,而任何自动包装不会自动发生。

//———————————

e5

注意重载方法,如remove(); 它很容易犯错误,由于自动装箱。 例如,如果您键入remove(2)而不是remove(Integer.valueOf(2)),则从列表中删除第三个元素(如第一个元素的索引为0),而不是值为2的元素。

e7

在使用Arrays.asList()后调用add,remove这些method时出现java.lang.UnsupportedOperationException异常。这是由于Arrays.asList() 返回java.util.ArraysArrayList,而不是ArrayList。ArraysArrayList和ArrayList都是继承AbstractList,remove,add等method在AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。ArrayList override这些method来对list进行操作,但是Arrays$ArrayList没有override remove(),add()等,所以throw UnsupportedOperationException。 搞了很久,最后才查出来这个问题。最后的解决办法是使用List lst = new ArrayList()构造一个LIST ,然后通过for循环将值放进lst里面去。还是少用asList的好。。。

  subList( )返回的是与主列表相关的子列表,对主列表的修改会导致子列表为undefined。同样,子列表的修改也会导致主列表变化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 读书笔记