持有对象
11.1 泛型和类型安全的容器
使用泛型时,可以检查放入对象的类型,在使用对象时可以有更清晰的语法。
通过使用泛型,可以在编译期防止将错误类型对象放到容器中。
11.2 基本概念
Java容器类库的用途是保存"对象",并将其划分为两个不同概念:
- Collection。一个独立元素的序列,这些元素都服从一条或多条规则,List必须按照插入的顺序保存元素,而Set不能有重复元素,Queue按照排队规则来确定对象产生的顺序。
- Map。一组成对的键值对对象,允许使用键值对来查找值,ArrayList允许你使用数字来查找值,因此在某种意义上讲,它将数字与对象关联在了一起,映射表允许我们使用另一个对象来查找某个对象,它也被成为关联数组。
11.3 添加元素
Collection构造器可以接受另一个Collection,用它来将自身初始化,因此你可以使用Arrays.List()来为这个构造器产生输入,但是Collection.addAll()方法运行起来要快得多,而且一个不包含元素的Collection,然后调用Collection.addAll()这种方式更方便,因此它是首选。Collection.addAll()成员方法只能接收另一个Collection对象作为参数,因此它不如Arra.asList()或Collections.addAll()灵活,这两个方式使用的都是可变参数列表。
public class AddingGroups {
public static void main(String[] args) {
Collection<Integer> c = new ArrayList<Integer>(
Arrays.asList(1,2,3,4,5));
Integer[] moreInts = {6,7,8,9,10};
c.addAll(Arrays.asList(moreInts));//添加list
Collections.addAll(c, 11,12,13,14,15);
Collections.addAll(c, moreInts); //添加一个集合
List<Integer> list = Arrays.asList(16,17,18,19,20); //数组或元素转化为list
list.set(1, 99);
System.out.println(list);
}
}
11.4 容器的打印
Java容器类中两种主要类型区别在于容器中每个“槽”中保存的元素个数。
Collection 在每个槽中只能保存一个元素。其中包括:
List:它以特定的顺序保存一组元素(ArrayList,LinkedList)
Set:元素不能重复。(HashSet,TreeSet,LinkedHashSet)
Queue:只允许一端进去,另一端取出。
Map在每个槽内保存了两个对象,即键和与之相关的值。
HashMap:可以快速查找
TreeMap:按照比较结果的升序保存键。
LinkedhashMap:按照插入顺序保存键,还具有hashmap的查询速度。
11.5 List
有两种类型的List:
- ArrayList ,基本的ArrayList,它长于随机访问元素,但是在List的中间插入和移除元素时比较慢。
- LinkedList 它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序访问,在随机访问方面相对比较慢,但是它的特性集较ArrayList更大。
retainAll():取交集
11.6 迭代器
迭代器的作用是:遍历并选择对象,Java 的Iterator只能单向移动,这个Iterator只能用来:
1)iterator()方法返回一个Iterator。
2)使用next()获取序列中的下一个元素。
3)使用hasNext()检查序列中是否还有元素。
4)使用remove()将新近返回的元素移除。
ListIterator是Iterator的子类型,它只适用于List的访问。ListIterator可以双向移动。
11.7 Linklist
getFirst()和element():返回第一个元素。list为空抛出异常
peek():返回第一个元素。list为空返回null
remove()和removeFirst():移除并返回列表的头。list为空抛出异常
poll():移除并返回列表的头。list为空返回null
addFirst()、add()、offer()、addLast():将某个元素插入到头(尾)部。
11.8 Stack
栈通常指后进先出的容器。
pop():返回并移除栈顶元素。
peek():返回栈顶元素,不移除。
11.9 Set
Set不保存重复元素。
HashSet使用了散列函数,TreeSet使用红-黑树结构。
11.10 Map
containsKey(key):查找是否包含某个键
containsValue(value):查找是否包含某个值。
11.11 Queue
队列是典型的先进先出容器。队列在并发编程中很重要那天,因为它可以安全地将对象从一个任务传输给另一个任务。
offer():在允许的情况下,将元素插入到队尾,或者返回false。
peek()和element():在不移除情况下返回队头。
remove()和poll():移除并返回队头。
- PriorityQueue
优先级队列。下一个弹出的元素是最需要的元素(最高优先级)。可以通过提供自己的Comparator修改排序规则。
11.12 Collection和Iterator
Collection是描述所有序列容器的共性接口。
AbstractCollection提供了Collection的默认实现。可以通过继承AbstractCollection避免重复代码。
生成Iterator是将队列与消费队列的方法连接在一起耦合度最小的方式,并且与实现Collection相比,在序列上施加的约束也比较少。
/**
* 生成Iterator获取迭代能力
* @author Administrator
*
*/
class PetSequence{
protected Pet[] pets = Pets.createArray(8);
}
public class NoCollectionSequence extends PetSequence {
public Iterator<Pet> iterator() {
return new Iterator<Pet>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < pets.length;
}
@Override
public Pet next() {
return pets[index++];
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static void main(String[] args) {
NoCollectionSequence nc = new NoCollectionSequence();
InterfaceVsIterator.display(nc.iterator());
}
}
11.13 Foreach与迭代器
foreach语法主要用于数组,但是它也可以应用于任何Collection对象。
适配器方法:提供特定的接口满足foreach语句,可以添加一个产生Iterable对象的方法。
11.14 总结
Java提供了大量持有对象的方式:
- 数组将数字与对象联系起来。
- Collection保存单一的元素,而Map保存相关联的键值对。
- List也建立数字索引与对象的关联。
- 如果要进行大量随机访问,就使用ArrayList,如果经常从中间插入或删除元素,则应该使用LinkedList。
- 各种Queue以及栈行为,由LinkedList支持。
- Map是一种将对象与对象相关联的设计。HashMap用来快速访问,TreeMap保持“键”始终处于排序状态。
- Set不接受重复元素。HashSet提供最快查询速度,TreeSet保持元素处于排序状态。LinkedSet以插入顺序保存元素。
- 新程序中不应使用过时的Vector,HashTable和Stack