全网最全的Java数据结构宝典开源分享,网友:看这一篇就够了

242 阅读3分钟

Hello,今天给各位童鞋们分享的是Java数据结构,赶紧拿出小本子记下来吧

image.png

数组

  • 数组是一个存放多个数据的容器
  • 数据是同一个类型的
  • 所有的数据是线性规则排列
  • 可通过位置索引来快速定位访问数据
  • 需明确容器长度

// 数组初始化

int[] a; // 没有new即没有申请内存空间

int[] a = new int[2]; // 数组长度为2,且元素都为0

int[] a = new int[]{ 1, 2, 3 }; // 逐个初始化

int[] a = { 1, 2, 3 };

JCF

  • JCF是一个容器框架,容器框架是为了表示和操作容器而规定的一种标准体系结构
  • 容器是能够存储数据的空间结构:如数组、列表、散列集等
  • 容器框架主要有以下三个部分
  • 对外的接口:容器中所能存储的抽象数据类型
  • 接口的实现:可复用的数据结构
  • 算法:对数据的查找和排序

在Java1.2以后Java推出了JCF

JCF主要是实现类:

  • 列表(List、ArrayList、LinkedList)
  • 集合(Set、HashSet、TreeSet、LinkedHashSet)
  • 映射(Map、HashMap、TreeMap、LinkedHashMap)

JCF主要的算法类

  • Arrays:对数组进行查找和排序等操作
  • Collections:对Collection及其子类进行排序和查找操作

列表List

List主要实现:

  • ArrayList(非同步的)
  • LinedList(非同步的)
  • Vector(同步)

ArrayList

  • 以数组实现的列表,不支持同步
  • 利用索引位置可以快速定位访问
  • 不适合指定位置的插入、删除的操作
  • 适合变动不大,主要用于查询的数据
  • 和Java数组相比,其容量可动态调整的
  • ArrayList在元素填满容器时会自动扩充容器大小的50%

image.png 遍历性能测试:

image.png 运行结果:

迭代器遍历用时:6505100纳秒索引遍历用时:4729700纳秒for-earch遍历用时:8569100纳秒

Process finished with exit code 0

LinkedList

  • 以双向链表实现的列表,不支持同步
  • 可被当作堆栈、队列和双端队列进行操作
  • 顺序访问高效、随机访问较差、中间插入和删除高效
  • 适用于经常变化的数据

image.png 遍历性能测试

image.png 运行结果:

迭代器遍历用时:6294100纳秒位置索引用时:3135172200纳秒for-earch遍历用时:6656100纳秒

Vector

  • 和ArrayList类似,可变数组实现的列表
  • Vector同步,适合在多线程下使用
  • 官方文档建议在非同步情况下,优先采用ArrayList

public static void main(String[] args) {

Vector<Integer> vector = new Vector<>();

vector.add(1);

vector.add(2);

vector.add(3);

vector.add(4);

vector.add(1,3);

System.out.println(vector.size());

}

遍历性能测试

image.png 运行结果:

迭代器遍历用时:7155600纳秒位置索引用时:6508500纳秒for-earch遍历用时:6303000纳秒

集合Set

  • 确定性:对任意对象都能判定其是否属于某个集合
  • 互异性:集合内每个元素都是不相同的,(内容互异)
  • 无序性:集合内的顺序无关
  • Java中的集合接口Set
  • HashSet (基于散列函数的集合,无序,不支持同步)
  • TreeSet (基于树结构的集合,可排序的、不支持同步)
  • LinkedHashSet(基于散列函数和双向链表的集合,可排序,不支持同步)

HashSet

  • 基于HashMap实现的,可容纳null元素,不支持同步
  • 支持同步使用 Set set = Collections.synchronizedSet(new HashSet(…))
  • add 添加一个元素
  • clear 清除整个HashSet
  • contains 判定是否包含一个元素
  • remove 删除一个元素
  • retainAll 计算两个集合交集

image.png 运行结果:

HashSet size is 6[null, 6, 7, 8, 9, 10][null, 7, 8, 9, 10]

遍历性能测试:

image.png 运行结果:

迭代器遍历:1592900纳秒for-earch遍历:1032800纳秒

LinkedHashSet

  • 继承HashSet,也是基于HashMap实现的,可容纳null元素
  • 不支持同步
  • Set set = Collections.synchronizedSet(new LinkedHashSet(…))
  • 方法和HashSet基本一致
  • add、clear、contains、remove、size
  • 通过一个双向链表维护插入顺序

public static void main(String[] args) {

LinkedHashSet<Integer> integers = new LinkedHashSet<>();

integers.add(null);

integers.add(1);

integers.add(2);

integers.add(3);

// 以下重复元素插入无效

integers.add(3);

integers.add(null);

System.out.println(integers.size()); // 4

}

遍历性能测试:

image.png

TreeSet

  • TreeSet基于ThreeMap实现的,不可以容纳null元素,不支持同步
  • SortedSet set = Collections.synchronizedSortedSet(new TreeSet(…));
  • add 添加一个元素
  • clear 清空
  • contains 判定是否包含一个元素
  • remove 删除一个元素
  • 根据compareTo方法或Comparator排序

public static void main(String[] args) {

TreeSet<Integer> treeSet = new TreeSet<>();

treeSet.add(100);

treeSet.add(10);

treeSet.add(1);

treeSet.add(12);

treeSet.add(13);

// 默认从小到大排序,输出为[1, 10, 12, 13, 100]

System.out.println(treeSet);

}

遍历性能测试:

image.png 运行结果:

迭代器遍历:2478900纳秒for-earch遍历:1279300纳秒

集合注意事项

HashSet、LinkedHashSet和TreeSet

  • HashSet,LinkedHashSet和TreeSet的元素只能是对象
  • HashSet和LinkedHashSet判定元素重复的原则
  • 判定两个元素的hashCode返回值是否相同,若不同,返回false
  • 若两者hashCode相同,判定equals方法,若不同,返回false,否则返回ture

TreeSet判定元素重复的原则

  • 需要元素继承自Compareble接口
  • 比较两个元素的compareTo方法

image.png

以size作为元素重复的判定依据

image.png 注意:HashSet元素判定规则只与hashCode、equals方法有关,和compareTo方法无关

compareTo方法具体规则

// 如果a>0,则obj1>obj2

// 如果a==0,则obj1==obj2

// 如果a<0,则obj1<obj2

int a = obj1.compareTo(obj2);

映射Map

  • 映射Map指的是两个集合之间的元素对应关系
  • 如 { 1, “张三” } -> { key, value }

Java中的Map

  • Hashtable (同步,性能低效,适用于数据量小的场景)
  • HashMap (不支持同步,性能高效,适用于数据量大的场景)
  • Properties (同步,文件形式,适用于数据量小的场景)

Hashtable

  • key-value对,key和value都不允许为null
  • 同步,多线程安全
  • 无序的
  • 适合数据量小
  • 主要方法: clear 、contains / containsValue , containsKey , get , put , remove , size

public static void main(String[] args) {

Hashtable<Integer, String> hashtable = new Hashtable<>();

hashtable.put(1, "value 1");

hashtable.put(2, "value 2");

hashtable.put(3, "value 3");

// 输出{3=value 3, 2=value 2, 1=value 1}

System.out.println(hashtable);

}

遍历性能测试:

image.png

image.png 运行结果:

使用Entry遍历:2537100纳秒使用KeySet遍历:1931300纳秒使用Enumeraton遍历:1332600纳秒

HashMap

  • key-value , key和value都允许为null
  • Map map = Collections.synichronizedMap(new HashMap(…));
  • 不同步,多线程不安全
  • 无序的
  • 主要方法: clear , containsValue, containsKey , get , put , remove , size

public static void main(String[] args) {

HashMap<Integer, String> hashMap = new HashMap<>();

hashMap.put(1, null);

hashMap.put(null, "value is null");

hashMap.put(2, "value is two");

// 输出为{null=value is null, 1=null, 2=value is two}

System.out.println(hashMap);

}

# 遍历性能测试:

image.png 运行结果:

使用Entry遍历:13562900纳秒使用KeySet遍历:11260300纳秒

LinkedHashMap

基于双向链表的维持插入顺序的HashMap

public static void main(String[] args) {

LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();

linkedHashMap.put(null, "key is null");

linkedHashMap.put(1, null);

linkedHashMap.put(2, "key is two");

// 输出{null=key is null, 1=null, 2=key is two}

System.out.println(linkedHashMap);

}

遍历性能测试:

image.png 运行结果:

使用Entry遍历:9421600纳秒使用KeySet遍历:9117500纳秒

TreeMap

基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出

public static void main(String[] args) {

TreeMap<Integer, String> treeMap = new TreeMap<>();

treeMap.put(2, null);

// 当key为null的时候运行报空指针异常

// treeMap.put(null, "key is null");

treeMap.put(1, "key is two");

// 输出为{1=null, 2=key is two}

System.out.println(treeMap);

}

遍历性能测试:

image.png 运行结果:

使用Entry遍历:3187900纳秒使用KeySet遍历:4659400纳秒

Properties

  • 继承于Hashtable
  • 可以将key-value存储到文件中
  • 适用于数据量少的配置文件
  • 继承自Hashtable的方法:clear , contains / containsValue , containsKey , get , put , remove , size
  • 从文件加载的load方法 , 写入到文件的store方法
  • 获取属性 getProperty , 设置属性 setProperty

image.png

image.png 运行结果:

写入到Test.properties文件中加载到Test.properties文件name : 123456从Test.properties文件加载name is 123456

Test.properties文件中的内容

#update name name#Sun Jun 13 22:27:45 CST 2021name=123456

数据结构的工具类

JCF中工具类

  • 不存储数据,而是在数据容器上,实现高效操作
  • 排序、搜索
  • 工具类有:Arrays类、Collections类

Arrays类

  • 处理对象是数组
  • 排序:对数组排序,sort / parallelSort
  • 查找:从数组中查找一个元素,binarySearch
  • 批量拷贝:从源数组批量复制到目标数组,copyOf
  • 批量复制:对数组进行批量复制,fill
  • 判定两个数组内容是否相同,equals

image.png 运行结果:

排序前46,12,-95,95,-62,9,92,-44,-14,91,排序后-95,-62,-44,-14,9,12,46,91,92,95,

public static void main(String[] args) {

Random random = new Random();

int[] array = new int[10];

for (int i = 0; i < array.length; i++) {

    array[i] = random.nextInt() % 100;

}

array[array.length - 1] = 999;

// 当数组中有多个999的时候随机返回999的指定位置

System.out.println("999的位置: " + Arrays.binarySearch(array, 999));

}

运行结果:

999的位置: 9

public static void main(String[] args) {

int[] a = new int[10];

Arrays.fill(a, 100);

int[] b = new int[10];

Arrays.fill(b, 100);

System.out.println("两个数组内容是否相同: " + Arrays.equals(a, b));

}

运行结果:

两个数组内容是否相同: true

Collections类

  • Collections处理对象是Collection及其子类
  • 排序:对List进行排序,sort
  • 搜索:从List中搜索元素,binarySearch
  • 批量赋值:对List批量赋值,fill
  • 最大、最小:查找集合中最大 / 最小,max,min
  • 反序:将List反序排列,reverse

image.png 运行结果:

12元素所在的位置: 3最大值: 12最小值: 1list的反序: [12, 9, 2, 1]

对象的比较

  • 对象实现Comparable接口(需要修改对象类)
  • Arrays和Collections在进行对象sort时,自动调用该方法
  • compareTo方法 int a = obj1.compareTo(obj2);
  • obj1 > obj2 升序,obj1 < obj2 降序,obj1 == obj2相等
  • 新建Comparator(适用于对象类不可更改的情况)
  • compare方法 int compare(Person o1, Person o2);
  • o1 - o2 > 0 升序,o1 - o2 = 0 相等,o1 - o2 < 0 降序
  • Comparator比较器将作为参数提交给工具类的sort方法

image.png 运行结果

Person{age=10}Person{age=12}Person{age=20}

image.png 运行结果:

Person{age=10}Person{age=12}Person{age=20}

好啦,今天的文章就到这里了,希望能够帮助到屏幕前迷茫的你们