栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JavaSE:List以及ArrayList 和 LinkedList

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaSE:List以及ArrayList 和 LinkedList

目录

List接口特有的常用方法

ArrayList

集合ArrayList 的构造方法

将 ArrayList 转换为线程安全的方法

LinkedList

LinkedList构造方法

ArrayList 和 Array 的区别

ArrayList 和 LinkedList 的区别

Vector


List接口特有的常用方法

List存储元素特点:有序可重复,且List集合中元素有下标(从0开始)

(1)void add(int index,E element) 在列表的指定位置插入指定元素

index索引即是该List中的下标,element为你插入的元素,如下图:

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

public class List方法 {
    public static void main(String[] args) {
        List arr = new ArrayList();
        arr.add("a");
        arr.add("b");
        arr.add("c");
        //调用List中特有的add方法
        arr.add(2,"java");
        Iterator it = arr.iterator();
        while (it.hasNext()){
            Object ob = it.next();
            System.out.println(ob);
        }
    }
}

结果图:

(2)E set(int index,E element) 用指定元素替换列表中指定位置的元素

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

public class List方法 {
    public static void main(String[] args) {
        List arr = new ArrayList();
        arr.add("a");
        arr.add("b");
        arr.add("c");
        arr.add("a");
        System.out.println("初始的元素序列为:");
        for( int i = 0 ; i < arr.size() ; i++){
            Object obj = arr.get(i);
            System.out.println(obj);
        }
        //替换指定位置下标的元素
        arr.set(2,"java");
        System.out.println("替换后后元素序列为:");
        for( int i = 0 ; i < arr.size() ; i++){
            Object obj = arr.get(i);
            System.out.println(obj);
        }
    }
}

结果图:

 (3)E get(int index) 返回列表中指定位置的元素

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

public class List方法 {
    public static void main(String[] args) {
        List arr = new ArrayList();
        arr.add("a");
        arr.add("b");
        arr.add("c");
        //调用List中特有的add方法
        arr.add(2,"java");
        for( int i =0 ; i< arr.size(); i++){
            //调用get方法
            Object obj = arr.get(i);
            System.out.println(obj);
        }
    }
}

结果图:

(4) int indexOf(Object o) 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回-1。

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

public class List方法 {
    public static void main(String[] args) {
        List arr = new ArrayList();
        arr.add("a");
        arr.add("b");
        arr.add("c");
        arr.add("a");
        //获取 “a” 第一次出现时的索引
        System.out.println(arr.indexOf("a"));
        //获取 “a” 最后一次出现时的索引
        System.out.println(arr.lastIndexOf("a"));
        //如果没有指定元素时
        System.out.println(arr.indexOf("java"));
    }
}

结果图:

(5)E remove(int index) 移除列表中指定位置的元素

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

public class List方法 {
    public static void main(String[] args) {
        List arr = new ArrayList();
        arr.add("a");
        arr.add("b");
        arr.add("c");
        arr.add("a");
        System.out.println("初始的元素序列为:");
        for( int i = 0 ; i < arr.size() ; i++){
            Object obj = arr.get(i);
            System.out.println(obj);
        }
        //删除指定位置下标的元素
        arr.remove(3);
        System.out.println("删除后元素序列为:");
        for( int i = 0 ; i < arr.size() ; i++){
            Object obj = arr.get(i);
            System.out.println(obj);
        }
    }
}

结果图:

ArrayList

(1)ArrayList 初始化容量为0,可以指定容量,未添加元素时为一个空数组,添加元素后默认容量由0 变为10

    
    private static final int DEFAULT_CAPACITY = 10;

(2)集合底层是一个Object类型的数组

    
    private static final Object[] EMPTY_ELEMENTDATA = {};

(3)会自动扩容1.5倍

先将旧容量右移1位,再加上旧容量就得到了新容量,正数右移1位相当于除以2,在该基础上加旧容量,则等价于新容量 = 旧容量 * 1.5,所以才有ArrayList每次扩容为旧容量的1.5倍的说法,最后调用Arrays.copyOf()方法进行拷贝,并将elementData指向新数组,而旧数组因为没有引用指向它,很快就会被垃圾收集器回收掉

    
    private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            int newCapacity = ArraysSupport.newLength(oldCapacity,
                    minCapacity - oldCapacity, 
                    oldCapacity >> 1           );
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }

集合ArrayList 的构造方法
ArrayList()构造一个初始容量为十的空列表
ArrayList(int initialCapacity)构造具有指定初始容量的空列表
ArrayList(Collection c)构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序

(1)无参构造

    transient Object[] elementData;    
 
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
 
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

(2)指定容量ArrayList(int initialCapacity)

        入参是ArrayList初始化容量,如果容量小于0就抛错,否则实例化一个Object对象数组赋值给全局变量elementData

public ArrayList(int initialCapacity) {
    // 容量大于0,按照指定的容量初始化数组
    if (initialCapacity > 0) {
        // 创建一个数组,且指定长度为initialCapacity
        this.elementData = new Object[initialCapacity];
    // 如果initialCapacity容量为0,把EMPTY_ELEMENTDATA的地址赋值给elementData
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    // 容量小于0,抛非法异常    
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
    }
}

(3)指定集合ArrayList(Collection c)

        传入Collection集合的对象,将传入的集合对象转为数组,然后给size赋值,判断如果传入的对象数组不是Object[],则转为Object[]

public ArrayList(Collection c) {
    // 将给定的集合对象转成数组,且将数组的地址赋值给elementData
    elementData = c.toArray();
    // 将elementData的长度赋值给集合长度size,且判断是否不等于 0
    if ((size = elementData.length) != 0) {
        // 判断elementData 和 Object[] 是否为不一样的类型
        // c.toArray()数组不是object数组进行转换成Object[]
        // 每个集合的toarray()的实现方法不一样,所以需要判断一下,如果不是Object[].class类型,那么就需要使用ArrayList中的方法去改造一下。
        // elementData.getClass()到底是什么类型的?
        if (elementData.getClass() != Object[].class)
            // 转换Object[] 
            // 如果不一样,使用Arrays的copyOf方法进行元素的拷贝
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // 给定的数组的长度为0,用空数组代替
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

将 ArrayList 转换为线程安全的方法

Collections.synchronizedList()

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


public class ArrayListTest {
    public static void main(String[] args) {
        //默认容量为10,此时线程是不安全的
        List list1 = new ArrayList();
        //变成线程安全的方法
        Collections.synchronizedList(list1);
        
        list1.add(1);
        list1.add(1);
        list1.add(1);
        list1.add(1);
    }
}

LinkedList

(1)LinkedList 的底层是一个双向链表(包含两个指针的,pre指向前一个节点,next指向后一个节点,但是第一个节点head的pre指向null,最后一个节点的tail指向null)

注意:JDK1.6时为双向循环链表(第一个节点的pre指向最后一个节点,最后一个节点的next指向第一个节点,也形成一个“环”)而在JDK1.7以及往后版本,底层实现为双向链表

JDK1.8源码

public class LinkedList
    extends AbstractSequentialList
    implements List, Deque, Cloneable, java.io.Serializable
{
    //长度
    transient int size = 0;
    //指向头结点
    transient Node first;
    //指向尾结点
    transient Node last;
}

(2)元素在空间存储上的内存不连续,随机增删元素时,不会有大量元素移动,所以增删效率高,查找效率低

LinkedList构造方法

(1)无参构造(public LinkedList())

    
    public LinkedList() {
    }

(2)有参构造(public LinkedList(Collection c))

    
    public LinkedList(Collection c) {
        this();
        addAll(c);
    }

ArrayList 和 Array 的区别
Array 可以容纳基本类型和对象,而 ArrayList 只能容纳对象。 Array 是指定大小的,而 ArrayList 大小是固定

ArrayList 和 LinkedList 的区别
(1)ArrrayList 底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问 (2)使用下标访问一个元素, ArrayList 的时间复杂 度是 O(1) ,而 LinkedList 是 O(n)

Vector

(1)Vector 底层也是一个数组,初始化容量为10

(2)扩容后,容量为原容量的两倍

(3)Vector 中的所有方法都是线程同步的,线程是安全的

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/841314.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号