java容器(概述--think in java 11章)

java容器类UML图:

                     

java容器的特点和作用:

持有对象,自动调整尺寸,方便的操作容器的方法
 

泛型和类型安全:

1).JavaSE5之前编译器允许向容器插入不正确的类型,使用泛型参数的容器提供了类型检查,避免了插入不正确的类型
2).将对象从容器中取出时类型转换也不是必须的了,带泛型参数的容器会在get时替你执行转型
3).泛型带参数的容器支持上转型,可以将一个泛型参数类型的子类型插入容器
基本概念:
java容器类类库的用途时保存对象,可划分成两个不同的概念:
1) Collection 一个独立元素的序列,这些元素都服从一条或多条规则。List必须按照插入的顺序保存元素,而Set不能有重复元素。
   Queue按照排队规则来确定对象产生的顺序
2)Map 一组成对的“键值对”对象,允许你用键来查找值。(ArrayList允许用值来查找值而map允许用键对象来查找值对象)

通常应该创建一个具体容器对象然后将其上转型为对应的接口,然后在其余的代码中都使用这个接口,但当要使用具体容器特有的方法时就不能这么做了。
比如:LinkedList具有在List接口中未包含的方法,而TreeMap也具有在Map接口中未包含的方法

Collection接口概括了序列的概念,一种存放一组对象的方式。add()方法:要确保这个Collection包含指定的元素,因为Set中只有元素不存在的情况下才会添加,
而List不关心是否存在重复。
 

添加一组元素:

在java.util包中的Arrays和Collections类中都有很多实用方法,可以在一个Collection中添加一组元素。
Arrays.asList()方法接受一个数组或是一个用逗号分隔的元素列表(使用可变参数),并将其转换为一个List对象。但要记住,Arrays.asList()返回的
是一个长度不可变的数组。(add()或delete()都会在运行时获得Unsupported Operation错误),Arrays.<Type>asList()插入线索以告诉编译器要产生的
List的类型
Collecctions.addAll()方法接受一个Collection对象,以及一个数组或是一个用逗号分隔的列表,将元素添加到Collection中。
Map除了用另一个Map之外,Java标准类库没有提供任何其他的自动初始化方式。
 

容器的打印:

默认的toString()方法工作的很好
Array.toString()可以产生数组的可打印表示,但对容器没用。
 

List:

有两种类型的List:
基本的ArrayList,长于随机访问元素,但是在List的中间插入和移除元素的速度较慢。(底层是用数组实现的)
LinkedList,它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序访问。在随机访问方面相对较慢,但特性集较ArrayList更大
(底层是用双向链表实现的)
可以用contains()方法来确定某个对象是否在列表中。传递对象的引用给remove()可以移除一个对象。传递对象的引用给indexOf()可以发现该对象在
List中所处位置的编号。(这些操作底层都是通过调用equals()实现的)
在List中间插入元素也是可行的(add()方法有一个带index参数的重载);对于LinkedList,在列表中间插入和删除都是廉价的操作,但是对于ArrayList,
代价十分高昂。
subList()方法允许从较大的列表中创建一个片段,而将其结果传递给这个较大列表的containsAll()方法时,很自然会得到True,subList底层是原始的列表,
所以对subList()的修改都会反映到原始列表中去。
retainAll是一种有效的交集操作。仅仅保留与参数集合重复的元素
remove有通过索引值删除的重载,不必调用equals方法
removeAll从List中移除所有参数List中的元素。
set()方法在指定的索引处用第二个参数替换
addAll使得可以在初始化List的中间插入新的列表,而不仅仅是用Collections中的addAll方法在末尾追加。
toArray()方法可以将任意Collection转换为一个数组。(有参版本可以传递数组,如果参数数组太小,toArray将会创建一个合适大小的数组)无参版本
返回的是Object数组。
 

迭代器:

迭代器是一个对象,它的工作是遍历并选择序列中的对象(也是一种设计模式),能够将遍历序列的操作与底层的结构分离
java的Iterator只能单向移动,这个Iterator只能用来:
1)使用方法iterator()要求容器返回一个Iterator。Iterator将准备号返回序列中的第一个元素。
2)使用next()获得序列中的下一个元素。
3)使用hasNext()检查序列中是否还有元素。
4)使用remove()将迭代器新近的元素删除。(必须先调用next())

ListIterator是一个更加强大的Iterator的子类型,它只能用于各种List类的访问。可以双向移动。还可以产生相对于迭代器在列表中指向的当前位置
的前一个和后一个元素的索引,并且可以使用set()方法替换它访问过的最后一个元素。
可以通过listIterator()方法产生一个指向List开始处的ListIterator,并且可以通过调用listIterator(n)方法创建一个一开始就指向列表索引为n的
元素处的ListIterator.(n不是下标是位置)

 

LinkedList:

LinkedList也像ArrayList一样实现了基本的List接口,但它执行某些操作时比ArrayList更高效,在随机访问操作方面却要逊色一点。
LinkedList添加了可以使用其作为栈,队列或双端队列的方法。
getFirst()和element()完全一样,它们都返回列表的头,并不删除它,如果List为空,则抛出NoSuchElementException。peek()方法与这两个方法
稍有差异,它在列表为空时返回null
removeFirst()与remove()也是完全一样的,它们移除并返回列表的头,而在列表为空时抛出NoSuchElementException。poll()稍有差异,它在列表为空
时返回null
add()和addLast()相同,它们都将某个元素插入到列表的尾端
addFirst()插入列表头

 

Set:

Set不保存重复的元素。
Set最常被使用的是测试归属性,你可以很容易的询问某个对象是否在Set中。正因如此,查找成为了Set中最重要的操作,因此你通常会选择一个HashSet
的实现,它专门对快速查找进行了优化。
除了TreeSet之外的Set具有与Collection完全一样的接口,因此没有任何额外的功能。
HashSet所维护的顺序与TreeSet或LinkedHashSet都不同,因为它们的实现具有不同的元素存储方式。TreeSet将元素存储在红黑树数据结构中,而HashSet
使用的是散列函数。LinkedHashSet因为查询速度的原因也使用了散列,但是使用链表来维护元素的插入顺序。
可以向TreeSet构造函数传递比较器来自定义排序规则。
 

Map:

Map的特点就是拥有将对象映射到其他对象的能力。
containsKey()可以判断有无键,containsValue()可以判断有无值(底层调用equals())
添加元素:
put(Key,Value)如果没有键,插入键和值并返回空,如果原来存在键则返回旧的值
map可以返回它的键的Set值的Collection和键值对的Set(map.keySet();map.values();map.entrySet();)
entrySet产生一个由Map.Entry的元素构成的Set,并且这个Set是一个Iterable,因此可以用于foreach循环

 

Queue:

队列是一个典型的先进先出(FIFO)的容器。即从容器的一端放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。队列常被当做
一种可靠的将对象从程序的某个区域传输到另一个区域的途径。队列在并发编程中特别重要。
LinkedList提供了方法以支持队列的行为,并且它实现了Queue接口,因此LinkedList可以用作Queue的一种实现。
offer()方法将一个元素插入到队尾返回true,或者返回false(),peek()和element()都将在不移除的情况下返回队头,peek()在队列为空时返回null,而
element()会抛出NoSuchElementException异常。poll()和remove()方法将移除并返回队头,pool()在队列为空时返回null,而remove()会抛出
NoSuchElementException异常。
 

PriorityQueue:

优先级队列声明下一个弹出元素是最需要的元素(具有最高优先级)。
当你在PriorityQueue上调用offer()方法来插入一个对象时,这个对象会在队列中被排序(有的是在移出时选择最重要的元素)
默认的排序将使用对象在队列中的自然排序,可以通过提供自己的比较器给构造参数修改排序规则。
如果想在PriorityQueue()中使用自己的类就必须包括额外的功能以产生排序或者提供自己的Comparator。
Comparable接口对每个实现它的类的对象强加了排序规则。该排序称之为自然排序(natural ordering)。
方法public int compareTo(T o)是自然排序的排序方法。
Comparator接口

通过比较两个入参得到顺序。返回值有三种:

    1,入参一大于入参二。
    0,入参相同。
    -1,入参一小于入参二。
PriorityQueue可以确保当你调用peek(),poll(),remove()方法时,获取的元素将是队列中优先级最高的元素。
Collection和Iterator:
Collection是描述所有序列容器的共性的根接口,它可被认为是一个“附属接口”,即因为要表示其他若干个接口的共性而出现的接口。
AbstractCollection类提供了Collection的默认实现,使得你可以创建AbstractCollection的子类型,而其中没有不必要的代码重复。
使用接口的一个理由是它可以使我们能够创建更通用的代码。

Iterator也可以描述容器的共性,但java中它和Collection捆绑在了一起。

iterator()方法和Collection绑定在了一起,实现Collection就必须实现iterator()方法,即使继承AbstractCollection也必须实现iterator和size
方法。


Foreach与迭代器:

foreach循环可用于数组和任何Collection对象,任何实现了Iterable的类都能用foreach循环。
数组不是Iterable但可以用foreach循环,数组不会发生自动装箱拆箱。











 

猜你喜欢

转载自blog.csdn.net/yanshaoshuai/article/details/81061777