用java的数组实现静态链表和JDK1.6自带的linkedlist做比较,经过测试(平台都是windows),发现如下结果:
由于java的linkedlist是不定长的,如果算上构造百万级list的时间,再加上遍历的时间,那么
速度明显比如静态链表慢1/2左右
如果将2个链表先填充满值,再进行遍历,计算遍历的时间,则发现JDK的linkedlist要慢1/3左右
代码如下:(静态链表)
package algorithms;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* 静态链表实现
*
* @author Alucard Wang
*
*/
public class StaticList<T> {
public static class Element<T> {
/*
* 数据对象
*/
public T data;
/*
* 游标
*/
public int cur;
}
private int maxsize = 100;
private Element<T>[] space = null;
// 链表头为space[maxsize-1];
private int r = maxsize - 1;
public StaticList(int maxsize) {
this.maxsize = maxsize;
r = maxsize - 1;
space = new Element[maxsize];
initSpace();
}
// 初始化空间
private void initSpace() {
for (int i = 0; i < maxsize - 2; ++i) {
space[i] = new Element<T>();
space[i].cur = i + 1;
}
space[maxsize - 2] = new Element<T>();
space[maxsize - 2].cur = 0;
// 头结点
space[maxsize - 1] = new Element<T>();
space[maxsize - 1].cur = 0;
}
// 分配空间,返回0认为已经没有可用空间
private int malloc() {
int i = space[0].cur;
if (i != 0) {
space[0].cur = space[i].cur;
}
return i;
}
// 回收空间,将下标为k的结点回收
private void free(int k) {
space[k].cur = space[0].cur;
space[0].cur = k;
}
//增加一个结点
public void add(T obj) throws Exception {
int i = malloc();
if (0 == i) {
throw new Exception("verflow!");
} else {
space[r].cur = i;
r = i;
// 尾结点为0
space[r].cur = 0;
space[r].data = obj;
}
}
// i 为 index
public Element get(int i) {
int p = maxsize - 1;
int j = 0;
while (space[p].cur != 0 && j < i) {
p = space[p].cur;
++j;
}
if (j != i) {
return null;
}
return space[p];
}
//删除一个结点
public Element delete(int i) throws Exception {
int p = maxsize - 1;
int j = 0;
while (space[p].cur != 0 && j < i - 1) {
p = space[p].cur;
++j;
}
if (j != i - 1) {
return null;
}
int q = space[p].cur;
space[p].cur = space[q].cur;
free(q);
return space[q];
}
//下一个结点
public Element<T> next(Element<T> e) {
if (e.cur != 0) {
return space[e.cur];
} else {
return null;
}
}
//清空
public void clear() {
initSpace();
}
public static void main(String[] args) throws Exception {
System.out.println("Please enter the linklist number:");
System.out.println("0: static linked list");
System.out.println("1: jdk linked list");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String methodNo = br.readLine();
System.out.println("Please enter the linklist max size");
String maxsizeNo = br.readLine();
int method = Integer.valueOf(methodNo);
int maxsize = Integer.valueOf(maxsizeNo);
System.out.println("============== test performance!!! 先构造,再计算遍历时间========================");
final int COUNT = maxsize-2;
List<String> javaList = null;
StaticList<String> slist = null;
if(method == 1) {
javaList = new LinkedList<String>();
for(int i=0; i<COUNT; i++) {
javaList.add(String.valueOf(i));
}
}
else {
slist = new StaticList<String>(maxsize);
for(int i=0; i<COUNT; i++) {
slist.add(String.valueOf(i));
}
}
Calendar ca = Calendar.getInstance();
long begin = ca.getTimeInMillis();
if (method == 0) {
Element<String> se = slist.next(slist.get(0));
while (se != null) {
se = slist.next(se);
}
}else {
Iterator<String> iter = javaList.iterator();
while(iter.hasNext()) {
iter.next();
}
}
System.out.println(Calendar.getInstance().getTimeInMillis() - begin);
System.out.println("finish!");
}
}
经测试(900000),可以看到
静态链表:
Please enter the linklist number:
0: static linked list
1: jdk linked list
0
Please enter the linklist max size
900000
============== test performance!!! 先构造,再计算遍历时间========================
16
finish!
JDK linkedlist:
Please enter the linklist number:
0: static linked list
1: jdk linked list
1
Please enter the linklist max size
900000
============== test performance!!! 先构造,再计算遍历时间========================
62
finish!
如果先计算构造+遍历的时间,则静态链表为:
Please enter the linklist number:
0: static linked list
1: jdk linked list
0
Please enter the linklist max size
900000
============== test performance!!! 计算遍历+构造时间========================
719
finish!
JDK linkedlist为:
Please enter the linklist number:
0: static linked list
1: jdk linked list
1
Please enter the linklist max size
900000
============== test performance!!! 计算遍历+构造时间========================
1125
finish!
是否我的测试方法有误或者有其他的问题,如果不是,则在某些场景下,是否能用静态链表来代替JDK呢?
分享到:
相关推荐
而`LinkedList`通过双向链表实现,插入和删除速度快,但访问元素速度慢。 `Set`接口不允许元素重复,`HashSet`是最常见的实现,它基于哈希表(HashMap)实现。元素的添加、删除和查找都依赖于对象的哈希值,因此...
- 空间分配:数组静态分配有固定大小,动态分配可能导致移动元素,链表更灵活。 8. **Map 集合遍历方式**: - 键找值遍历:通过键找到对应的值进行遍历。 - 键值对对象集合遍历:获取 Entry 集合,使用迭代器。 ...
signByIF.java 用if语句实现符号函数示例 triangleStar.java 输出一个由*组成的直角三角形 upperToLowCase.java 大写转换成小写 variableScopeExample.java 变量使用范围示例 第3章 示例描述:本章学习对象和类...
ArrayList 是基于数组实现的,LinkedList 是基于双链表实现的。ArrayList 的随机访问集合元素时性能较好,因为可以直接返回数组中 index 位置的元素。LinkedList 的随机访问集合元素时性能较差,因为需要在双向列表...
在JDK1.8中,`HashMap`进行了优化,采用了数组+链表+红黑树的数据结构。当链表长度超过8且桶的大小超过64时,链表会转换为红黑树,从而提高了查找、插入和删除的效率。 8、**ConcurrentHashMap的优化**: `...
4. **ArrayList 和 LinkedList**: 在尾部添加元素,ArrayList 的效率通常更高,因为 ArrayList 是基于动态增长的数组,而 LinkedList 是链表结构,添加元素需要遍历链表。 5. **equals 和 hashCode**:当自定义类...
HashMap是非线程安全的,它的数据结构基于数组和链表实现,它可以根据需要自动扩容。当HashMap中的元素数量超过阈值时,会自动进行扩容操作,容量扩大会按照1倍来增加,并重新计算阈值。HashMap在处理哈希冲突时,会...
ArrayList基于动态数组实现,查询速度快,尾部插入和删除也较快,但中间插入和删除的时间复杂度较高。LinkedList使用链表结构,头尾操作高效,但在链表中间进行操作则效率较低。 Map接口是key-value存储的集合,不...
- 在JDK 1.7及之前的版本中,HashMap是基于Entry数组实现的,使用链表来处理哈希冲突,即在同一个数组位置上,用链表存储多个Entry对象。 - 在JDK 1.8及之后的版本中,当链表长度大于等于阈值(默认是8)并且...
List接口提供了有序的集合,并允许重复元素,具体实现包括ArrayList(基于动态数组实现)、Vector(线程安全的数组实现,已较少使用)、LinkedList(基于链表实现)。Set接口提供了不允许重复元素的集合,具体实现...
- HashMap:JDK8之前是数组+链表,JDK8后链表过长会转换为红黑树,提高查找效率。 - LinkedHashMap:在HashMap基础上增加了双向链表,保持插入顺序或访问顺序。 - Hashtable:类似于HashMap,但线程安全,不支持...
队列有多种实现,如循环数组和链表,`Deque`接口支持双端队列操作。优先级队列(PriorityQueue)按优先级顺序排列元素。 5. **内部类**:内部类的实例化需要外部类的实例,如果内部类是静态的,就不需要。在你的...
**LinkedList** 基于链表实现,支持快速增删元素: - `add(E e)`:在末尾添加元素。 - `addFirst(E e)`:在开头添加元素。 - `addLast(E e)`:在末尾添加元素。 - `getFirst()`:获取第一个元素。 - `getLast()`:...
另外,Java提供了丰富的API,其中 Arrays 类提供了许多处理数组的静态方法,使得操作数组变得更为简便。Java的集合框架也是学习过程中的重点,它包含了List、Set和Map等数据结构的实现。 Java语言基础编程中还包括...
HashMap内部使用了数组和链表(JDK1.8后引入了红黑树优化)的组合结构,通过哈希函数计算元素的存储位置。当哈希冲突时,元素会被放在链表或红黑树中。HashMap的初始容量通常是16,且每次扩容时容量翻倍。 此外,...
之前的版本使用的是简单的哈希表(数组+链表)结构。当哈希冲突发生时,所有冲突的元素都会形成一条链表。 **关键优化点**: - 当链表长度超过一定阈值(默认为8)且哈希表大小大于64时,链表将会转换成红黑树。 - ...