No_16_0310 Java基础学习第十五天

文档版本 开发工具 测试平台 工程名字 日期 作者 备注
V1.0 2016.03.10 lutianfei none

[TOC]


第八章-集合

No_16_0310 Java基础学习第十五天_第1张图片
类型 Java数组 ArrayList LinkedList Vector
随机访问(get) 16 23 63 31
迭代操作(iterator) 31 47 33 48
插入操作(inert) 不适用 1610 31 1625
删除操作(remove) 不适用 6625 16 6750

1、对Java数组进行随机访问和迭代操作具有最快的速度
2、对LinkedList进行插入和删除操作具有较快的速度
3、对ArrayList进行随机访问具有较快的速度
4、Vector没有突出的性能,已不提倡使用

集合类概述

  • 为什么出现集合类?

    • 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类
    • 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储。而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识里面,有哪些是容器类型的呢?数组StringBuffer。但是StringBuffer的结果是一个字符串,不一定满足我们的要求,所以我们只能选择数组,这就是对象数组。而对象数组又不能适应变化的需求,因为数组的长度是固定的,这个时候,为了适应变化的需求,Java就提供了集合类供我们使用。
  • 数组和集合类同是容器,有何不同?

    • A:长度区别
      • 数组: 的长度固定
      • 集合: 长度可变
    • B:内容不同
      • 数组: 存储的是同一种类型的元素
      • 而集合: 可以存储不同类型的元素
    • C:元素的数据类型问题
      • 数组可以存储基本数据类型,也可以存储引用数据类型
      • 集合只能存储引用类型
  • 集合类的特点

    • 集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。


Collection接口概述

  • Collection 层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。

Collection的功能概述:

1:添加功能
  • boolean add(Object obj):添加一个元素
  • boolean addAll(Collection c):添加一个集合的元素
2:删除功能
  • void clear():移除所有元素
  • boolean remove(Object o):移除一个元素
  • boolean removeAll(Collection c):移除一个集合的元素(是一个还是所有)
3:判断功能
  • boolean contains(Object o):判断集合中是否包含指定的元素
  • boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)
  • boolean isEmpty():判断集合是否为空
4:获取功能
  • Iterator iterator():迭代器,集合的专用遍历方式
5:长度功能
  • int size():元素的个数
  • 面试题:数组有没有length()方法呢?字符串有没有length()方法呢?集合有没有length()方法呢?
    • 数组没有
    • 字符串有
    • 集合没有,是size()函数
6:交集功能
  • boolean retainAll(Collection c):两个集合都有的元素
    • 思考元素去哪了,返回的boolean又是什么意思呢?
7:把集合转换为数组
  • Object[] toArray():把集合转成数组,可以实现集合的遍历
public class CollectionDemo3 {
    public static void main(String[] args) {
        // 创建集合对象
        Collection c = new ArrayList();

        // 添加元素
        c.add("hello"); // Object obj = "hello"; 向上转型
        c.add("world");
        c.add("java");

        // 遍历
        // Object[] toArray():把集合转成数组,可以实现集合的遍历
        Object[] objs = c.toArray();
        for (int x = 0; x < objs.length; x++) {
            // System.out.println(objs[x]);
            // 我知道元素是字符串,我在获取到元素的的同时,还想知道元素的长度。
            // System.out.println(objs[x] + "---" + objs[x].length());
            // 上面的实现不了,原因是Object中没有length()方法
            // 我们要想使用字符串的方法,就必须把元素还原成字符串
            // 向下转型
            String s = (String) objs[x];
            System.out.println(s + "---" + s.length());
        }
    }
}

/*
hello---5
world---5
java---4
*/
  • 练习:
/*
 * 练习:用集合存储5个学生对象,并把学生对象进行遍历。
 * 
 * 分析:
 * A:创建学生类
 * B:创建集合对象
 * C:创建学生对象
 * D:把学生添加到集合
 * E:把集合转成数组
 * F:遍历数组
 */
public class StudentDemo {
    public static void main(String[] args) {
        // 创建集合对象
        Collection c = new ArrayList();

        // 创建学生对象
        Student s1 = new Student("林青霞", 27);
        Student s2 = new Student("风清扬", 30);
        Student s3 = new Student("令狐冲", 33);
        Student s4 = new Student("武鑫", 25);
        Student s5 = new Student("刘晓曲", 22);

        // 把学生添加到集合
        c.add(s1);
        c.add(s2);
        c.add(s3);
        c.add(s4);
        c.add(s5);

        // 把集合转成数组
        Object[] objs = c.toArray();
        // 遍历数组
        for (int x = 0; x < objs.length; x++) {
            // System.out.println(objs[x]);

            Student s = (Student) objs[x];
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}

Collection接口成员方法练习

  • Eg1:
public class CollectionDemo {
    public static void main(String[] args) {
        // 创建集合对象
        // Collection c = new Collection(); //错误,因为接口不能实例化
        
        Collection c = new ArrayList();
        // boolean add(Object obj):添加一个元素
        // System.out.println("add:"+c.add("hello"));
        c.add("hello");
        c.add("world");
        c.add("java");

        // void clear():移除所有元素
        // c.clear();

        // boolean remove(Object o):移除一个元素
         //System.out.println("remove:" + c.remove("hello"));
         //System.out.println("remove:" + c.remove("javaee"));

        // boolean contains(Object o):判断集合中是否包含指定的元素
        // System.out.println("contains:"+c.contains("hello"));
        // System.out.println("contains:"+c.contains("android"));

        // boolean isEmpty():判断集合是否为空
        // System.out.println("isEmpty:"+c.isEmpty());

        //int size():元素的个数
        System.out.println("size:"+c.size());
        
        System.out.println("c:" + c);
    }
}

  • Eg2:
public class CollectionDemo2 {
    public static void main(String[] args) {
        // 创建集合1
        Collection c1 = new ArrayList();
        c1.add("abc1");
        c1.add("abc2");
        c1.add("abc3");
        c1.add("abc4");

        // 创建集合2
        Collection c2 = new ArrayList();
//        c2.add("abc1");
//        c2.add("abc2");
//        c2.add("abc3");
//        c2.add("abc4");
        c2.add("abc5");
        c2.add("abc6");
        c2.add("abc7");

        // boolean addAll(Collection c):添加一个集合的元素
        // System.out.println("addAll:" + c1.addAll(c2));
        
        //boolean removeAll(Collection c):移除一个集合的元素(是一个还是所有)
        //只要有一个元素被移除了,就返回true。一出的是c1,c2共有的对象元素。
        //System.out.println("removeAll:"+c1.removeAll(c2));

        //boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)
        //只有包含所有的元素,才叫包含
        // System.out.println("containsAll:"+c1.containsAll(c2));
        
        //boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
        //假设有两个集合A,B。
        //A对B做交集,最终的结果保存在A中,B不变。
        //返回值表示的是A是否发生过改变。
        System.out.println("retainAll:"+c1.retainAll(c2));
        
        System.out.println("c1:" + c1);
        System.out.println("c2:" + c2);
    }
}

Iterator接口概述

  • 对 collection 进行迭代的迭代器,集合的专用遍历方式。
  • 依赖于集合而存在

Iterator接口成员方法

  • boolean hasNext()
  • Object next(): 获取元素
  • Eg:
/*
 * Iterator iterator():迭代器,集合的专用遍历方式
 *         Object next():获取元素,并移动到下一个位置。
 *             NoSuchElementException:没有这样的元素,因为你已经找到最后了。
 *         boolean hasNext():如果仍有元素可以迭代,则返回 true。(
 */
public class IteratorDemo {
    public static void main(String[] args) {
        // 创建集合对象
        Collection c = new ArrayList();

        // 创建并添加元素
        // String s = "hello";
        // c.add(s);
        c.add("hello");
        c.add("world");
        c.add("java");

        // Iterator iterator():迭代器,集合的专用遍历方式
        Iterator it = c.iterator(); // 实际返回的肯定是子类对象,这里是多态

        while (it.hasNext()) {
            // System.out.println(it.next());
            String s = (String) it.next();
            System.out.println(s);
        }
    }
}
  • Eg:
/*
 * 问题1:能用while循环写这个程序,我能不能用for循环呢?
 * 问题2:不要多次使用it.next()方法,因为每次使用都是访问一个对象。
 */
 
public class IteratorTest2 {
    public static void main(String[] args) {
        // 创建集合对象
        Collection c = new ArrayList();

        // 创建学生对象
        Student s1 = new Student("林青霞", 27);
        Student s2 = new Student("风清扬", 30);
        Student s3 = new Student("令狐冲", 33);
        Student s4 = new Student("武鑫", 25);
        Student s5 = new Student("刘晓曲", 22);

        // 把学生添加到集合中
        c.add(s1);
        c.add(s2);
        c.add(s3);
        c.add(s4);
        c.add(s5);

        // 遍历
        Iterator it = c.iterator();
        while (it.hasNext()) {
            //标准写法
            Student s = (Student) it.next();
            System.out.println(s.getName() + "---" + s.getAge());

        }
        // System.out.println("--------------------");

        // for循环改写,效率高,但理解难度大
        // for(Iterator it = c.iterator();it.hasNext();){
        // Student s = (Student) it.next();
        // System.out.println(s.getName() + "---" + s.getAge());
        // }
    }
}

Iterator接口的使用和原理讲解

  • Iterator接口的使用讲解
  • Iterator接口的原理讲解
  • 为什么不定义成一个类,而是一个接口
No_16_0310 Java基础学习第十五天_第2张图片
  • 看源码是如何实现的
    • 层层继承,最终在Itr内部类具体实现了
public interface Iterator {
    boolean hasNext();
    Object next(); 
}

public interface Iterable {
    Iterator iterator();
}

public interface Collection extends Iterable {
    Iterator iterator();
}

public interface List extends Collection {
    Iterator iterator();
}

public class ArrayList implements List {
    public Iterator iterator() {
        return new Itr();
    }
    
    private class Itr implements Iterator {
        public boolean hasNext() {}
        public Object next(){} 
    }
}


Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
Iterator it = c.iterator();     //new Itr();
while(it.hasNext()) {
    String s = (String)it.next();
    System.out.println(s);
}


Collection案例

  • 存储字符串并遍历(熟练背写)
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
 * 需求:存储字符串并遍历。
 * 
 * 分析:
 *         A:创建集合对象
 *         B:创建字符串对象
 *         C:把字符串对象添加到集合中
 *         D:遍历集合
 */
public class CollectionTest {
    public static void main(String[] args) {
        // 创建集合对象
        Collection c = new ArrayList();

        // 创建字符串对象
        // 把字符串对象添加到集合中
        c.add("林青霞");
        c.add("风清扬");
        c.add("刘意");
        c.add("武鑫");
        c.add("刘晓曲");

        // 遍历集合
        // 通过集合对象获取迭代器对象
        Iterator it = c.iterator();
        // 通过迭代器对象的hasNext()方法判断有没有元素
        while (it.hasNext()) {
            // 通过迭代器对象的next()方法获取元素
            String s = (String) it.next();
            System.out.println(s);
        }
    }
}
  • 存储自定义对象并遍历(熟练背写)
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
 * 需求:存储自定义对象并遍历Student(name,age)
 *
 * 分析:
 *         A:创建学生类
 *         B:创建集合对象
 *         C:创建学生对象
 *         D:把学生对象添加到集合对象中
 *         E:遍历集合
 */
public class CollectionTest2 {
    public static void main(String[] args) {
        // 创建集合对象
        Collection c = new ArrayList();

        // 创建学生对象
        Student s1 = new Student("貂蝉", 25);
        Student s2 = new Student("小乔", 16);
        Student s3 = new Student("黄月英", 20);
        Student s4 = new Student();
        s4.setName("大乔");
        s4.setAge(26);

        // 把学生对象添加到集合对象中
        c.add(s1);
        c.add(s2);
        c.add(s3);
        c.add(s4);
        c.add(new Student("孙尚香", 18)); // 匿名对象

        // 遍历集合
        Iterator it = c.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}


List接口

List接口概述

  • 有序 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
  • 与 set 不同,列表通常允许重复的元素。
List案例
  • 存储字符串并遍历

  • 存储自定义对象并遍历

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
 * 存储自定义对象并遍历
 */
public class ListDemo {
    public static void main(String[] args) {
        // 创建集合对象
        List list = new ArrayList();

        // 创建学生对象
        Student s1 = new Student("白骨精", 30);
        Student s2 = new Student("蜘蛛精", 40);
        Student s3 = new Student("观音姐姐", 22);

        // 把学生对象添加到集合对象中
        list.add(s1);
        list.add(s2);
        list.add(s3);

        // 遍历
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}

List接口成员方法

List集合的特有功能:
  • A:添加功能

    • void add(int index,Object element):在指定位置添加元素,其他元素顺位后移
  • B:获取功能

    • Object get(int index):获取指定位置的元素
  • C:列表迭代器

    • ListIterator listIterator():List集合特有的迭代器
  • D:删除功能

    • Object remove(int index):根据索引删除元素,返回被删除的元素
  • E:修改功能

    • Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
import java.util.ArrayList;
import java.util.List;

/*
 * List集合的特有功能:
 * A:添加功能
 *         void add(int index,Object element):在指定位置添加元素
 * B:获取功能
 *         Object get(int index):获取指定位置的元素,可以做遍历使用。
 * C:列表迭代器
 *         ListIterator listIterator():List集合特有的迭代器
 * D:删除功能
 *         Object remove(int index):根据索引删除元素,返回被删除的元素
 * E:修改功能
 *         Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
 */
public class ListDemo {
    public static void main(String[] args) {
        // 创建集合对象
        List list = new ArrayList();

        // 添加元素
        list.add("hello");
        list.add("world");
        list.add("java");

        // void add(int index,Object element):在指定位置添加元素
        // list.add(1, "android");//没有问题
        // IndexOutOfBoundsException
        // list.add(11, "javaee");//有问题
        // list.add(3, "javaee"); //没有问题
        // list.add(4, "javaee"); //有问题

        // Object get(int index):获取指定位置的元素
        // System.out.println("get:" + list.get(1));
        // IndexOutOfBoundsException
        // System.out.println("get:" + list.get(11));

        // Object remove(int index):根据索引删除元素,返回被删除的元素
        // System.out.println("remove:" + list.remove(1));
        // IndexOutOfBoundsException
        // System.out.println("remove:" + list.remove(11));

        // Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
        System.out.println("set:" + list.set(1, "javaee"));

        System.out.println("list:" + list);
    }
}
  • get方法做遍历
import java.util.ArrayList;
import java.util.List;

/*
 * List集合的特有遍历功能:
 *         size()和get()方法结合使用
 */
public class ListDemo2 {
    public static void main(String[] args) {
        // 创建集合对象
        List list = new ArrayList();

        // 添加元素
        list.add("hello");
        list.add("world");
        list.add("java");

        // 最终的遍历方式就是:size()和get()
        for (int x = 0; x < list.size(); x++) {
            // System.out.println(list.get(x));

            String s = (String) list.get(x);
            System.out.println(s);
        }
    }
}
  • 普通遍历与For遍历
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
 * 存储自定义对象并遍历,用普通for循环。(size()和get()结合)
 */
public class ListDemo3 {
    public static void main(String[] args) {
        // 创建集合对象
        List list = new ArrayList();

        // 创建学生对象
        Student s1 = new Student("林黛玉", 18);
        Student s2 = new Student("刘姥姥", 88);
        Student s3 = new Student("王熙凤", 38);

        // 把学生添加到集合中
        list.add(s1);
        list.add(s2);
        list.add(s3);

        // 遍历
        // 迭代器遍历
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s.getName() + "---" + s.getAge());
        }
        System.out.println("--------");

        // 普通for循环
        for (int x = 0; x < list.size(); x++) {
            Student s = (Student) list.get(x);
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}


ListIterator 列表迭代器

  • ListIterator listIterator():List集合特有的迭代器
  • 该迭代器继承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法。
ListIterator接口的成员方法
  • boolean hasPrevious()
  • E previous()
  • 注意:要用逆向遍历,必须先正向遍历,所以一般无意义,不使用。
public class ListIteratorDemo {
    public static void main(String[] args) {
        // 创建List集合对象
        List list = new ArrayList();
        list.add("hello");
        list.add("world");
        list.add("java");

        // ListIterator listIterator()
        ListIterator lit = list.listIterator(); // 子类对象
        // while (lit.hasNext()) {
        // String s = (String) lit.next();
        // System.out.println(s);
        // }
        // System.out.println("-----------------");
        
        // System.out.println(lit.previous());
        // System.out.println(lit.previous());
        // System.out.println(lit.previous());
        // NoSuchElementException
        // System.out.println(lit.previous());

        while (lit.hasPrevious()) {
            String s = (String) lit.previous();
            System.out.println(s);
        }
        System.out.println("-----------------");

        // 迭代器
        Iterator it = list.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s);
        }
        System.out.println("-----------------");

    }
}
  • ConcurrentModificationException: 并发修改异常
    • 现象:迭代器遍历集合,集合修改集合元素。
    public class ListIteratorDemo2 {
    public static void main(String[] args) {
        // 创建List集合对象
        List list = new ArrayList();
        // 添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
    
        // 迭代器遍历
         Iterator it = list.iterator();
         while (it.hasNext()) {
         String s = (String) it.next();
         if ("world".equals(s)) {
         list.add("javaee");
         
         //报错:ConcurrentModificationException
         }
         }
    
        System.out.println("list:" + list);
    }
    

}
```
* 原因:迭代器是依赖于集合而存在的,在判断成功后,集合中新添加了元素,而迭代器不知道,所以会报错。换句话说:迭代器遍历元素的时候,集合不能修改元素。
* 解决方案
* 方案一:迭代器迭代元素,迭代器修改元素;元素是跟着刚才迭代的元素后面的。
* 注:Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator
* 方案二:集合遍历元素,集合修改元素(For循环);元素在最后添加。


public class ListIteratorDemo2 {
    public static void main(String[] args) {
        // 创建List集合对象
        List list = new ArrayList();
        // 添加元素
        list.add("hello");
        list.add("world");
        list.add("java");

        // 方式1:迭代器迭代元素,迭代器修改元素
        // 而Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator
        // ListIterator lit = list.listIterator();
        // while (lit.hasNext()) {
        // String s = (String) lit.next();
        // if ("world".equals(s)) {
        // lit.add("javaee");
        // }
        // }

        // 方式2:集合遍历元素,集合修改元素(普通for)
        for (int x = 0; x < list.size(); x++) {
            String s = (String) list.get(x);
            if ("world".equals(s)) {
                list.add("javaee");
            }
        }

        System.out.println("list:" + list);
    }
}


常见数据结构

  • 栈:先进后出
  • 队列:先进先出
  • 数组:查询快,增加删除麻烦
  • 链表:由一个链子把多个节点连接组成的数据。
    • 节点:由数据地址组成。(数据域和指针组成)
      No_16_0310 Java基础学习第十五天_第3张图片
  • 哈希表
List:(面试题List的子类特点)
  • ArrayList:

    • 底层数据结构是数组查询快,增删慢
    • 线程不安全效率高
  • Vector:

    • 底层数据结构是数组查询快,增删慢
    • 线程安全效率低
  • LinkedList:

    • 底层数据结构是链表查询慢,增删快
    • 线程不安全效率高
  • List有三个儿子,我们到底使用谁呢?

    • 要安全吗?
      • 要:Vector(即使要安全,也不用这个了,后面有替代的)
      • 不要:ArrayList或者LinkedList
        • 查询多:ArrayList
        • 增删多:LinkedList
    • 如果你什么都不懂,就用ArrayList。

你可能感兴趣的:(No_16_0310 Java基础学习第十五天)