Java基础系列--09_集合2
昨天介绍了集合的主要架构体系,今天主要的目的是学习集合的迭代器的遍历和List的特有功能。
迭代器:
概述:由于多种集合的数据结构不同,所以存储方式不同,取出方式也不同。但是他们都是有判断和获取这两个行为,因而将迭代器抽象成一个接口。要想利用迭代器遍历集合,只要该集合内部实现这个接口即可。
以ArrayList集合为例的源码解析:
1 public interface Iterator{ 2 public abstract boolean hasNext(); 3 public abstract Object next(); 4 public abstract void remove(); 5 } 6 7 public interface Collection{ 8 //查看源码发现各种方法都没有实现,找他的下一级子类 9 public abstract Iterator iterator(); 10 } 11 12 public interface List extends Collection{ 13 //各种方法都没有实现,找他的下一级子类 14 ... 15 } 16 17 public class ArrayList implements List{ 18 //各种方法都得到了实现 19 ... 20 21 public Iterator iterator(){ 22 return new Itr(); 23 } 24 25 private class Itr implements Iterator{
26 //size是ArrayList的元素个数 27 int cursor; // 返回下一个元素的索引 28 public boolean hasNext(){return cursor != size;} 29 public Object next(){...} 30 } 31 }
迭代器的并发修改异常:
1 // 创建集合对象
2 List list = new ArrayList();
3 // 添加元素
4 list.add("hello");
5 list.add("world");
6 list.add("java");
7 //创建集合的迭代器
8 Iterator it = list.iterator();
9 //使用迭代器判断是否存在下一个元素
10 while (it.hasNext()) {
11 String s = (String) it.next();
12 //如果存在"hello"这个字符串就增加一个"helloWorld"字符串
13 if ("hello".equals(s)) {
14 //通过集合去添加元素
15 list.add("helloWorld");
16 }
17 }
在这里报了一个java.util.ConcurrentModificationException异常
发生异常的原因:当我们在使用迭代器遍历集合,而迭代器的hasNext()就像一个游标一样会一次一次的往下一个元素移动。而当我们通过集合去添加新元素时,迭代器并不知道我们添加了新元素。所以就会报出并发修改异常。用一句话概述就是“用迭代器遍历集合,用集合去操作集合”。
解决方案:从并发修改异常产生的原因去看,有两个解决方案
方案一:使用迭代器遍历集合,使用迭代器修改集合(但是不建议)
方案二:使用for循环去遍历集合,并使用集合本身修改集合
1 // 完全通过集合实现
2 // for (int x = 0; x < list.size(); x++) {
3 // String s = (String) list.get(x);
4 // if ("hello".equals(s)) {
5 // list.add("IOS");
6 // }
7 // }
8 // System.out.println("list:"+list);
9 // System.out.println("-----------");
10
11 // 完全通过迭代器遍历并修改集合,ListIterator是Iterator的子类
12 ListIterator lit = list.listIterator();
13 while (lit.hasNext()) {
14 String s = (String) lit.next();
15 if ("hello".equals(s)) {
16 lit.add("IOS");
17 }
18 }
19 System.out.println("list:" + list);
List
前面已经说过List的特点:1.有序(存储和取出的顺序一致);2.可以重复;3.可以通过索引值操作对应位置的元素
List的特有功能
1 1、添加功能
2 void add(int index,Object obj): 在列表的指定位置插入指定元素
3 2、删除功能
4 Object remove(int index): 移除列表中指定位置的元素
5 3、修改功能
6 Object set(int index,Object obj): 用指定元素替换列表中指定位置的元素
7 4、获取功能
8 Object get(int index): 返回列表中指定位置的元素。
9 int indexOf(Object obj): 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
10 ListIterator listIterator():返回按适当顺序在列表的元素上进行迭代的迭代器。
11 5、截取功能
12 List subList(int fromIndex, int toIndex):截取集合。
List的三个常用子类
ArrayList:底层的数据结构是数组,查询速度块,增删慢;线程不安全,效率高。
Vector: 底层数据结构是数组,查询速度快,增删慢;线程安全,效率低。
LinkedList:底层数据结构是链表,查询速度慢,增删快;线程不安全,效率高。
一般来说我们也需要根据自己的需求来重写equals方法,重写的主要分为三个步骤
1. 判断是否为同一个对象
2.判断是否为该的对象
3.向下转型,然后根据需求比较成员变量