ArrayList和LinkedList的区别

本文详细分析了Java中ArrayList和LinkedList两种数据结构的底层实现,包括它们在内存使用、查询和增删操作上的特点,并讨论了各自适用的应用场景:ArrayList适合查询频繁的场景,而LinkedList则适用于频繁增删的场景。
摘要由CSDN通过智能技术生成

1.底层实现数据结构不同:

ArrayList底层用数组实现,占用一片连续的内存空间,查询快。

LinkedList底层用双链表实现,占用的内存空间不一定连续,增删快。

1.1ArrayList源码

import java.util.Arrays;

public class MyArrayList <T>{
    private Object Mydata[] ={};
    private static int size = 0;
    private static final int DEFAULT_CAPACITY = 10;
    public MyArrayList() {

    }
    public MyArrayList(int capacity) throws Exception {
        if(capacity>0){
            Mydata = new Object[capacity];
        }else if(capacity<0){
            throw new Exception("集合的初始容量不可以是负数");
        }
    }

    public boolean add(Object obj){
        ensure(size+1);
        this.Mydata[size++]=obj;

        return true;
    }

    public boolean add(int index,Object obj) throws Exception {
        if(check_rangeIndex(index)){

            throw new Exception("添加索引位置不合法");
        }
        ensure(size+1);

        int num = size-1-index+1;
        if(num>0){
            System.arraycopy(Mydata,index, Mydata,index+1 , num);
        }
//        for(int i=size-1;i>=index;i--){
//            Mydata[i+1] = Mydata[i];
//        }
        Mydata[index]=obj;
        size++;
        return true;
    }


    public Object remove(int index) throws Exception {
        if(check_rangeIndex1(index)){

            throw new Exception("删除索引位置不合法");
        }
        Object old = Mydata[index];

//        for(int i = index+1;i<size;i++) {
//            Mydata[i-1] = Mydata[i];
//        }
        int num = this.size-1-index;
        if(num>0)
        System.arraycopy(Mydata, index+1, Mydata,index,num);
        Mydata[size-1]=null;
        size--;
        return old;
    }

    public boolean remove(Object obj) throws Exception {
        if(obj == null){
            for(int i=0;i<size;i++){
                if(Mydata[i] == null){
                    remove(i);
                    return true;
                }
            }
        }else{
            for(int i=0;i<size;i++){
                if(obj.equals(Mydata[i])){
                    remove(i);
                    return true;
                }
            }
        }
        return false;
    }

    public Object get(int index) throws Exception {
        if(check_rangeIndex1(index)){
            throw new Exception("查询索引位置不合法");
        }
        return Mydata[index];
    }

    public Object set(int index,Object obj) throws Exception {
        if(check_rangeIndex1(index)){
            throw new Exception("修改索引位置不合法");
        }
        Object old = Mydata[index];
        Mydata[index] = obj;

        return old;
    }

    public int size(){
        return this.size;
    }

    @Override
    public String toString() {
        String s="[";
        for(int i=0;i<size;i++){
            s+=Mydata[i];
            if(i<size-1)s+=",";
        }
        s+="]";
        return s;
    }

    private boolean check_rangeIndex1(int index) {
        return index<0 || index>=size;
    }

    private boolean check_rangeIndex(int index) {
        return index<0 || index>size;
    }



    private void ensure(int min_capacity) {
        ensure_grow(cal_capacity(min_capacity,MyArrayList.DEFAULT_CAPACITY));
    }

    private void ensure_grow(int min_capacity) {
        if(min_capacity-this.Mydata.length>0){
            grow(min_capacity);
        }
    }

    private void grow(int minCapacity) {
        int oldCapacity = this.Mydata.length;
        int newCapacity = oldCapacity + (oldCapacity>>1);

        if(newCapacity<minCapacity){
            newCapacity = minCapacity;
        }

//        Object newdata[] = new Object[newCapacity];
//        if(Mydata.length>0)
//        System.arraycopy(Mydata,0,newdata, 0, Mydata.length);
        Mydata = Arrays.copyOf(Mydata,newCapacity);
//        for(int i=0;i<Mydata.length;i++){
//            newdata[i]=Mydata[i];
//        }

        //Mydata = newdata;
    }

    private int cal_capacity(int minCapacity, int defaultCapacity) {
        if (Mydata.length==0) {
            return Math.max(minCapacity, defaultCapacity);
        }
        return minCapacity;
    }


}

1.2LinkedList源码

public class MyLinkedList<E> {
    private static int size = 0;
    private static int modCounts = 0;
    Node first = null;
    Node last = null;
    class Node<E>{
        //LinkedList
        E item;
        Node<E> pre;
        Node<E> next;

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

    public MyLinkedList(){

    }

    Node node(int index){
        Node find = null;
        if(index< (size>>1)){
            Node f = first;
            for(int i=0;i<index;i++){
                f = f.next;
            }
            find = f;
        }else{
            Node l = last;
            for(int i=size-1;i>index;i--){
                l = l.pre;
            }
            find = l;
        }

        return find;
    }

    void linkLast(E e){
        final Node l = last;
        final Node newnode = new Node(last, e, null);
        last = newnode;
        if(l==null){
            first = newnode;
        }else{
            l.next = newnode;
        }
        size++;
        modCounts++;
    }
    void linkFirst(E e){
        final Node f = first;
        final Node newnode = new Node(null, e, first);
        first = newnode;

        if(f==null){
            last = newnode;
        }else{
            f.pre = newnode;
        }
        size++;
        modCounts++;
    }

    void linkBefore(E e,Node next) {
        final Node pre = next.pre;
        Node<E> newnode = new Node<>(pre, e, next);
        if(pre == null){
           first = newnode;
        }else{
            pre.next = newnode;
        }
        if(next==null){
            last = newnode;
        }else {
            next.pre = newnode;
        }
        size++;
        modCounts++;
    }

    public void addFirst(E e){
        linkFirst(e);
    }

    public void addLast(E e){
        linkLast(e);
    }

    public void add(int index,E e) throws Exception {
        if(index_illegal1(index)){
            throw new Exception("索引位置不合法");
        }
        if(index==size){
            linkLast(e);
        }
        else{
        linkBefore(e,node(index));
        }
    }

    private boolean index_illegal1(int index) {
        return index<0 || index>size;
    }

    public void add(E e){
        linkLast(e);
    }

    public int size(){
        return size;
    }

    private E unLinkLast(Node<E> l){
        E olditem = l.item;
        Node<E> pre = l.pre;
        l.pre = null;
        l.item = null;
        last = pre;
        if(pre==null){
            first = null;
        }else{
            pre.next = null;
        }
        size--;
        modCounts++;

        return olditem;
    }

    public E removeLast() throws Exception {
        final Node l = last;
        if(l==null){
            throw new Exception("删除的元素不能是空");
        }else{
            return (E) unLinkLast(l);
        }
    }
    public E removeFirst() throws Exception {
        final Node f = first;
        if(f==null){
            throw new Exception("删除的元素不能是空");
        }else{
            return (E) unLinkFirst(f);
        }
    }

    public E remove(int index) throws Exception {
        if(index_illegal(index)){
            throw new Exception("索引位置不合法");
        }
        return (E) unLink(node(index));
    }

    public E getLast() throws Exception {
        if(last==null){
            throw new Exception("获取元素为空");
        }
        return (E) last.item;
    }
    public E getFirst() throws Exception {
        if(first==null){
            throw new Exception("获取元素为空");
        }
        return (E) first.item;
    }


    public boolean remove(Object obj){
        if(obj==null){
            Node now = first;
            for(int i=0;i<size;i++){
                if(now.item == null){
                    unLink(node(i));
                    return true;
                }
                now = now.next;
            }
        }else{
            Node now = first;
            for(int i=0;i<size;i++){
                if(now.item.equals(obj)){
                    unLink(node(i));
                    return true;
                }
                now = now.next;
            }
        }

        return false;
    }

    public E get(int index) throws Exception {
        if(index_illegal(index)){
            throw new Exception("索引位置不合法");
        }
        return (E) node(index).item;
    }

    public E set(int index,E e) throws Exception {
        if(index_illegal(index)){
            throw new Exception("索引位置不合法");
        }
        Node node = node(index);
        E old = (E) node.item;
        node.item = e;

        return old;
    }

    private E unLinkFirst(Node<E> f) {
        E olditem = f.item;
        final Node next = f.next;
        f.item =  null;
        f.next = null;
        first = next;
        if(next == null){
            last = null;
        }else{
          next.pre = null;
        }
        size--;
        modCounts++;
        return olditem;
    }

    private E unLink(Node<E> m){
        E olditem = m.item;
        final Node pre = m.pre;
        final Node next = m.next;
        m.item = null;
        m.pre = null;
        m.next = null;
        if(pre==null){
            first = next;
        }
        else{
            pre.next = next;
        }

        if(next==null){
            last = pre;
        }
        else {
            next.pre = pre;
        }

        size--;
        modCounts++;
        return olditem;
    }



    private boolean index_illegal(int index) {
        return index<0 || index >= size;
    }

    @Override
    public String toString() {
        String s="[";
        Node now = first;
        for(int i=0;i<size;i++){
            s+=now.item;
            if(i<size-1)
                s+=",";
            now = now.next;
        }
        s+="]";
        return s;
    }
}

2.应用场景不同:

ArrayList查询快,增删慢,适合查询多的场合;

LinkedList增删快,查询慢,适合增删多的场景;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值