Java—LinkedList集合的运用和详解
1.LinkedList的特点:
有序、可重复、链表结构存储数据;
根据索引查询略慢;
数据的增删比较方便;
更便于实现栈和队列的存储设计
package com.bjsxt.test;
import java.util.LinkedList;
/**
* 使用LinkedList存储大量数据
*/
public class TestLinkedList {
public static void main(String[] args) {
LinkedList list = new LinkedList();
for (int i = 0; i <= 10 ; i++) {
list.add(i);
}
System.out.println(list);
list.add(1);
//通过源码我们可以得知size的默认值为0,在我们通过add向里面增加一个数据的时候size就会加1,size的主要作用就是返回集合中元素的个数。
for (int i = 0; i < list.size()-1 ; i++) {
Integer integer = (Integer) list.get(i);
System.out.println(integer);
}
}
}
2.LinkedList常用的API
注意:LinkedList和ArrayList父类的接口都是List;具有大量相同的API,并且遍历的方式是相同的。在这里我们就不在介绍LinkedList和ArrayList相同的API了,以下介绍的是LinkedList独有的API
package com.bjsxt.test;
import java.util.LinkedList;
/**
* 使用LinkedList存储大量数据
*/
public class TestLinkedList {
public static void main(String[] args) {
//1.引入带泛型的LinkedList
LinkedList<String> list = new LinkedList<String>();
//向集合的末尾添加元素
list.add("a");
list.add("b");
list.add("c");
//增加元素
list.addFirst("d");//在集合的第一个位置增加元素
list.addLast("e");//在集合的最后的位置增加元素
System.out.println(list.size());
System.out.println(list);
System.out.println("------------------------");
//removeFirst():移出并返回集合中的第一个元素
String s = list.removeFirst();
System.out.println(s);
System.out.println(list);
//removeLast():移出并返回集合中最后一个元素
String s1 = list.removeLast();
System.out.println(s1);
System.out.println(list);
System.out.println("------------------------------");
//getFirst():获得集合中第一个元素,但是不从集合中移除元素
String first = list.getFirst();
System.out.println(first);
System.out.println(list);
//getLast():获得集合中最后一个元素,但是不从集合中移出元素
String last = list.getLast();
System.out.println(last);
System.out.println(list);
}
}
3.LinkedList原理图
采用双向链表存储数据,既可以向前查找数据,又可以向后查找数据;便于我们实现双端队列,模拟栈和队列的结构。
在LinkedList源码中我们可以看出:
LinkedList集合有一个私有的静态内部类Node;
E item是当前元素的本身;
Nodenext 是用于存储下一个元素的引用;
Nodeprev是用于存储上一个元素的引用;
链表上的每个节点就是一个Node对象,所有的算法都是基于众多的Node对象形成的链式结构而计算的。
数据在增加和删除时速度比较快,是因为不需要大量的移动元素;同时在LinkedLIst中根据索引和元素内容查找比较慢。
package com.bjsxt.test;
/**
* 原理解析及模拟实现
*/
public class MyLinkedList {
//用于存储链条的开头
private MyNode first;
//用于存储链条的结尾
private MyNode last;
//用于存储元素的个数
int size = 0;
public void add(Object o){
addlast(o);
}
public void addlast(Object o){
//创建一个Node,让其作为最后一个元素
MyNode l =last;
MyNode node = new MyNode(o,null,last);
last=node;
if(l == null){
first=node;
}else {
l.next = node;
size++;
}
}
private class MyNode{
//当前要存储的数据
Object ele;
//下一个元素的引用
MyNode next;
//上一个元素的引用
MyNode prev;
public MyNode(Object ele, MyNode next, MyNode prev) {
this.ele = ele;
this.next = next;
this.prev = prev;
}
}
}
ArrayList和LinkedList的比较:
不变的是什么?
1.运算的结果没有改变
2.执行的代码没有改变
变化的是什么?
1.底层的结构变了:ArrayList是数组;LinkedList是双向链表
2.具体的执行过程变化了:ArrayList:大量的后移元素;LinkedList:不需要大量的移动元素,修改节点的指向即可
在选择使用ArrayList和LinkedList的时候怎么选择?
根据使用场合而定:
1.在 代码中存在大量的根据索引查询的操作,大量的遍历操作,建议使用ArrayList
2.如果存在较多的添加、删除操作,建议使用LinkedList
public class TestLinkedList {
public static void main(String[] args) {
//1.创建一个ArrayList集合对象
//ArrayList<Integer> list = new ArrayList<Integer>();
//LinkedList<Integer> list = new LinkedList<Integer>();
//List<Integer> list = new ArrayList<Integer>();
List<Integer> list = new LinkedList<Integer>();
//2.对集合中的元素进行操作
//2.1 添加
list.add(80);//向末尾添加元素
list.add(80);
list.add(78);//自动装箱
list.add(new Integer(78));
//list.add("Java");
// list.addFirst(12);
// list.addLast(12);
list.add(0,12);
list.add(12);
list.add(100);
list.add(56);
list.add(80);
list.add(2,99);//向指定的位置添加元素
//2.2 查询指定的元素
System.out.println(list.size());//元素的个数
System.out.println(list);
list.remove(1);
System.out.println(list);
System.out.println(list.isEmpty());
}
}