-
【JAVA】笔记(15)---集合(4)- 数组数据结构;单向 / 双向 链表数据结构;A
数组数据结构:
1.数组中每个元素占用的空间大小相同;且每个元素的内存地址连续,知道首元素的内存地址,再根据不同的下标,通过数学表达式就可以计算出其他元素的内存地址,所以数组的检索效率非常高;
2.数组优点:检索效率高;数组缺点:增删效率低(在数组末尾添加元素,效率不受影响);
单向链表数据结构:
1.单向链表类的基本组成单位是另一个类 Node ;
2.特性:
1)单向链表的每个单位节点都有两个属性--- 存储的数据和下一个节点的内存地址 ;
2)链表的增删效率高于数组的原因是因为增删元素不涉及到大量元素的位移问题;
3)当当前节点已经是链表的最后一个节点时,它储存的“ 下一个节点 ”的内存地址即为 null ;
4)链表的检索效率低于数组的原因是因为链表检索元素,只能“ 从头节点一个一个地往下遍历,直到找到对应元素为止 ”;
图示:
双向链表数据结构:
1.双向链表的基本组成单位还是 Node 类 ;
2.双向链表除 first(双向链表的第一个节点) 与 last(双向链表的最后一个节点) 以外,每个节点都有三个属性:
存储的数据,上一个节点的内存地址,下一个节点的内存地址;
3.双向链表的其他特性与双向链表相同:检索效率低,增删效率高;
4.最初这个链表中没有任何元素,first,last 的引用都是 null;
图示:
ArrayList:
1.底层为一个 Object [ ] 数组,当添加第一个元素时,初始化容量为10,每次扩容是原容量的1.5倍;
2.构造方法:new ArrayList ( ) ; new ArrayLIst ( 初始化容量 ) ;
3.当 ArrayList 集合内存不够时,集合则会自动扩容,增长为原容量的1.5倍;
4.注意:建议给定集合一个大约的初始容量,要尽量避免自动扩容;
ArrayList 是非线程安全的;
LinkList:
1.底层为一个双向链表,无初始化容量,存在下标,但检索效率依然很低,因为只能从头节点开始一个一个遍历;
2.LinkList 是非线程安全的;
Vector:
1.Vector 集合底层采用了数组的数据结构,初始化容量为10,每次扩容之后是原容量的2倍;
2.因为 Vector 的所有方法都是 synchronized 关键词修饰的,所以线程安全,但是效率较低,由于保证线程安全还有其他更适合的方案,所以 Vector 集合使用较少;
总结:
1.对于 ArrayList , LinkedList,Vector ,在日常使用过程中,我们只需考虑使用哪个集合就行,在这三种集合行使相同功能时,只是效率,或在线程方面,可能会与有所不同,但是代码上的书写及运行结果都是一样的;
2.因为我们要面向接口编程,调用的都是已经封装好的接口中的方法;
3.总之就俩句话:ArrayList,LinkedList ,Vector 会用一个就行 ,检索多就 ArrayList ,增删多就 LinkedList,Vector 不常用;
栗子老师老王:用 ArrayList 实现代码
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class practice {
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("我好不容易心动一次");
list.add(1,"你却让我输的这么彻底");
list.add(2,"焯!");
for (String string:list) {
System.out.println(string);
}
list.remove(2);
list.set(1,"你却让我输的这么彻底!(颤音)");
Iterator<String> iterator=list.iterator();
while (iterator.hasNext()){
String string=iterator.next();
System.out.println(string);
}
}
}
运行结果:
-------------------------------
我好不容易心动一次
你却让我输的这么彻底
焯!
我好不容易心动一次
你却让我输的这么彻底(颤音)
Process finished with exit code 0
栗子老师老刘:用 LinkLIst 实现相同代码(老刘仅仅只是把第7行中的 ArrayList 改为 LinkedList ,运行结果与刚才的完全一样!)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class practice {
public static void main(String[] args) {
List<String> list=new LinkedList<>();//只把 ArrayLsit 修改为 LinkedList
list.add("我好不容易心动一次");
list.add(1,"你却让我输的这么彻底");
list.add(2,"焯!");
for (String string:list) {
System.out.println(string);
}
list.remove(2);
list.set(1,"你却让我输的这么彻底!(颤音)");
Iterator<String> iterator=list.iterator();
while (iterator.hasNext()){
String string=iterator.next();
System.out.println(string);
}
}
}
运行结果:
-----------------------------------
我好不容易心动一次
你却让我输的这么彻底
焯!
我好不容易心动一次
你却让我输的这么彻底!(颤音)
Process finished with exit code 0
栗子老师老张说:“ 用 Vector 实现这些代码也是相同的结果,代码啥的也就改构造方法那块就行,不信你自己去试试 ” 。
随笔:
使用集合工具类将非线程安全的 ArrayList 转换为线程安全的:
import java.util.*;
public class practice {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//这样 list 也是线程安全的了,效果目前无法展示(手动狗头)
Collections.synchronizedList(list);
}
}
原文:https://www.cnblogs.com/Burning-youth/p/15604931.html