Java DataStructure-List


        

List

链表是线性表的一种。线性表是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表有两种存储方式,一种是顺序存储结构,另一种是链式存储结构。我们常用的数组就是一种典型的顺序存储结构。

在 List 中,用户可以精确控制列表中每个元素的插入位置,另外用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。 与 Set 不同,List 通常允许重复的元素。 另外 List 是有序集合而 Set 是无序集合。


List中常见的实现类

  • ArrayList 是一个数组队列,相当于动态数组。它由数组实现,随机访问效率高,随机插入、随机删除效率低。

  • LinkedList 是一个双向链表。它也可以被当作堆栈、队列或双端队列进行操作。LinkedList随机访问效率低,但随机插入、随机删除效率高。

  • Vector 是矢量队列,和ArrayList一样,它也是一个动态数组,由数组实现。但是ArrayList是非线程安全的,而Vector是线程安全的。

  • Stack 是栈,它继承于Vector。它的特性是:先进后出(FILO, First In Last Out) —— Stack使用

如何选用ArrayList,Linkedlist,Vector?

1.需要线程安全时,用Vector.

2.不存在线程安金问题时,并且查找较多用Araylist(一般使用它)。

3.不存在线程安金问题时,增加或删除元素较多用LinkedList.

LinkedList

uGdPYt.jpg

常用方法:

方法详解

LinkedList源码学习

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package DataStructure;

import java.util.Iterator;
import java.util.LinkedList;

public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<>();
System.out.println("****************** linkedlist基本操作 *******************");
linkedList.addFirst(0); // 添加元素到列表开头
linkedList.add(1); // 在列表结尾添加元素
linkedList.add(2, 2); // 在指定位置添加元素
linkedList.addLast(3); // 添加元素到列表结尾
System.out.println("LinkedList直接输出:" + linkedList + "\n");

System.out.println("getFirst()获得第一个元素: " + linkedList.getFirst()); // 返回此列表的第一个元素
System.out.println("getLast()获得第最后一个元素: " + linkedList.getLast()); // 返回此列表的最后一个元素
System.out.println("removeFirst()删除第一个元素并返回: " + linkedList.removeFirst()); // 移除并返回此列表的第一个元素
System.out.println("removeLast()删除最后一个元素并返回: " + linkedList.removeLast()); // 移除并返回此列表的最后一个元素
System.out.println("After remove:" + linkedList + "\n");
System.out.println("contains()方法判断列表是否包含1这个元素:" + linkedList.contains(1)); // 判断此列表包含指定元素,如果是,则返回true
System.out.println("该linkedList的大小 : " + linkedList.size() + "\n"); // 返回此列表的元素个数

System.out.println("****************** 位置访问操作 *******************");
linkedList.set(1, 3); // 将此列表中指定位置的元素替换为指定的元素
System.out.println("After set(1, 3):" + linkedList);
System.out.println("get(1)获得指定位置(这里为1)的元素: " + linkedList.get(1) + "\n"); // 返回此列表中指定位置处的元素

System.out.println("****************** Search操作 *******************");
linkedList.add(3);
System.out.println("indexOf(3): " + linkedList.indexOf(3)); // 返回此列表中首次出现的指定元素的索引
System.out.println("lastIndexOf(3): " + linkedList.lastIndexOf(3) + "\n");// 返回此列表中最后出现的指定元素的索引

System.out.println("****************** 遍历操作 *******************");
linkedList.clear();
for (int i = 0; i < 100000; i++) {
linkedList.add(i);
}
// 迭代器遍历
long start = System.currentTimeMillis();
Iterator<Integer> iterator = linkedList.iterator();
while (iterator.hasNext()) {
iterator.next();
}
long end = System.currentTimeMillis();
System.out.println("Iterator:" + (end - start) + " ms");

// 顺序遍历(随机遍历)
start = System.currentTimeMillis();
for (int i = 0; i < linkedList.size(); i++) {
linkedList.get(i);
}
end = System.currentTimeMillis();
System.out.println("for1:" + (end - start) + " ms");

// 另一种for循环遍历
start = System.currentTimeMillis();
for (Integer i : linkedList)
;
end = System.currentTimeMillis();
System.out.println("for2:" + (end - start) + " ms");

// 通过pollFirst()或pollLast()来遍历LinkedList
LinkedList<Integer> temp1 = new LinkedList<>();
temp1.addAll(linkedList);
start = System.currentTimeMillis();
while (temp1.size() != 0) {
temp1.pollFirst();
}
end = System.currentTimeMillis();
System.out.println("pollFirst()或pollLast():" + (end - start) + " ms");

// 通过removeFirst()或removeLast()来遍历LinkedList
LinkedList<Integer> temp2 = new LinkedList<>();
temp2.addAll(linkedList);
start = System.currentTimeMillis();
while (temp2.size() != 0) {
temp2.removeFirst();
}
end = System.currentTimeMillis();
System.out.println("removeFirst()或removeLast():" + (end - start) + " ms");
}
}

演示结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
****************** linkedlist基本操作 *******************
LinkedList直接输出:[0, 1, 2, 3]

getFirst()获得第一个元素: 0
getLast()获得第最后一个元素: 3
removeFirst()删除第一个元素并返回: 0
removeLast()删除最后一个元素并返回: 3
After remove:[1, 2]

contains()方法判断列表是否包含1这个元素:true
该linkedList的大小 : 2

****************** 位置访问操作 *******************
After set(1, 3):[1, 3]
get(1)获得指定位置(这里为1)的元素: 3

****************** Search操作 *******************
indexOf(3): 1
lastIndexOf(3): 2

****************** 遍历操作 *******************
Iterator:21 ms
for1:3658 ms
for2:2 ms
pollFirst()pollLast():6 ms
removeFirst()removeLast():6 ms

ArrayList

ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

在我们学数据结构的时候就知道了线性表的顺序存储,插入删除元素的时间复杂度为O(n),求表长以及增加元素,取第 i 元素的时间复杂度为O(1)

与 Vector 不同,ArrayList 中的操作不是线程安全的!所以,建议在单线程中才使用 ArrayList,而在多线程中可以选择 Vector 或者 CopyOnWriteArrayList。

常用方法:

方法详解

ArrayList源码学习

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package DataStructure;

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

public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
System.out.printf("Before add:arrayList.size() = %d\n",arrayList.size());
arrayList.add(1);
arrayList.add(3);
arrayList.add(5);
arrayList.add(7);
arrayList.add(9);
System.out.printf("After add:arrayList.size() = %d\n",arrayList.size());

System.out.println("Printing elements of arrayList");
// 三种遍历方式打印元素
// 第一种:通过迭代器遍历
System.out.print("通过迭代器遍历:");
Iterator<Integer> it = arrayList.iterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();

// 第二种:通过索引值遍历
System.out.print("通过索引值遍历:");
for(int i = 0; i < arrayList.size(); i++){
System.out.print(arrayList.get(i) + " ");
}
System.out.println();

// 第三种:for循环遍历
System.out.print("for循环遍历:");
for(Integer number : arrayList){
System.out.print(number + " ");
}

// toArray用法
// 第一种方式(最常用)
Integer[] integer = arrayList.toArray(new Integer[0]);

// 第二种方式(容易理解)
Integer[] integer1 = new Integer[arrayList.size()];
arrayList.toArray(integer1);

// 抛出异常,java不支持向下转型
//Integer[] integer2 = new Integer[arrayList.size()];
//integer2 = arrayList.toArray();
System.out.println();

// 在指定位置添加元素
arrayList.add(2,2);
// 删除指定位置上的元素
arrayList.remove(2);
// 删除指定元素
arrayList.remove((Object)3);
// 判断arrayList是否包含5
System.out.println("ArrayList contains 5 is: " + arrayList.contains(5));

// 清空ArrayList
arrayList.clear();
// 判断ArrayList是否为空
System.out.println("ArrayList is empty: " + arrayList.isEmpty());
}
}

演示结果:

1
2
3
4
5
6
7
8
Before add:arrayList.size() = 0
After add:arrayList.size() = 5
Printing elements of arrayList
通过迭代器遍历:1 3 5 7 9
通过索引值遍历:1 3 5 7 9
for循环遍历:1 3 5 7 9
ArrayList contains 5 is: true
ArrayList is empty: true

参考文档

---------------- The End ----------------

本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
本文地址:https://philxin.top/2019/09/29/Java-DataStructure-List/
转载请注明出处,谢谢!

0%