Java--集合(List、ArrayList、Vector、LinkedList)

一、集合概念

  对象的容器,实现了对对象常用的操作,类似数组功能

二、集合和数组的区别

  • 数组长度固定,集合长度不固定
  • 数组可以存储基本类型和引用类型,集合只能存储引用类型(如果想存储基本类型,则需把基本类型装箱)
  • 重点:迭代器专门用来遍历集合的一种方式
  •            hasNext();有没有下一个元素 有返回true,否则返回false
  •            next();获取下一个元素
  •            remove();删除当前元素

 

package com.monv.jihe;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * Collection接口的使用
 * 1.添加元素
 * 2.删除元素
 * 3.遍历元素
 * 4、判断
 * @author Administrator
 *
 */
public class TestCollection {
    public static void main(String[] args) {
        //创建集合
        Collection collection = new ArrayList();
        //1.添加元素
        collection.add("苹果");
        collection.add("葡萄");
        collection.add("草莓");
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection);
        //2.删除
//        collection.remove("葡萄");
//        collection.clear();//清空
//        System.out.println("元素个数:"+collection.size());
//        System.out.println(collection);
        //3.遍历元素
        //3.1 使用增强for(foreach)  不能用for循环 因为没有下标
        System.out.println("-------使用增强for遍历----------");
        for (Object object : collection) {
            System.out.println(object);
        }
        //3.2 使用迭代器(专门用来遍历集合的一种方式)
        //hasNext();有没有下一个元素
        //next();获取下一个元素
        //remove();删除当前元素
        System.out.println("-------使用迭代器遍历---------");
        Iterator it = collection.iterator();
        while(it.hasNext()){
            String str = (String)it.next();
            System.out.println(str);
//            collection.remove(str);//迭代过程中不能用collection的其他方法来改变元素的
//            it.remove();//可以用迭代器的方法remove()进行删除
        }
        System.out.println(collection.size());
        //4.判断
        System.out.println("--------判断是否包含某个元素----------");
        System.out.println(collection.contains("梨"));
        System.out.println(collection.contains("葡萄"));
    }
}

 三、List子接口

  特点:有序(添加和遍历的顺序是一致的)、有下标、元素可以重复

  方法:除了collection中的方法外,还包含其特有的方法

  • void add(int index,Object o);//在index的位置插入对象o
  • boolean addAll(int index,Collection c);//将一个集合中的元素添加到此集合中index位置
  • Object get(int index);//返回集合中指定位置的元素
  • List subList(int fromIndex,int toIndex);//返回fromIndex和toIndex之间集合元素 含首不含尾
package com.monv.jihe;

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

/**
 * List子接口的使用
 * 特点:1.有序 有下标 2.可以重复
 * @author Administrator
 *
 */
public class Demo1 {
    public static void main(String[] args) {
        //先创建集合对象
        List list = new ArrayList();
        //1.添加元素
        list.add("苹果");
        list.add("小米");
        list.add(0, "华为");
        System.out.println("元素个数:"+list.size());
        System.out.println(list.toString());
        //2.删除元素
//        list.remove("苹果");
//        list.remove(0);
//        System.out.println("删除后元素个数:"+list.size());
        //3.遍历
        //3.1for循环遍历
        System.out.println("----3.1for循环遍历----");
        for(int i=0;i<list.size();i++) {
            System.out.println(list.get(i));
        }
        //3.2增强for循环遍历
        System.out.println("----3.2增强for循环----");
        for (Object object : list) {
            System.out.println(object);
        }
        //3.3使用迭代器
        System.out.println("----3.3使用迭代器----");
        Iterator it = list.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        //list 指针默认指向第一个元素
        //3.4列表迭代器
        System.out.println("----3.41列表迭代器(从前往后)----");
        ListIterator lit = list.listIterator();
        while(lit.hasNext()) {
            System.out.println(lit.nextIndex() +":"+lit.next());
        }
        //如果使用从后往前迭代的话 指针需要指向最后一个元素 ,在上个循环的基础上 执行从后往前的迭代
        System.out.println("---3.42列表迭代器(从后往前)---");
        while (lit.hasPrevious()) {
            System.out.println(lit.previousIndex() + ":" + lit.previous());
        }
        //4.判断
        System.out.println("--------4.判断----------");
        System.out.println(list.contains("苹果"));
        System.out.println(list.isEmpty());

        //5.获取位置
        System.out.println("--------5.获取位置--------");
        System.out.println(list.indexOf("华为"));
    }
}
-------------------------------------------------------------------------
package com.monv.jihe;

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

/**
 * List的使用
 * @author Administrator
 *
 */

public class Demo2 {
    public static void main(String[] args) {
        //创建集合
        List list = new ArrayList();
        //1.添加数字数据(添加的时候包含自动装箱的操作 把基本类型转换为引用类型)
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        list.add(60);
        System.out.println("集合元素的个数:"+list.size());
        System.out.println(list.toString());
        //2.删除操作
//        list.remove(20);//注意:这里是根据index下标删除的 总共有5个元素 删除第20个元素 下标越界 会报错
//        list.remove(0);
//        list.remove((Object)20);//把20转换为object类型后再进行删除
//        list.remove(new Integer(20));
        System.out.println("删除后元素个数:"+list.size());
        
        //3.补充方法 subList:返回子集合 含头不含尾
        System.out.println("-----subList-----");
        List subList = list.subList(1, 3);
        System.out.println("子集合元素个数:"+subList.size());
        System.out.println(subList.toString());
    }
}

四、 List实现类

4.1 ArrayList【重点】:数组结构实现,查询快、增删慢;JDK1.2版本,运行效率快、线程不安全

package com.monv.jihe;

public class Student {
    private String name;
    private int age;
    
    public Student() {
        // TODO Auto-generated constructor stub
    }
        
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
    @Override
    public boolean equals(Object obj) {
        //1.判断是否是同一个对象
        if(this == obj) {
            return true;
        }
        //2.判断是否为空
        if(obj == null) {
            return false;
        }
        //3.判断是否是Student类型
        if (obj instanceof Student) {
            Student s = (Student)obj;
            //4.比较属性
            if (this.name.equals(s.getName())&&this.age == s.getAge()) {
                return true;
            }
        }
        //5.不满足返回false
        return false;
    }
}
--------------------------------------------
package com.monv.jihe;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

/**
 * ArrayList的使用
 * 存储结构:数组,查找遍历速度快,增删慢
 * @author Administrator
 *
 */
public class Demo3 {
    public static void main(String[] args) {
        //创建集合 size 0 容量0,扩容原来的1.5倍(当添加第11个元素的时候,容量扩到15)
        ArrayList arrayList = new ArrayList();
        Student s1 = new Student("小明", 20);
        Student s2 = new Student("小红", 21);
        Student s3 = new Student("小花", 19);
        Student s4 = new Student("小芳", 18);
        //1.添加元素    
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        arrayList.add(s4);
        System.out.println("元素个数:"+arrayList.size());
        System.out.println(arrayList.toString());
        //2.删除元素
//        arrayList.remove(0);
//        arrayList.remove(s2);
        //remove删除判断的时候是用equals(this==obj) 来判断两个对象的地址是否一样
        //如果想用下面new一个对象的方式来删除s4 则需要在Student中重写equals让它来比较两个值是否一样 一样删除 在
        arrayList.remove(new  Student("小芳", 18));
        System.out.println("删除后元素个数:"+arrayList.size());
        //3.遍历元素【重点】
        //3.1使用迭代器
        System.out.println("--------3.1使用迭代器-------------");
        Iterator it = arrayList.iterator();
        while(it.hasNext()) {
            Student s = (Student)it.next();
            System.out.println(s.toString());
        }
        //3.2列表迭代器
        System.out.println("--------3.2使用列表迭代器正向--------");
        ListIterator lit= arrayList.listIterator();
        while(lit.hasNext()) {
            Student s = (Student) lit.next();
            System.out.println(s.toString());
        }
        System.out.println("--------3.2使用列表迭代器逆向--------");
        while(lit.hasPrevious()) {
            Student s = (Student) lit.previous();
            System.out.println(s.toString());
        }
        //4.判断
        System.out.println(arrayList.contains(new Student("小明", 20)));//因为重写了equals 所以也可以用new的方式来比较值是否相同
        System.out.println(arrayList.isEmpty());//判断是否为空
        //5.查找
        System.out.println(arrayList.indexOf(s3));//查找位置
    }
}

源码分析:DEFAULT_CAPACITY = 10; 默认容量

               ( 注意:如果没有向集合中添加任何元素,容量为0,当开始向集合中添加元素的时候,默认容量为10;每次扩容大小是原来的1.5倍)

     elementData:存放元素的数组

     size :实际元素的个数

     add():添加元素

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

   private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
   //数组扩容的方法
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

  

4.2 Vector:数组结构实现,查询快,增删慢;JDK1.0版本,运行效率慢、线程安全

package com.monv.jihe;

import java.util.Enumeration;
import java.util.Vector;

/**
 * 演示Vector集合使用
 * 存储结构:数组
 * @author Administrator
 *
 */
public class Demo4 {
    public static void main(String[] args) {
        //创建集合
        Vector vector = new Vector();
        //1.添加元素
        vector.add("花生");
        vector.add("小麦");
        vector.add("玉米");
        System.out.println("元素个数:"+vector.size());
        //2.删除
//        vector.remove("花生");
//        vector.remove(2);
//        vector.clear();//清空
        System.out.println("删除后元素个数:"+vector.size());
        //3.遍历 使用枚举器
        Enumeration en = vector.elements();
        while(en.hasMoreElements()) {
            String s = (String)en.nextElement();
            System.out.println(s);
        }
        //4.判断
        System.out.println(vector.contains("花生"));
        System.out.println(vector.isEmpty());//是否为空
//5.其他方法firstElement() lastElement() elementAt() System.out.println(vector.firstElement()); System.out.println(vector.lastElement()); System.out.println(vector.elementAt(1)); } }

 

4.3LinkedList:链表结构实现,增删快,查询慢。第一个元素指向第二元素,然后依次类推,删除的时候,链表会重新指向另外的一个元素。因为有引用指向关系所以查询的时候比较慢。

package com.monv.jihe;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

/**
 * LinkedList 使用
 * 存储结构:双向链表
 * @author Administrator
 *
 */
public class Demo5 {
    public static void main(String[] args) {
        //创建集合
        LinkedList linkedList = new LinkedList();
        Student s1 = new Student("小明", 20);
        Student s2 = new Student("小红", 21);
        Student s3 = new Student("小花", 19);
        //1.添加元素
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        System.out.println("元素个数:"+linkedList.size());
        System.out.println(linkedList.toString() );
        //2.删除元素
//        linkedList.remove(0);
//        linkedList.remove(s1);
//        linkedList.remove(new Student("小红", 21));
//        linkedList.clear();//清空
        System.out.println("删除后元素个数:"+linkedList.size());
        //3.遍历
        //3.1使用for遍历
        System.out.println("----3.1使用for遍历----");
        for(int i = 0;i<linkedList.size();i++) {
            System.out.println(linkedList.get(i));
        }
        //3.2增强for循环
        System.out.println("----3.2增强for循环----");
        for (Object object : linkedList) {
            Student s = (Student)object;
            System.out.println(s.toString());
        }
        //3.3使用迭代器
        System.out.println("----3.3使用迭代器----");
        Iterator it = linkedList.iterator();
        while(it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        //3.4使用列表迭代器
        System.out.println("----3.4使用列表迭代器----");
        ListIterator lit = linkedList.listIterator();
        while(lit.hasNext()) {
            Student s = (Student) lit.next();
            System.out.println(s.toString());
        }                
        //4.判断
        System.out.println("----判断----");
        System.out.println(linkedList.contains(s2));
        System.out.println(linkedList.isEmpty());
        //5.获取
        System.out.println("----获取----");
        System.out.println(linkedList.indexOf(s2));
        
    }
}

源码分析:

    int  size : 集合的大小   

    Node  first : 链表的头节点 

    Node  last :链表的尾节点

    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

 4.4 ArrayList和LinkedList 不同结构实现方式

  • ArrayList(数组):必须开辟连续的空间,查询快,增删慢。而且有角标
  • LinkedList(双向链表):无需开辟连续空间,查询慢,增删快
  •  

     

posted @ 2020-10-12 22:36  改Bug的小魔女  阅读(134)  评论(0编辑  收藏  举报