1.数组的尺寸是有限制的,而容器没有
- 数组是具有固定尺寸的。
- 而容器是没有固定尺寸的,你可以把任意数量的对象放置在容器中,并且不需要指定容器的大小。
2.容器应配合泛型来使用
- 通过给容器规定泛型,使该容器只能添加该泛型类型的对象。
- 容器也接收可以向上转型为泛型类型的对象。
ArrayList<Apple> list = new ArrayList<>(); //只能存储Apple类型的对象
3.当不需要索引时,可以使用foreach语法来遍历容器(演示遍历List容器)
for(Apple a : list) {
System.out.println(a);
}
4.Java容器类库的两个不同概念:Collection与Map
- Collection:一个独立元素的序列,这些元素都服从一条或多条规则。
- Map:一组成对的“键值对”对象,允许你使用键来查找值。
- Collection中的ArrayList可以通过get(索引)来使用数字来值。而Map是用对象来查找另一个对象。
5.创建容器时,应该先创建一个具体类型的对象再转型为对应的接口
List<Apple> list1 = new ArrayList<>();
List<Apple> list2 = new LinkList<>();
Map<Integer, Aplple> map = new TreeMap<>();
但是要注意,LinkList
具有在List
中没有的方法,TreeMap
拥有在Map
中没有的方法,如果你要使用这些方法,就不要去向上转型为容器接口。
6.使用java.util包下的Arrays类或Collections类中的方法来添加一组元素
Arrays.asList()
接受一个数组或是一个用逗号分隔开的元素列表(使用了可变参数),然后将它们转换为一个List对象,也就是实现了new一个List对象的操作,所以可以将Arrays.asList()的返回结果赋值给容器接口实现初始化。- 可在asList前面插入<>“显式类型参数说明”来告诉编译器实际产生的List类型是什么(当有继承时会比较好用)。
List<Integer> list = Arrays.asList(1,2,3,4,5);
List<Integer> list = Arrays.<Integer>asList(1,2,3,4,5);
Collections.addAll()
接受两个参数,第一个参数是Collection对象,第二个参数是一个数组或用逗号分隔开的元素列表,作用是将元素添加到Collection容器的末尾中。
List<Integer> list = Arrays.asList(1,2,3,4,5);
Collections.addAll(list, 6,7,8,9,10);
7.迭代器
迭代器统一了对容器的访问方式:它能够将容器底层的结构与对容器进行遍历的操作分离,从而达到忽略容器的各种不同类型来进行遍历是可行的。
7.1 Iterator迭代器
Iterator迭代器只能单向移动
iterator()
返回一个Iterator迭代器对象,该对象准备好返回容器的第一个元素。next()
返回当前索引指向的元素,然后索引向前移动。hasNext()
判断容器中是否还有元素。remove()
将next()最新获得到的元素删除。
List<String> list = new ArrayList<>();
Iterator<String> it = list.iterator(); //使用iterator返回Iterator迭代器
it.next();
it.remove(); //需要注意的是,remove()必须要在next()使用之后再使用
7.2 ListIterator迭代器
ListIterator迭代器是只用于List类型的迭代器,它比Iterator迭代器更丰富:它可以双向移动。
listIterator()
返回一个ListIterator迭代器对象,该对象准备好返回容器的第一个元素。listIterator(Index)
返回一个所传参数索引为初始索引的ListIterator。next()
返回当前索引指向的元素,然后索引向前移动。hasNext()
判断容器中是否还有元素。remove()
将next()最新获得到的元素删除。nextIndex()
返回当前索引的前一个索引。previousIndex()
返回当前索引的下一个索引。set()
将next()最新获得的元素进行替换。
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("W");
list.add("R");
list.add("J");
ListIterator<String> it = list.listIterator();
System.out.println(it.previousIndex());
System.out.println(it.next());
System.out.println(it.nextIndex());
System.out.println("---------------");
System.out.println(it.next());
System.out.println(it.previousIndex());
System.out.println(it.nextIndex());
}
}
/* Output:
* -1
* W
* 1
* ---------------
* R
* 1
* 2
*/
8.List:ArrayList和LinkedList
- ArrayList:随机访问元素较快,但是在中间插入和删除操作时较慢。
- LinkedList:随机访问元素较慢,但是在中间插入和删除操作时较快;并提供了优化的顺序访问。
8.1 List的3个共用方法
add()
为List容器添加对象。get(index)
获取List容器指定索引的对象。size()
获取List容器所存对象的个数。
8.2 ArrayList的一些方法
contains()
确定所传入参数是否在容器中。remove()
根据传入的参数,移除容器中的某个元素。indexOf()
根据传入的参数,获取该参数在容器中的索引。
注意:当涉及确定某个元素是否在容器中、发现某个元素的索引、移除某个元素时,都依赖于Object类的equals()方法。所以以上3个方法都依赖于equals()
方法
subList(index, index)
获得索引之间的容器片段。containsAll()
传入一个容器片段,判断是否在容器中。removeAll()
移除传入的容器片段。retainAll()
有效的“交集”操作,保留调用此方法的容器与作为参数传入的容器的相同元素。addAll(index, someList)
可以将容器片段插入到List的中间(第一个参数索引位置之后);也可以不用索引参数,直接将someList添加到容器的末尾,这与Collections的addAll()方法的效果一样。set(index, oneList)
将index位置的元素替换成arg。clear()
清除容器中的元素。isEmpty()
判断容器是否为空。toArray()
返回Object类型的数组;若传入参数,则返回参数类型的数组。
8.3 LinkedList的一些方法
LinkedList方法和ArrayList方法大致相同,只是LinklList往中间插入和删除元素时更高效;
不过LinkedList提供其特有的(所以要以LinkedList为引用类型才可以用下面的方法而不是List)使其用作栈、队列或双端队列的方法:
getFirst()
返回列表的第一个元素而不移除它。getLast()
返回列表的最后一个元素而移除它。removeFirst()
返回列表的第一个元素并移除它。removeLast()
返回列表的最后一个元素并移除它。addFirst()
将元素插入到列表头。addLast()
将元素插入到列表尾。
9.Set
- HashSet:提供最快的查询速度;使用了散列函数进行存储;乱序。
- LinkedHashSet:也使用了散列,但是看起来它使用了链表来维护元素的插入顺序。
- TreeSet:按照某种顺序保持元素处于排序状态;元素存储在红-黑树中。
10.Map
- HashMap:设计用来快速访问,但是会打乱元素的插入顺序。
- LinkedHashMap:保持元素的插入顺序,但也通过散列提供了快速访问的能力。
- TreeMap:保持“键”始终处于排序状态,所以访问速度没有HashMap快。
put()
放入键和值。get()
根据键获取值。containsKey()
是否有某个键。contaninsValue()
是否有某个值。keySet()
返回键的Set集合。
11.Queue
队列是一个典型的先进先出的容器。
因为LinkedList提供了方法以支持队列的行为,并且LinkedList实现了Queue接口,因此可以将LinkedList用作Queue的一种实现,new一个LinkedList然后向上转型位为Queue。
Queue<String> queue = new LinkedList<>();
offer()
将一个元素插入到队尾。peek()
返回对头并且不移除对头;为空时返回null。element()
返回队头并且不移除队头;为空时抛出NoSuchElementExcption。poll()
返回队头并移除队头;为空时返回null。remove()
返回队头并移除队头;为空时抛出NoSuchElementExcption异常。
12.总结
- 容器不能持有基本类型,只能持有对象,但是自动包装机制会仔细地执行基本类型到容器中所持有的包装器类型之间的双向转换。
- List也像数组一样可以用数字索引和对象相关联,数组和List都是排好序的容器,只是List能够自动扩充容量。
- 如果要进行大量的随机访问,就使用ArrayList;如果要经常从表中插入或删除元素,就使用LinkedList。
- 各种Queue以及栈的行为,由LinkedList提供。
- Collection与List、Set、Queue和Map的联系:
- List和Collection存在着明显的不同,尽管List所要求的方法都保存在Collection中。
- 除了TreeSet之外的所有Set都拥有与Collection完全一样的接口。
- Queue接口的方法都是独立的;在创建具有Queue功能的实现时,不需要使用Collection方法。
- Map和Collection之间的唯一重叠就是Map可以使用entrySet()和values()方法来产生Collection。