《Java编程思想》 第十一章 持有对象 记录

1. 泛型与类型安全的容器

  • @SuppressWarnings注解及其参数表示只有有关“不受检查的异常”的警告信息应该被抑制。

2. 基本概念

  • Collection接口概括了序列的概念,一种存放一组对象的方式。

3. 添加一组对象

  • Arrays.asList()方法接受一个数组或是一个用逗号分隔的元素列表(使用可变参数),并将其转换为一个List对象。

4. 容器的打印

  • Collection的每个槽只能保存一个元素。此类容器包括:List,它以特定的顺序保存一组元素;Set,元素不能重复;Queue,只允许在容器的一“端”插入对象,并从另一“端”移除对象。Map在每个槽内保存了两个对象,即键和与之相关联的值。
  • ArrayList和LinkedList都是List类型,从输出可以看出,他们都按照被插入的顺序保存元素。两者各不同之处不仅在于执行某些类型的操作时的性能,而且LinkedList包含的操作多与ArrayList。
  • HashSet、TreeSet和LinkedHashSet都是Set类型,输出显示在Set中,每个相同的项只有保存一次,但是输出也显示了不同的Set实现存储元素的方式也不同。HashSet使用的是相当复杂的方式来存储元素,这种技术是最快的获取元素的方式,因此,存储的顺序看起来并无实际意义(通常你只会关心某事物是否是某个Set的成员,而不会关心它在Set出现的顺序)。如果存储顺序很重要,那么可以使用TreeSet,它按照比较结果的升序保存对象;或者使用LinkedHashSet,它按照被添加的顺序保存对象。
  • Map(也被称为关联数组)使得你可以用键来查找对象,就像一个简单的数据库。键所关联的对象称为值。HashMap与HashSet一样,HashMap也提供了最快的查找技术,也没有按照任何明显的顺序来保存元素。TreeMap按照比较结果的升序保存键,而LinkedHashMap则按照插入顺序保存键,同时还保留了HashMap的查询速度。

5. List

  • List承诺可以将元素维护在特定的序列中。List接口在Collection的基础上添加了大量的方法,使得可以在List的中间插入和移除元素。有两种类型的List:
  1. 基本的ArrayList,它长于随机访问元素,但是在List的中间插入和移除元素时较慢
  2. LinkedList,它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序访问。在随机访问方面相对比较慢,但是它的特性集较ArrayList更大。
  • retainAll()方法是一种有效的“交集”操作。

6. 迭代器

  • 迭代器(也使一种设计模式)是一个对象,它的工作是遍历并选择序列中的对象,而不必知道该序列底层的结构。迭代器通常被称为轻量级对象:创建它的代价小。因此,经常可以见到对迭代器有些奇怪的限制;例如,Java的Iterator只能单向移动,这个Iterator只能用来:
  1. 使得方法iterator()要求容器返回一个Iterator。Iterator将准备好返回序列的第一个元素。
  2. 使用next()获得序列中的下一个元素。
  3. 使用hasNext()检查序列中是否还有元素。
  4. 使用remove()将迭代器新近返回的元素删除。
  • Iterator能够将遍历序列的操作与序列底层的结构分离。正由于此,我们有时会说:迭代器统一了对容器的访问方式。

7. LinkedList

  • 在List的中间插入和移除时比ArrayList更高效

8. Stack

  • “栈”通常是指“后进后出”(LIFO)的容器。有时栈也被称为叠加栈,因为最后“压入”栈的元素,第一个“弹出”栈。

9. Set

  • Set不保存重复的元素。
  • 想对结果排序,可以使用TreeSet来代替HashSet。

11. Queue

  • 队列是一种典型的先进先出(FIFO)的容器。即从容器的一段放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。队列常被当作一种可靠的将对象从程序的某个区域传输到另一个区域的途径。队列在并发编程中特别重要,因为它们可以安全地将对象从一个任务传输到另一个任务。
  • 先进先出描述了最典型的队列规则。队列规则是指在给定一组队列中的元素的情况下,确定下一个弹出队列的元素的规则。先进先出声明的是下一个元素应该是等待时间最长的元素。
  • 优先级队列生命下一个弹出元素是最需要的元素(具有最高优先级)。

12. Collection和Iterator

  • Collection是描述所有序列容器的共性的根接口,它可能被认为是一个“附属接口”,即因为要表示其他若干个接口的共性而出现的接口。
  • 使用接口描述的一个理由是它可以使我们能够创建更通用的代码。通过针对接口而非具体实现来编写代码,我们的代码可以应用于更多的对象类型。因此,如果我编写的方法将接受一个Collection,那么该方法就可以应用于任何实现了Collection的类,这也使得一个新类可以选择去实现Collection接口,以便我的方法可以使用它。

13. Foreach与迭代器

  • foreach可用于数组,也可以应用于任何Collection对象。
  • Iterable接口包含一个能够产生Iterator的iterator()方法,并且Iterator接口被用来在序列中移动。因此如果你创建了任何实现Iterable的类,都可以将它用于foreach()语句中。
  • Arrays.asList()的输出被传递给了ArrayList()构造器,因此打乱这些引用不会修改该数组。但如果直接使用Arrays.asList(数组) 的结果,这种会修改该数组的顺序。Arrays.asList()产生的List对象会使用底层数组作为其物理实现是很重要的。只要你执行的操作会修改这个list,并且你不想原来的数组被修改,那么你就应该在另一个容器中创建一个副本。

14. 总结

  1. 数组将数字与对象联系起来。它保存类型明确的对象,查询对象时,不需要对结果做类型转换。它可以是多维的,可以保存基本类型的数据。但是,数组一旦生成,其容量就不能改变。
  2. Collection保存单一的元素,而Map保存相关联的键值对。有了Java的泛型,你就可以指定容器中存放的对象类型,因此你就不会将错误类型的对象放置到容器中,并且在从容器中获取元素时,不必进行类型转换。各种Collection和各种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。
    简单的容器分类
发布了57 篇原创文章 · 获赞 11 · 访问量 9883

猜你喜欢

转载自blog.csdn.net/qq_36160730/article/details/96900712