LinkedList底层原理
ArrayList数据结构
- 物理结构:紧密结构(也就是底层内存挨着)
- 逻辑结构:线性表(数组)
LinkedList数据结构
- 物理结构:跳转结构
- 逻辑结构:线性表(链表)
既然是链表,那么就会有单线链表和双线链表;
注意:LinkedList:底层是双线链表
问题:给LinkedList中放入三个元素:“aa”,“bb”,“cc”,为什么要称为双线链表?
原因:首先会把这三个元素封装为一个对象,它们在底层其实是一个指向一个,在逻辑中就想象为中间有一条线,地址会分为一块三分内存,第一块存储为aa,把这个aa存放在中间的位置,aa前面的空内存放的是前一个元素的内存地址,aa的后一块内存放的是后一个元素的地址,把这个三块同等份的内存整体封装成一个对象;在开辟一块新的三等份的内存,将bb放入中间,此时aa的后一个元素地址就是bb的内存地址,自动将bb的这三块同等份的内存封装为一个对象;这时候有会有一块新的同等份的三块内存,中间存储cc这时候,bb的后一个空位置就会指向cc的对象内存地址;
总结:总体来说,就是一个内存的后一个元素位置指向后面元素的对象地址,然后后面的对象地址又会指向前面的对象地址,在这个过程中是一个双向的(你指向我,我指向你),这样就实现了一个双向链表的结构体。
模拟LinkedList存储元素过程:
package zhai.linkedlist;
public class One {
private One a; // 首个元素
private Object b; // 中间元素
private One c; // 尾部元素
public One getA() {
return a;
}
public void setA(One a) {
this.a = a;
}
public Object getB() {
return b;
}
public void setB(Object b) {
this.b = b;
}
public One getC() {
return c;
}
public void setC(One c) {
this.c = c;
}
}
package zhai.linkedlist;
public class Two {
private One a; // 首个元素
private One b; // 尾部元素
private int count; // 链表长度
// 添加方法
public void add(Object o){
One one = new One();
if (a == null){
// 这个元素一定是第一个元素
one.setA(null);
one.setB(o); // 第一个元素在中间,前后都为空
one.setC(null);
a = one;
b = one;
}else { // 当元素不为空时
One one1 = new One();
one1.setA(b);
one1.setC(null);
a.setC(one1);
a = one1;
}
count++;
}
// 获取元素长度
public int getSize(){
return count; // 这个count其实就是元素中循环的次数
}
// 模拟一个根据下标获取元素的方法 其实在链表中并没有下标
public Object index(int index){
One o = a;
for (int i = 0; i < index; i++) {
o = o.getC();
}
return o.getB();
}
}
测试:
package zhai.linkedlist;
public class TestOne {
public static void main(String[] args) {
Two two = new Two();
two.add(123);
System.out.println(two.getSize());
System.out.println(two.index(0));
}
}
输出:
1
123