集合框架
为什么会出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
数组和集合类同是容器,有何不同?
数组虽然可以存储对象,但长度是固定的,而集合的长度是可变的(自动扩容)。
数组中也可以存储基本数据类型,但是集合中只能存储对象。
集合类的特点
集合只用于存储对象,集合长度是可变的(自动扩容)。集合可以存储不同类型的对象。
Collection
|-------List:元素是有序的,元素可以重复,因为该集合体系有索引。
|------ArrayList:底层的数组结构使用的是数组结构。特点:查询速度快,但是增删稍慢,线程不同步。
|------LinkedList:底层使用的链表结构。特点:增删速度快,查询慢。
|------Vector:底层是数组结构,线程同步,被ArrayList替代了。
|-------Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
|-------HashSet:底层数据结构是哈希表.线程是非同步的
保证元素唯一性的原理,判断元素的hashCode值是否相同
如果相同还会继续判断元素的equals方法,是否为true
|-------TreeSet:可以对Set集合中的元素进行排序
底层数据结构是二叉树
保证元素唯一性的依据:compareTo方法return 0
Collection接口的共性方法
@Test
public void testCollection(){
//由于Collection是接口,使用ArrayList具体实现类
Collection<String> collection1 = new ArrayList<String>();
collection1.add("java01");
collection1.add("java02");
collection1.add("java03");
collection1.add("java04");
Collection<String> collection2 = new ArrayList<String>();
collection2.add("java01");
collection2.add("java02");
collection2.add("java07");
collection2.add("java08");
//size()
System.out.println("=== >size() : " + collection1.size());
//isEmpty()
System.out.println("=== >isEmpty() : " + collection1.isEmpty());
//contains(Object)
System.out.println("=== >contains(Object) : " + collection1.contains("java02"));
//add(E)
System.out.println("=== >add(E) : " + collection1.add("java04"));
//remove(Object);
System.out.println("=== >remove(Object) : " + collection1.remove("java05"));
//containsAll(Collection<?>)
System.out.println("=== >containsAll(Collection<?>) : " + collection1.containsAll(collection2));
//addAll(Collection<? extends E>)
System.out.println("=== >addAll(Collection<? extends E>) : " + collection1.addAll(collection2));
//removeAll(Collection<?>)
System.out.println("=== >removeAll(Collection<?>) : " + collection1.removeAll(collection2));
//retainAll(Collection<?>)
System.out.println("=== >retainAll(Collection<?> : " + collection1.retainAll(collection2));
//clear()清空集合
//-----------------------------------------------------------------------------//
// 输出结果
// === >size() : 4
// === >isEmpty() : false
// === >contains(Object) : true
// === >add(E) : true
// === >remove(Object) : false
// === >containsAll(Collection<?>) : false
// === >addAll(Collection<? extends E>) : true
// === >removeAll(Collection<?>) : true
// === >retainAll(Collection<?> : true
}
注意:
add方法的参数类型是Object,以便接收任意类型对象
集合中存储的都是对象的引用
迭代器Iterator
什么是迭代器?其实就是集合取出元素的方式
@Test
public void testCollectionIterator(){
//由于Collection是接口,使用ArrayList具体实现类
Collection<String> collection1 = new ArrayList<String>();
collection1.add("java01");
collection1.add("java02");
collection1.add("java03");
collection1.add("java04");
collection1.add("java05");
collection1.add("java06");
//获取迭代器
Iterator<String> iterator = collection1.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
但是,需要注意的是使用迭代器进行迭代集合中的元素时,不可以使用集合操作元素的方式进行对集合元素的操作,否则会抛出java.util.ConcurrentModificationException异常这是因为:Iterator是工作在一个独立的线程中的,并且拥有一个mutex锁。Iterator被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

@Test
public void testCollectionIterator(){
//由于Collection是接口,使用ArrayList具体实现类
Collection<String> collection1 = new ArrayList<String>();
collection1.add("java01");
collection1.add("java02");
collection1.add("java03");
collection1.add("java04");
collection1.add("java05");
collection1.add("java06");
//获取迭代器
Iterator<String> iterator = collection1.iterator();
while (iterator.hasNext()) {
String temp = iterator.next();
System.out.println(temp);
if ("java01".equals(temp)) {
collection1.remove("java01");
}
}
}