JavaSE学习笔记(十六)—— List

一、List接口概述

1.1 List概述

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

1.2 List案例

【List集合存储字符串并遍历】

public class ListDemo {
    public static void main(String[] args) {
        // 创建集合对象
        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();
            System.out.println(s);
        }
    }
}

【存储自定义对象并遍历】

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的特有功能

2.1 基本功能

【添加功能】

  void add(int index,Object element):在指定位置添加元素

【获取功能】

  Object get(int index):获取指定位置的元素

【列表迭代器】

  ListIterator listIterator():List集合特有的迭代器

【删除功能】

  Object remove(int index):根据索引删除元素,返回被删除的元素

扫描二维码关注公众号,回复: 6232355 查看本文章

【修改功能

  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);
    }
}

2.2 遍历功能

【使用普通for循环]

  List集合的特有遍历功能:size()和get()方法结合使用

public class ListDemo {
    public static void main(String[] args) {
        // 创建集合对象
        List list = new ArrayList();

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

        for (int x = 0; x < list.size(); x++) {
            String s = (String) list.get(x);
            System.out.println(s);
        }
    }
}

  存储自定义对象并遍历,用普通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():List集合特有的迭代器。该迭代器继承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法。

  特有功能:

  • Object previous():获取上一个元素
  • boolean hasPrevious():判断是否有元素
public class ListIteratorDemo {
    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();
            System.out.println(s);
        }
        System.out.println("----------");

        // ListIterator listIterator()
        ListIterator lit = list.listIterator();
        while (lit.hasPrevious()) {
            String s = (String) lit.previous();
            System.out.println(s);
        }
    }
}

  注意:ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,所以一般无意义,不使用。

三、List的并发修改异常

  问题:我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。

public class ListIteratorDemo {
    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:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

【产生的原因】

  迭代器是依赖于集合而存在的,在判断成功后,集合中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
  其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。

【解决方法】

  • 方式一:迭代器迭代元素,迭代器修改元素(元素是跟在刚才迭代的元素后面的)
    public class ListIteratorDemo {
        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");
                }
            }
    
            System.out.println("list:" + list);//[hello, world, javaee, java]
        }
    }
  • 方式2:集合遍历元素,集合修改元素(元素在最后添加的)
    public class ListIteratorDemo {
        public static void main(String[] args) {
            // 创建List集合对象
            List list = new ArrayList();
            // 添加元素
            list.add("hello");
            list.add("world");
            list.add("java");
    
            // 方式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);//[hello, world, java, javaee]
        }
    }

四、List接口的实现类

4.1 ArrayList

【ArrayList类概述】

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

【ArrayList案例】

  存储字符串并遍历

public class ArrayListDemo {
    public static void main(String[] args) {
        // 创建集合对象
        ArrayList array = new ArrayList();

        // 创建元素对象,并添加元素
        array.add("hello");
        array.add("world");
        array.add("java");

        // 遍历
        Iterator it = array.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s);
        }

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

        for (int x = 0; x < array.size(); x++) {
            String s = (String) array.get(x);
            System.out.println(s);
        }
    }
}

  ArrayList存储自定义对象并遍历

public class ArrayListDemo2 {
    public static void main(String[] args) {
        // 创建集合对象
        ArrayList array = new ArrayList();

        // 创建学生对象
        Student s1 = new Student("武松", 30);
        Student s2 = new Student("鲁智深", 40);
        Student s3 = new Student("林冲", 36);
        Student s4 = new Student("杨志", 38);

        // 添加元素
        array.add(s1);
        array.add(s2);
        array.add(s3);
        array.add(s4);

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

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

        for (int x = 0; x < array.size(); x++) {
            // ClassCastException 注意,千万要搞清楚类型
            // String s = (String) array.get(x);
            // System.out.println(s);

            Student s = (Student) array.get(x);
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}

  去除集合中字符串的重复值(字符串的内容相同)

/*
 * 分析:
 *         A:创建集合对象
 *         B:添加多个字符串元素(包含内容相同的)
 *         C:创建新集合
 *         D:遍历旧集合,获取得到每一个元素
 *         E:拿这个元素到新集合去找,看有没有
 *             有:不搭理它
 *             没有:就添加到新集合
 *         F:遍历新集合
 */
public class ArrayListDemo {
    public static void main(String[] args) {
        // 创建集合对象
        ArrayList array = new ArrayList();

        // 添加多个字符串元素(包含内容相同的)
        array.add("hello");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("java");
        array.add("world");

        // 创建新集合
        ArrayList newArray = new ArrayList();

        // 遍历旧集合,获取得到每一个元素
        Iterator it = array.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();

            // 拿这个元素到新集合去找,看有没有
            if (!newArray.contains(s)) {
                newArray.add(s);
            }
        }

        // 遍历新集合
        for (int x = 0; x < newArray.size(); x++) {
            String s = (String) newArray.get(x);
            System.out.println(s);
        }
    }
}

  去除集合中字符串的重复值(字符串的内容相同),要求:不能创建新的集合,就在以前的集合上做。

public class ArrayListDemo2 {
    public static void main(String[] args) {
        // 创建集合对象
        ArrayList array = new ArrayList();

        // 添加多个字符串元素(包含内容相同的)
        array.add("hello");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("java");
        array.add("world");

        // 由选择排序思想引入,我们就可以通过这种思想做这个题目
        // 拿0索引的依次和后面的比较,有就把后的干掉
        // 同理,拿1索引...
        for (int x = 0; x < array.size() - 1; x++) {
            for (int y = x + 1; y < array.size(); y++) {
                if (array.get(x).equals(array.get(y))) {
                    array.remove(y);
                    y--;
                }
            }
        }

        // 遍历集合
        Iterator it = array.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s);
        }
    }
}

  去除集合中自定义对象的重复值(对象的成员变量值都相同)

/*
 * 我们按照和字符串一样的操作,发现出问题了。
 * 为什么呢?
 *         我们必须思考哪里会出问题?
 *         通过简单的分析,我们知道问题出现在了判断上。
 *         而这个判断功能是集合自己提供的,所以我们如果想很清楚的知道它是如何判断的,就应该去看源码。
 * contains()方法的底层依赖的是equals()方法。
 * 而我们的学生类中没有equals()方法,这个时候,默认使用的是它父亲Object的equals()方法
 * Object()的equals()默认比较的是地址值,所以,它们进去了。因为new的东西,地址值都不同。
 * 按照我们自己的需求,比较成员变量的值,重写equals()即可。
 * 自动生成即可。
 */
public class ArrayListDemo3 {
    public static void main(String[] args) {
        // 创建集合对象
        ArrayList array = new ArrayList();

        // 创建学生对象
        Student s1 = new Student("林青霞", 27);
        Student s2 = new Student("林志玲", 40);
        Student s3 = new Student("凤姐", 35);
        Student s4 = new Student("芙蓉姐姐", 18);
        Student s5 = new Student("翠花", 16);
        Student s6 = new Student("林青霞", 27);
        Student s7 = new Student("林青霞", 18);

        // 添加元素
        array.add(s1);
        array.add(s2);
        array.add(s3);
        array.add(s4);
        array.add(s5);
        array.add(s6);
        array.add(s7);

        // 创建新集合
        ArrayList newArray = new ArrayList();

        // 遍历旧集合,获取得到每一个元素
        Iterator it = array.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();

            // 拿这个元素到新集合去找,看有没有
            if (!newArray.contains(s)) {
                newArray.add(s);
            }
        }

        // 遍历新集合
        for (int x = 0; x < newArray.size(); x++) {
            Student s = (Student) newArray.get(x);
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}

4.2 Vector

【Vector类概述】

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

【Vector类特有功能】

  添加功能:public void addElement(Object obj) -- add()

  获取功能:

  public Object elementAt(int index)    -- get()
  public Enumeration elements()      -- Iterator iterator()
    boolean hasMoreElements()       hasNext()
    Object nextElement()             next()

public class VectorDemo {
    public static void main(String[] args) {
        // 创建集合对象
        Vector v = new Vector();

        // 添加功能
        v.addElement("hello");
        v.addElement("world");
        v.addElement("java");

        // 遍历
        for (int x = 0; x < v.size(); x++) {
            String s = (String) v.elementAt(x);
            System.out.println(s);
        }

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

        Enumeration en = v.elements(); // 返回的是实现类的对象
        while (en.hasMoreElements()) {
            String s = (String) en.nextElement();
            System.out.println(s);
        }
    }
}

4.3 LinkedList

【LinkedList类概述】

  底层数据结构是链表,查询慢,增删快
  线程不安全,效率高

【LinkedList类特有功能】

  A:添加功能
    public void addFirst(Object e)
    public void addLast(Object e)
  B:获取功能
    public Object getFirst()
    public Obejct getLast()
  C:删除功能
    public Object removeFirst()
    public Object removeLast()

public class LinkedListDemo {
    public static void main(String[] args) {
        // 创建集合对象
        LinkedList link = new LinkedList();

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

        // public void addFirst(Object e)
        // link.addFirst("javaee");
        // public void addLast(Object e)
        // link.addLast("android");

        // public Object getFirst()
        // System.out.println("getFirst:" + link.getFirst());
        // public Obejct getLast()
        // System.out.println("getLast:" + link.getLast());

        // public Object removeFirst()
        System.out.println("removeFirst:" + link.removeFirst());
        // public Object removeLast()
        System.out.println("removeLast:" + link.removeLast());

        // 输出对象名
        System.out.println("link:" + link);
    }
}

【练习】

  请用LinkedList模拟栈数据结构的集合,并测试

  注意,题目的意思是:你自己的定义一个集合类,在这个集合类内部可以使用LinkedList模拟。

  MyStack.java

/**
 * 自定义的栈集合
 */
public class MyStack {
    private LinkedList linkedList;

    public MyStack() {
        linkedList = new LinkedList();
    }

    public void add(Object obj) {
        linkedList.addFirst(obj);
    }

    public Object get() {
        return linkedList.removeFirst();
    }

    public boolean isEmpty() {
        return linkedList.isEmpty();
    }
}

  MyStackDemo.java

/**
 * MyStack的测试
 */
public class MyStackDemo {
    public static void main(String[] args) {
        // 创建集合对象
        MyStack myStack = new MyStack();

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

        while (!myStack.isEmpty()) {
            System.out.println(myStack.get());
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/yft-javaNotes/p/10856110.html