Java数据结构之表的增删对比---ArrayList与LinkedList之一

一、Java_Collections表的实现

  与c不同Java已经实现并封装了现成的表数据结构,顺序表以及链表。

  1、ArrayList是基于数组的实现,因此具有的特点是:1.有索引值方便查找,对于get和set操作花费常数时间,2.但是其缺点是:插入/删除某个数据的代价比较大。

2、LinkedList是基于双链表实现,因此具有的特点是:1.基于链表方便插入与删除操作开销较小,2.但是不方便索引,不管是索引哪一个元素都需要从头开始逐次查找。

就增删操作下面举个简单例子:给出一个表(具体实现未知),将该表中偶数值的项删除,比如该表中的元素为:1,2,3,4,5,调用该方法后得到元素:1,3,5

//-----------------------------------------------------------

//该代码主要是用来说明顺序表与链表在增删上的操作消耗

 1 import java.util.ArrayList;
 2 import java.util.Iterator;
 3 import java.util.LinkedList;
 4 import java.util.List;
 5 import java.util.ListIterator;
 6
 7 /**
 8  * 找到一个表list中偶数值的项,并删除 下面显示逐渐优化的过程 对比顺序表:arrayList与LinkedList。自己把握
 9  *
10  * @author Administrator
11  *
12  */
13 public class RemoveEvens {
14     public static void main(String[] args) {
15         List<Integer> list = new ArrayList<>();
16         list.add(1);
17         list.add(2);
18         list.add(3);
19         list.add(4);
20
21         // removeEvensVer2(list);
22
23         for (int i : list) {
24             System.out.println(i);
25         }
26     }
27
28     // 基础版本
29     /*
30      * 对于ArrayList集合,get方法虽然较快,但是remove的时间消耗为二次时间,
31      * 对于linkedlist集合,暴露两个问题首先是对get的调用效率不是很高因此例程花费二次时间,而且同时对remove
32      * 的调用同样低效,因为要到达i的代价是昂贵的。
33      */
34     public static void removeEvensVer1(List<Integer> list) {
35
36         int i = 0;
37         // 遍历列表,获得每一个元素
38         while (i < list.size()) {
39             // 当前项是偶数,就移除
40             if (list.get(i) % 2 == 0) {
41                 list.remove(i);
42             } else {
43                 i++;
44             }
45         }
46     }
47
48     // 迭代器版本增强版本,避免并发修改异常
49     // 对于linkedlist的迭代器的remove方法只消耗常数时间项,该方法对于arraylist仍是无可救药
50
51     public static void removeEvensVer2(List<Integer> list) {
52         Iterator<Integer> iterator = list.iterator();
53         while (iterator.hasNext()) {
54             if (iterator.next() % 2 == 0) {
55                 iterator.remove();
56             }
57         }
58     }
59
60     // 并发修改异常,一般这里会出现,主要是由于迭代器的引用失效
61     public static void removeEvensVer3(List<Integer> list) {
62         // ListIterator<Integer> listIterator = list.listIterator();
63         //增强for本质上是使用迭代器实现,而list的remove方法导致list发生变化,进一步导致原list的迭代器引用
64         //发生变化,导致并发异常。
65         for (Integer x : list) {
66             if (x % 2 == 0) {
67                 list.remove(x);
68             }
69         }
70     }
71 }
时间: 2024-11-10 02:07:57

Java数据结构之表的增删对比---ArrayList与LinkedList之一的相关文章

java的List接口的实现类 ArrayList,LinkedList,Vector 的区别

Java的List接口有3个实现类,分别是ArrayList.LinkedList.Vector,他们用于存放多个元素,维护元素的次序,而且允许元素重复. 3个具体实现类的区别如下: 1. ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问.数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中.当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制.移动.代价比较高.因此,它

Java数据结构-线性表之顺序表ArrayList

线性表的顺序存储结构,也称为顺序表,指用一段连续的存储单元依次存储线性表中的数据元素. 根据顺序表的特性,我们用数组来实现顺序表,下面是我通过数组实现的Java版本的顺序表. package com.phn.datestructure; /** * @author 潘海南 * @Email [email protected] * @TODO 顺序表 * @date 2015年7月16日 */ public class FOArrayList<E> { // 顺序表长度 private int

Java数据结构-线性表之单链表LinkedList

线性表的链式存储结构,也称之为链式表,链表:链表的存储单元可以连续也可以不连续. 链表中的节点包含数据域和指针域,数据域为存储数据元素信息的域,指针域为存储直接后继位置(一般称为指针)的域. 注意一个头结点和头指针的区别: 头指针: 指向链表的第一个节点的指针,若链表有头结点,则是指向头结点的指针: 头指针具有标识作用,所以常用头指针作为链表的名字: 不论链表是否为空,头指针都不为空: 是链表的必要元素. 头结点: 头结点是为了操作的统一和方便而设立的,放在第一个元素节点的前面,其数据域一般无意

Java数据结构-线性表之静态链表

静态链表的定义: 节点由一个一维数组和一个指针域组成,数组用来存放数据元素,而指针域里面的指针(又称游标)用来指向下一个节点的数组下标.这样的链表称之为静态链表. 链表中的数组第一个和最后一个位置需要特殊处理,不存数据.第一个位置(即数组0下标)的节点的指针用来存放备用链表的第一个节点的数组下标.最后一个位置(即数组长度MaxSize-1下标)的节点的指针用来存放指向有数值的第一个数据元素的数组下标,类似于单链表的头结点. 静态链表的示例图: 下面举一个摘抄自<大话数据结构>的例子,来解释一下

Java数据结构-线性表之栈(顺序栈和链栈)

栈的定义:(特殊的线性表) ??仅在表的一端进行插入和删除的线性表.允许插入.删除的这一端称为栈顶,另一端称为栈底.表中没有元素时称为空栈. ??被称为后进先出的线性表(Last In First Out),简称 LIFO表,或被称为先进后出的线性表(First In Last Out),简称 FILO表. ??栈更具存储方式的不同分为两种:顺序栈和链栈. 顺序栈: 和顺序表一样,顺序栈也采用数组来存放数据元素: 为了保证栈底位置的不变,采用数组下标为0的位置作为顺序栈的栈底. 而栈顶指针的最大

Java数据结构-线性表之队列

队列(Queue)的定义:只允许在一端进行插入另一端进行删除操作的线性表.允许插入的一端称为队尾(rear) ,允许删除的一端称为队头(front). 具有"先进先出"特点. 队列也是线性表,所以也存在顺序结构和链式结构. 顺序队列: 对于队列,入队操作的解释为: (是在队尾追加一个元素,不需要移动任何元素,因此时间复杂度为0(1).) 判断队列是否已满: 如果没满则先给队尾元素赋值; 然后将队尾指针后移一位(对队尾指针赋值,Q->rear = Q->rear+1 ). 出

Java数据结构-线性表之栈的应用-递归及其应用

??递归函数的定义:把一个直接调用自己或通过一系列的调用语句间接地调用自己的函数,称做递归函数(递归函数必须有一个结束的条件,以免陷入无穷尽的递归中). 迭代和递归的区别是: ?(1).迭代使用的是循环结构,递归使用的是选择结构. ?(2).递归能使程序的结构更清晰.更简洁.更容易让人理解,从而减少读懂代码的时间.但是大量的递归调用会建立函数的副本,会耗费大量的时间和内存. ?(3).迭代则不需要反复调用函数和占用额外的内存.因此我们应该视不同情况选择不同的代码实现方式. 下面解释一下怎么使用栈

Java数据结构-线性表之链表应用-检测链表是否有环

??如何检测一个链表是否有环?这个是一个出现频率较高的面试题. ??如下是一个含有环的链表. (图片来自http://www.nowamagic.net/librarys/veda/detail/2245 一个有很多关于数据结构的文章的网站,还有其他的资料,可以看看) 我这里解题的方法有三种: 快慢指针方法:两个速度不一样的指针遍历总会相遇: 利用环的顶点数和边相等的关系: 两个指针遍历判断步数是否相等. ??为了实现检查链表是否含有环的情况,我们需要先构建出一个含有环的链表. ??于是乎我在之

线性表之何时使用ArrayList、LinkedList?

前言 线性表不仅可以存储重复的元素,而且可以指定元素存储的位置并根据下表访问元素. List接口的两个具体实现:数组线性表类ArrayList.链表类LinkedList. ArrayList ArrayList使用数组存储元素,这个数组是动态创建的.如果元素个数超过了数组的容量,就会创建一个更大的数组,并将当前数组中的所有元素都复制到新数组中.另外需要注意的是,ArrayList容量可能根据元素的增加而自动增大,但是不能自动减少.可以使用trimToSize()将数组容量减少到线性表大小. L