java基础三:Arraylist和LinkList区别

ArrayList和LinkedList的区别

只有有以下几点:
1. ArrayList是基于动态数组的数据结构,LinkedList是基于双向链表的数据结构。
2. 对于随机访问get和set,ArrayList要优于LinkedList,因为LinkedList要移动指针。
3. 对于新增和删除操作add和remove,LinkedList比较有优势,因为ArrayList要移动数据。

下面写一段代码测试下:

public void compute(View view)
    {
        ArrayList arrayList = new ArrayList();
        LinkedList linkedList = new LinkedList();
        Object object = new Object();
        //add test
        long start = System.currentTimeMillis();
        for(int i = 0;i < 50000;i++)
        {
            arrayList.add(0,object);
        }
        Log.e("DataStuc","arraylist add 50000,time = "+(System.currentTimeMillis() - start));

       start = System.currentTimeMillis();
        for(int i = 0;i < 50000;i++)
        {
            linkedList.add(0,object);
        }
        Log.e("DataStuc","linkedList add 50000,time = "+(System.currentTimeMillis() - start));

        //get test
        start = System.currentTimeMillis();
        for(int i = 0;i < 50000;i++)
        {
            arrayList.get(i);
        }
        Log.e("DataStuc","arraylist get 50000,time = "+(System.currentTimeMillis() - start));

       start = System.currentTimeMillis();
        for(int i = 0;i < 50000;i++)
        {
            linkedList.get(i);
        }
        Log.e("DataStuc","linkedList get 50000,time = "+(System.currentTimeMillis() - start));

        //set test
        start = System.currentTimeMillis();
        for(int i = 0;i < 50000;i++)
        {
            arrayList.set(i,object);
        }
        Log.e("DataStuc","arraylist set 50000,time = "+(System.currentTimeMillis() - start));

       start = System.currentTimeMillis();
        for(int i = 0;i < 50000;i++)
        {
            linkedList.set(i,object);
        }
        Log.e("DataStuc","linkedList set 50000,time = "+(System.currentTimeMillis() - start));
    }

下面是log:

12-11 10:39:19.520 13995-13995/com.biyou.datastruction E/DataStuc: arraylist add 50000,time = 5254
12-11 10:39:19.680 13995-13995/com.biyou.datastruction E/DataStuc: linkedList add 50000,time = 154
12-11 10:39:19.680 13995-13995/com.biyou.datastruction E/DataStuc: arraylist get 50000,time = 4
12-11 10:39:34.840 13995-13995/com.biyou.datastruction E/DataStuc: linkedList get 50000,time = 15157
12-11 10:39:34.840 13995-13995/com.biyou.datastruction E/DataStuc: arraylist set 50000,time = 4
12-11 10:39:50.040 13995-13995/com.biyou.datastruction E/DataStuc: linkedList set 50000,time = 15199

可以看出来ArrayList更适合读取数据,LinkedList更适合添加和删除数据。

ArrayList内部是使用可増长数组实现的,所以是用get和set方法是花费常数时间的,但是如果插入元素和删除元素,除非插入和删除的位置都在表末尾,否则代码开销会很大,因为里面需要数组的移动。
LinkedList是使用双链表实现的,所以get会非常消耗资源,LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端,但是插入和删除元素花费常数时间。

单向链表基本介绍

链表是一种数据结构,和数组同级。比如,Java中我们使用的ArrayList,其实现原理是数组。而LinkedList的实现原理就是链表了。
链表在进行循环遍历时效率不高,但是插入和删除时优势明显。下面对单向链表做一个介绍。
单向链表是一种线性表,实际上是由节点(Node)组成的,一个链表拥有不定数量的节点。
其数据在内存中存储是不连续的,它存储的数据分散在内存中,每个结点只能也只有它能知道下一个结点的存储位置。由N各节点(Node)组成单向链表,每一个Node记录本Node的数据及下一个Node。
向外暴露的只有一个头节点(Head),我们对链表的所有操作,都是直接或者间接地通过其头节点来进行的。

这里写图片描述

上图中最左边的节点即为头结点(Head),但是添加节点的顺序是从右向左的,添加的新节点会被作为新节点。最先添加的节点对下一节点的引用可以为空。引用是引用下一个节点而非下一个节点的对象。因为有着不断的引用,所以头节点就可以操作所有节点了。
下图描述了单向链表存储情况。存储是分散的,每一个节点只要记录下一节点,就把所有数据串了起来,形成了一个单向链表。

图2

节点(Node)是由一个需要储存的对象及对下一个节点的引用组成的。也就是说,节点拥有两个成员:储存的对象、对下一个节点的引用。下面图是具体的说明:

这里写图片描述

链表种类

单向链表或者单链表

单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向表中的下一个节点,而最后一个节点则指向一个空值NULL。

单向链表只可向一个方向遍历。

查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。也可以提前把一个节点的位置另外保存起来,然后直接访问。

双向链表,也叫双链表

双向链表中不仅有指向后一个节点的指针,还有指向前一个节点的指针。第一个节点的”前连接”指向NULL,最后一个节点的”后连接”指向NULL。

这样可以从任何一个节点访问前一个节点,也可以访问后一个节点,以至整个链表。一般是在需要大批量的另外储存数据在链表中的位置的时候用。

由于另外储存了指向链表内容的指针,并且可能会修改相邻的节点,有的时候第一个节点可能会被删除或者在之前添加一个新的节点。这时候就要修改指向首个节点的指针。

有一种方便的可以消除这种特殊情况的方法是在最后一个节点之后、第一个节点之前储存一个永远不会被删除或者移动的虚拟节点,形成一个循环链表。这个虚拟节点之后的节点就是真正的第一个节点。这种情况通常可以用这个虚拟节点直接表示这个链表。

循环链表

在一个循环链表中, 首节点和末节点被连接在一起。这种方式在单向和双向链表中皆可实现。要转换一个循环链表,你开始于任意一个节点然后沿着列表的任一方向直到返回开始的节点。循环链表可以被视为”无头无尾”。

循环链表中第一个节点之前就是最后一个节点,反之亦然。循环链表的无边界使得在这样的链表上设计算法会比普通链表更加容易。对于新加入的节点应该是在第一个节点之前还是最后一个节点之后可以根据实际要求灵活处理,区别不大。

另外有一种模拟的循环链表,就是在访问到最后一个节点之后的时候,手工跳转到第一个节点。访问到第一个节点之前的时候也一样。这样也可以实现循环链表的功能,在直接用循环链表比较麻烦或者可能会出现问题的时候可以用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值