JAVA集合框架(二)

JAVA集合框架(二)

二. List接口与实现类

  • 特点:有序、有下标、元素可以重复。

1. List接口

集合遍历:
例一:
import java.util.*;
public class Application {
    public static void main(String[] args) {
    //创建一个集合
        List list = new ArrayList();
    //添加元素
        list.add("苹果");
        list.add("香蕉");
        list.add(0,"草莓");
        System.out.println(list);
    //删除元素
//        list.remove("苹果");
//        list.remove(0);
//        System.out.println(list);
    //判断
        System.out.println("是否包含'苹果':"+list.contains("苹果"));
        System.out.println("是否为空:"+list.isEmpty());
    //获取
        System.out.println("苹果的下标为:"+list.indexOf("苹果"));
    //遍历
        //for()
        System.out.println("----------for--------");
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }
        //增强for
        System.out.println("----------增强for--------");
        for (Object o : list) {
            System.out.println(o);
        }
        System.out.println("----------迭代器---------");
        //迭代器
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //列表迭代器  和iterator的区别:ListIterator可以向前或向后遍历,添加,删除,修改元素
        ListIterator listIterator = list.listIterator();
        System.out.println("---------list迭代器从前到后:-----------");
        while (listIterator.hasNext()){
            System.out.print(listIterator.nextIndex()+"\t");
            System.out.println(listIterator.next());
        }
        System.out.println("---------list迭代器从后到前:-----------");
        while (listIterator.hasPrevious()){
            System.out.print(listIterator.previousIndex()+"\t");
            System.out.println(listIterator.previous());
        }
    }
}
---------------结果---------------
[草莓, 苹果, 香蕉]
是否包含'苹果'true
是否为空:false
苹果的下标为:1
----------for--------
草莓
苹果
香蕉
----------增强for--------
草莓
苹果
香蕉
----------迭代器---------
草莓
苹果
香蕉
---------list迭代器从前到后:-----------
0	草莓
1	苹果
2	香蕉
---------list迭代器从后到前:-----------
2	香蕉
1	苹果
0	草莓
例二:
import java.util.*;
public class Application {
    public static void main(String[] args) {
        List list= new ArrayList();
        //添加数字类型:隐藏了自动装箱操作
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        System.out.println(list.size());
        System.out.println(list);
        //删除
        list.remove((Object) 10);
        list.remove(new Integer(20));//包装
        //不可直接用list.remove(10);  会把10当成下标来删除,导致下标越界
        System.out.println(list);
    }
}
---------------结果---------------
4
[10, 20, 30, 40]
[30, 40]
add()方法

void add(int index,Object o)//在index位置插入对象o。

import java.util.ArrayList;
import java.util.List;
public class Application {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(0,"苹果");
        list.add(1,"香蕉");
        list.add(2,"草莓");
        list.add(0,"菠萝");
        System.out.println(list);
    }
}
----------------结果-----------------
[菠萝, 苹果, 香蕉, 草莓]
addAll()方法

boolean addAll(int index,Collection c)//将一个集合中的元素添加到此集合中的index位置。

import java.util.ArrayList;
import java.util.List;
public class Application {
    public static void main(String[] args) {
        List list = new ArrayList();
        List list2 = new ArrayList();
        list.add(0,"苹果");
        list.add(1,"香蕉");
        list2.add(0,"草莓");
        list2.add(1,"菠萝");
        System.out.println(list);
        System.out.println(list2);
        list2.addAll(1,list);
        System.out.println(list2);
    }
}
---------------结果---------------
[苹果, 香蕉]
[草莓, 菠萝]
[草莓,  菠萝]
get()方法

0bject get(int index)//返回集合中指定位置的元素。

import java.util.ArrayList;
import java.util.List;
public class Application {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(0,"苹果");
        list.add(1,"香蕉");
        list.add(2,"草莓");
        System.out.println(list);
        System.out.println(list.get(0));
    }
}
---------------结果---------------
[苹果, 香蕉, 草莓]
苹果
subList()方法

List subList(int fromIndex,int toIndex)//返回fromIndex和toIndex之间的集合元素。

import java.util.ArrayList;
import java.util.List;
public class Application {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(0,"苹果");
        list.add(1,"香蕉");
        list.add(2,"草莓");
        System.out.println(list);
        System.out.println(list.subList(1,3));//包含下界,不含上界
    }
}
---------------结果---------------
[苹果, 香蕉, 草莓]
[香蕉, 草莓]

2. List实现类

  • ArrayList【重点】:
    数组结构实现,查询快、增删慢;
    JDK1.2版本,运行效率快、线程不安全。
  • Vector:
    数组结构实现,查询快、增删慢;
    JDK1.0版本,运行效率慢、线程安全。
  • LinkedList:
    链表结构实现,增删快,查询慢。
ArrayList集合:
  • 数组结构实现,查询快、增删慢;
  • JDK1.2版本,运行效率快、线程不安全。
import java.util.*;
public class Application {
    public static void main(String[] args) {
    //ArrayList实现类
    //存储结构:数组,查找遍历速度快,增删速度慢
    //创建集合
        ArrayList arrayList = new ArrayList();
    //增加元素
        Student s1 = new Student("aaa", 20);
        Student s2 =new Student("bbb",20);
        Student s3 =new Student("ccc",20);
        Student s4 =new Student("ddd",20);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        arrayList.add(s4);
        System.out.println("元素个数为:"+arrayList.size());
        System.out.println(arrayList);
    //删除元素
        arrayList.remove(s1);
        System.out.println(arrayList);
        arrayList.remove(new Student("bbb",20));//相当于用了equals方法,比较地址,不相同则无法删除
        //解决方法重写equals方法
        System.out.println(arrayList);
    //遍历元素
        //迭代器
        Iterator iterator = arrayList.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //列表迭代器
        ListIterator listIterator = arrayList.listIterator();
        while (listIterator.hasNext()){
            System.out.println(listIterator.nextIndex()+":\t"+listIterator.next());
        }
    //判断
        System.out.println("包含学生s3吗\t"+arrayList.contains(s3));
        System.out.println("包含学生s4吗\t"+arrayList.contains(new Student("ddd", 20)));
        System.out.println("是否为空\t"+arrayList.isEmpty());
    //查找
        System.out.println("查找s4的下标为\t"+arrayList.indexOf(s4));
    }
}
---------------结果---------------
元素个数为:4
[[name=aaa, age=20], [name=bbb, age=20], [name=ccc, age=20], [name=ddd, age=20]]
[[name=bbb, age=20], [name=ccc, age=20], [name=ddd, age=20]]
[[name=ccc, age=20], [name=ddd, age=20]]
[name=ccc, age=20]
[name=ddd, age=20]
0:	[name=ccc, age=20]
1:	[name=ddd, age=20]
包含学生s3吗	true
包含学生s4吗	true
是否为空	false
查找s4的下标为	1
public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        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 "[name="+name+", age="+age+"]";
    }

    @Override
    public boolean equals(Object obj) {
        //是否是同一个对象
        if(this==obj){
            return true;
        }
        //是否是同为空
        if(obj==null){
            return false;
        }
        //判断是否是Student类
        if(obj instanceof Student){
            Student s =(Student)obj;
            //比较属性
            if(this.name.equals(s.getName()) && this.age==s.getAge()){
                return true;
            }
        }
        //不满足,返回false
        return false;
    }
}
ArrayList源码分析

默认容量大小: DEFAULT_CAPACITY = 10;(添加元素之后,没有添加时为0)

存放元素的数组: 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));//第一次执行相当于ensureExplicitCapacity(10);
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);//当第一次add时,DEFAULT_CAPACITY=10,minCapacity=1
    }
    return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)    //10>0
            grow(minCapacity);
    }
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;  //oldCapacity=0;
        int newCapacity = oldCapacity + (oldCapacity >> 1);  //newCapacity=0+0;
        if (newCapacity - minCapacity < 0)  //0-10 < 0
            newCapacity = minCapacity;  //newCapacity=10;
        if (newCapacity - MAX_ARRAY_SIZE > 0)  //MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8  肯定是假
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);  //创建新数组,长度为10,内容为空
    }

当添加在10个以内的时候,容量为10,到存储第11个时,扩容为15个,之后每次扩容大小为最大容量的1.5倍。

Vector集合(了解)
  • 数组结构实现,查询快、增删慢;
  • JDK1.0版本,运行效率慢、线程安全。
import java.util.Enumeration;
import java.util.Vector;

public class Application {
    public static void main(String[] args) {
        //创建集合
        Vector vector = new Vector();
        //添加元素
        vector.add("aaa");
        vector.add("bbb");
        vector.add("ccc");
        System.out.println("元素个数为:"+vector.size());
        //删除
        //vector.remove(0);
        //vector.remove("ccc");
        //vector.clear();
        //枚举器遍历
        Enumeration elements = vector.elements();
        while (elements.hasMoreElements()){
            System.out.println(elements.nextElement());
        }
        System.out.println("是否包含 ccc :"+vector.contains("ccc"));
        System.out.println("是否为空:"+vector.isEmpty());
        //其他方法
        System.out.println("第一个元素:"+vector.firstElement());
        System.out.println("最后一个元素:"+vector.lastElement());
        System.out.println("获取0号元素:"+vector.elementAt(0));//获取元素
        System.out.println("获取2号元素:"+vector.get(2));//获取元素
    }
}
---------------结果---------------
元素个数为:3
aaa
bbb
ccc
是否包含 ccc :true
是否为空:false
第一个元素:aaa
最后一个元素:ccc
获取0号元素:aaa
获取2号元素:ccc
LinkedList集合
  • 双向链表结构实现,增删快,查询慢。
import java.util.*;
public class Application {
    public static void main(String[] args) {
    //创建集合
        LinkedList linkedList = new LinkedList();
        Student s1 = new Student("张三", 20);
        Student s2 = new Student("李四", 20);
        Student s3 = new Student("王五", 20);
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        linkedList.add(s3);
        System.out.println("元素个数为:"+linkedList.size());
        System.out.println(linkedList);
    //删除
        linkedList.remove(new Student("王五", 20));
        System.out.println(linkedList);
        //linkedList.clear();
    //遍历
        System.out.println("-----------for-----------");
        for(int i=0;i<linkedList.size();i++){
            System.out.println(linkedList.get(i));
        }
        System.out.println("---------增强for----------");
        for (Object o : linkedList) {
            //System.out.println((Student) o);
            System.out.println(o);
        }
        System.out.println("---------迭代器----------");
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()){
            //System.out.println((Student) iterator.next());
            System.out.println(iterator.next());
        }
        System.out.println("---------list迭代器----------");
        ListIterator listIterator = linkedList.listIterator();
        while (listIterator.hasNext()){
            System.out.println(listIterator.nextIndex()+"\t"+listIterator.next());
        }
    //判断
        System.out.println("是否包含s2:"+linkedList.contains(s2));
        System.out.println("是否为空:"+linkedList.isEmpty());
    //获取
        System.out.println("获取s2所在下标:"+linkedList.indexOf(s2));
    }
}
---------------结果---------------
元素个数为:4
[[name=张三, age=20], [name=李四, age=20], [name=王五, age=20], [name=王五, age=20]]
[[name=张三, age=20], [name=李四, age=20], [name=王五, age=20]]
-----------for-----------
[name=张三, age=20]
[name=李四, age=20]
[name=王五, age=20]
---------增强for----------
[name=张三, age=20]
[name=李四, age=20]
[name=王五, age=20]
---------迭代器----------
[name=张三, age=20]
[name=李四, age=20]
[name=王五, age=20]
---------list迭代器----------
0	[name=张三, age=20]
1	[name=李四, age=20]
2	[name=王五, age=20]
是否包含s2:true
是否为空:false
获取s2所在下标:1
LinkedList源码分析

创建集合时:

transient int size = 0; 集合大小=0,还没有添加
transient Node first; 指向第一个元素,为空
transient Node last; 指向最后一个元素,为空

第一次添加时:

public boolean add(E e) {
        linkLast(e);//链接到最后一个位置
        return true;
    }
void linkLast(E e) {
    final Node<E> l = last; //添加时为一个节点,类型就是这个Node
    final Node<E> newNode = new Node<>(l, e, null);// l为prev=null ,e为当前数据,null为next  
    //当创建第二个的时候,l=头节点,把prev赋值为头节点
    last = newNode;//第一次执行时将尾赋值为刚创建的节点 
    if (l == null)
        first = newNode;//第一次执行时把头也赋值为第一个创建的节点,
    else
        l.next = newNode;//第二次创建时,头的next指向第二个节点(双向链表)
    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;
    }
}
ArrayList和LinkedList的区别

ArrayList是一个数组
LinkedList是一个双向链表,结构差不多如下图所示:
在这里插入图片描述ArrayList:必须开辟连续空间,查询快,增删慢。
LinkedList:无需开辟连续空间,查询慢,增删快。

另几篇链接:
JAVA集合框架(一)链接
JAVA集合框架(三)链接
JAVA集合框架(四)链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值