Fork me on GitHub

第16章 List集合的总结和遍历

第16章 List集合的总结和遍历

1.重构设计

根据Vector类,ArrayList类,和LinkedList类所具有的存储特点以及拥有的方法入手,发现共性往上抽取。
共同特点:
1.允许元素重复
2.会记录先后添加的顺序po

根据他们的特点,我们可以指定规范:
遵循该规范的实现类,无论底层算法如何,都必须保证允许元素重复和保证添加先后顺序,我们给该规范起名字:List
在java中规范我们使用接口来表示。即List接口
List接口:
1.元素允许重复
2.记录添加顺序

实现接口的三个类
LinkedList类:
实现:栈,单向队列,双向队列,双向链表
Vector类
数组结构
ArrayList类
数组结构
List实现类特点和性能分析:
三种共同特点:上面两点
不同点
Vector:底层采用数组方法结构算法,方法都使用了synchronized修饰,线程安全,但是性能相对于ArrayList较低。
ArrayList:底层采用数组结构算法,方法没有使用synchronized修饰,线程部安全,性能相对于Vector较高。
ArrayList现在已经取代了Vector的江湖地位,建议以后不要使用Vector,直接使用ArrayList。
为了保证ArrayList的线程安全,LinkedList list = Collections.synchronizedList(new ArrayList(……));
LinkedList:底层采用双向链表数据结构算法,方法没有使用synchroized修饰,线程部安全
数据结构算法和双向链表结构算法的性能问题:
数据结构算法:插入和删除算法速度低,查询和更改较快
链表结构算法:插入和删除操作速度快,查询和更改较慢
使用的选择:
Vector类打死不用!即使要用选ArrayList类
如果删除和插入操作频繁,应该选择LinkedList类
如果查询操作频繁,应该使用ArrayList类
在实际开发中使用ArrayList较多,具体根据需求环境来确定

面向接口编程:
接口类型 变量 = new 实现类();
List list = new ArrayList();

2.集合的迭代操作

集合都是可以迭代的,具体操作方法有四种:
集合的迭代
把集合中的元素一个一个的遍历取出来
遍历的四种遍历方法
for方法
for-each方法
Iterator方法
Enumeration方法
迭代器对象
Iterator:迭代器对象,只能从上往下迭代
boolea hasNext():判断当前指针后是否有下一个元素
Object next():获取指针的下一个元素,并且移动指针
LisIterator:是Iterator接口的子接口,支持双向迭代,从上往下迭代,从下往上迭代
Enumeration():古老的迭代器对象,现在已经被Iterator取代了,适用于古老的Vector类

import java.util.*;

/**
 * 测试遍历集合的四种方法
 */
public class TestIterator {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");

        //方式1:for循环
        for (int index = 0; index < list.size(); index++){
            Object ele = list.get(index);//取出指定索引位置的元素
//            System.out.println(ele);//A  B  C  D
        }


        //方法2:for-each增强循环
        //语法:
        /*
        for(类型 变量 : 数组名/Iterable的实例){
            //TODO
        }
         */
        for (Object ele : list){
//            System.out.println(ele);//A  B  C  D
        }

        //方法3.1使用迭代器while方法
        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());//A  B  C  D
        }

        //方法3.2使用迭代器for方法
        //注意for中的语法,两个分好,两个语句
        for (Iterator it2 = list.iterator(); it2.hasNext();){
            System.out.println(it2.next());//A  B  C  D
        }

        //方法4.枚举法:古老的迭代对象
        Vector v = new Vector();
        v.add("A");
        v.add("B");
        v.add("C");
        v.add("D");
        Enumeration en = v.elements();
        while (en.hasMoreElements()){
            Object ele = en.nextElement();
            System.out.println(ele);//A  B  C  D
        }

    }
}

深入分析for-each和迭代器
1.for-each可以操作数组,底层依然采用for循环+索引来获取数组元素
2.for-each可以操作Iterable实例:底层其实采用的是Iterator

迭代的同时删除元素
在迭代集合的时候,边迭代边删除,是非常常用的操作:
当迭代到指定元素时,不能使用集合对象的remove()删除方法,这样会报并发修改异常,
在Collection接口中存在删除指定元素的方法,boolean remove(Object ele);但是该方法只能从集合中删除元素,不能把迭代器中指定的元素也删除

正确的方法
应该使用Iterator中的remove()方法
该方法会从两个线程中同时移除被删除的元素,保证了两个线程的同步

posted @ 2016-12-09 15:41  洋葱源码  阅读(360)  评论(0编辑  收藏  举报