Java学习笔记(十六):Collection集合及子类接口List
Collection集合
一、概念
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类。
二、数组和集合的区别
- 长度区别:
数组的长度是固定的而集合的长度是可变的; - 存储数据类型的区别:
数组可以存储基本数据类型 , 也可以存储引用数据类型; 而集合只能存储引用数据类型,但是根据自动拆装箱规则,此条件并不能算作是集合的弊端。 - 内容区别:
数组只能存储同种数据类型的元素 ,集合可以存储不同引用类型的元素;
三、功能概述
-
添加功能
//添加一个元素,传入的参数可以是任何类型的数据,返回值为是否添加成功。 boolean add(Object obj); boolean add(Object 100); //自动装箱 //添加一个集合的元素 (给一个集合添加进另一个集合中的所有元素) boolean addAll(Collection c);
-
删除功能
//移除所有元素 void clear() //移除一个元素 boolean remove(Object o) //移除一个集合的元素(移除一个以上返回的就是true) 删除的元素是两个集合的交集元素,如果没有交集元素 则删除失败 返回false boolean removeAll(Collection c); //删除a集合中a和b的交集元素,b集合中元素不变 a.removeAll(Collection b);
-
判断功能
//判断集合中是否包含指定的元素 boolean contains(Object o) //判断集合中是否包含指定的集合元素(这个集合 包含 另一个集合中所有的元素才算包含 才返回true) boolean containsAll(Collection c) //比如:1,2,3 containsAll 1,2=true // 1, 2,3 containsAll 2,3,4=false //判断集合是否为空 boolean isEmpty()
-
遍历功能
//使用以下方法得到一个迭代器 Iterator<E> iterator(); //遍历输出迭代器的结果 Collection collection = new ArrayList(); Iterator iterator = collection.iterator(); while(iterator.hasNext()){ //判断有没有下一个元素可以迭代 Object next = iterator.next; //要打印其他类型的数据需要向下转型 Integer num = (Integer) next; sout(num); } //长度功能,得到元素的个数 int size();
-
交集功能
//例如:A集合对B集合取交集,获取到的交集元素在A集合中,如果没有交集元素那么A集合会被清空。返回的布尔值表示的是A集合是否发生变化 boolean retainAll(Collection c)
-
把集合转换为数组
Object[] toArray(); //实现时可以创建一个Object类型的数组 Object[] arr = list.toSSrray();
List接口
一、特点
元素存取的顺序是一致的,并且每一个元素都存在一个索引,元素可以重复。
二、特有功能
- 在指定索引处添加元素
void add(int index,E element);
- 移除指定索引处的元素。返回的是移除的元素
E remove(int index);
假如集合中存储的是Integer类型的数据,此时如果要根据元素而不是索引删除元素(父类remove方法的功能),可以先手动包装一下来区分。
List list = new ArrayList();
list.add(100);
list.add(200);
list.add(300);
list.remove(Integer.valueOf(300));
- 获取指定索引处的元素
E get(int index);
此后可以通过for循环来遍历List集合。如:
List list = new ArrayList();
list.add(100);
list.add(200);
list.add(300);
for(int i = 0;i < list.size(); i++){
Object obj = list.get(i);
sout(obj);
}
- 更改指定索引处的元素 返回的而是被替换的旧元素
set(int index,E element);
-
List的特有迭代器ListIterator
ListIterator 继承自Iterator ,可以使用Iterator中的方法。调用方法与其父类一致。
特有功能:
-
是否存在前一个元素
boolean hasPrevious();
-
返回列表中的前一个元素
E previous();
-
以上两个方法可以实现反向遍历,但是注意**要完成反向遍历之前,要先进行正向遍历 **,这样指针才能移到最后。
如果直接反向遍历是没有效果的,因为指针默认位置就在最前面 他前面没有元素。
- 返回第一次出现的索引
int index of(Object obj);
- 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分元素到一个新的集合中
E subList(int fromIndex, int toIndex)
三、并发修改异常(ConcurrentModificationException)
当使用迭代器检测集合中某一个元素时,发现该元素后,当我们想压要再添加元素时,编译代码后发现编译器报错ConcurrentModificationException。
List list = new ArrayList();
list.add("Hello");
list.add("World");
ListIterator listIterator = list.listIterator();
while(listIterator.hasNext()){
String ele = (String)listIterator.Next();
if("World".eqauls(ele)){
list.add("Java");
}
}
原因是我们的迭代依赖与集合,当我们往集合中添加好了元素之后获取迭代器 ,此时迭代器已经知道了集合的元素个数。
这个时候在遍历的时候又临时想给集合里面加一个元素(用的是集合的add方法),此时迭代顺序就被打乱了,这样就会报错。
解决方法:
用迭代器自带的add方法添加元素,那就不会报错了。
while(listIterator.hasNext()){
String ele = (String)listIterator.Next();
if("World".eqauls(ele)){
listIterator.add("Java");
}
}
当然也可以不使用迭代器,改用for循环也可以解决问题。
List的三个子类
特点:
- ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。 - Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。 - LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。