Java中常用的数据结构及其特点

1.List

1.1  ArrayList(底层是使用数组实现)

特点:

ArrayList对于随机访问和更新操作(如get和set)具有较好的性能,时间复杂度为O(1)。

缺点:

插入和删除元素时,需要移动元素的位置,因此性能较差,时间复杂度为O(n)。

1.2  LinkedList(底层使用双向链表实现)

在Java中,LinkedList实现了Deque接口,因此提供了一系列Deque接口中定义的方法

类似于双端队列

优点:

LinkedList对于插入和删除操作具有较好的性能,因为只需要改变链表中相邻节点的指针即可,时间复杂度为O(1)。

缺点:

对于随机访问和更新操作,性能较差,需要遍历链表,时间复杂度为O(n)。

1.2.1  ArrayDeque

ArrayDeque是基于数组实现的双端队列,它不是线程安全的。ArrayDeque没有容量限制,可以根据需要动态地增长和收缩。在大多数情况下,ArrayDeque比LinkedList具有更快的性能,因为它是基于数组的,因此具有更好的局部性和更低的内存消耗。但是,ArrayDeque不支持容量限制,因此在需要限制容量的情况下,可能需要自行实现扩容策略。

1.2.2  ConcurrentLinkedDeque


ConcurrentLinkedDeque是Java并发包(java.util.concurrent)中提供的线程安全的双端队列实现类。它使用无锁算法实现,并发性能很高。ConcurrentLinkedDeque适用于多线程环境下需要高并发访问的场景。需要注意的是,ConcurrentLinkedDeque并不是阻塞队列,它不会阻塞线程,而是通过CAS操作实现并发控制。

1.3  Vector

基于数组,大小可变(数组扩容),与ArrayList类似

3. Map

3.1  hashMap

        简单的相关用法

map.put("England", "London");
map.get("England");
map.remove("England");
map.clear();
map.size();
// Print keys
for (String i : capitalCities.keySet()) {
  System.out.println(i);
}
// Print values
for (String i : capitalCities.values()) {
  System.out.println(i);
}

3.2  TreeMap


reeMap是Java中的一个基于红黑树实现的有序映射表,它实现了SortedMap接口,因此具有根据键的自然顺序或自定义顺序进行排序的功能。下面是对TreeMap的详细介绍:

特点: 有序性:TreeMap中的键值对根据键的自然顺序或自定义顺序进行排序。如果使用自然顺序,则键必须实现Comparable接口;如果使用自定义顺序,则在创建TreeMap时可以传入Comparator对象。 基于红黑树:TreeMap的底层数据结构是一棵红黑树,这使得TreeMap具有较高的查找、插入和删除性能,时间复杂度为O(log n)。 不允许null键:TreeMap不允许使用null作为键,但可以使用null作为值。 不是线程安全的:TreeMap不是线程安全的,如果需要在多线程环境中使用,需要进行适当的同步措施。

TreeMap<Integer, String> treeMap = new TreeMap<>();
// 或者
TreeMap<Integer, String> customTreeMap = new TreeMap<>(Comparator.reverseOrder());
​
// 可以使用以下方式进行遍历,也可以像HashMap一样进行key,value遍历
for (Map.Entry<Integer, String> entry : treeMap.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

4.Set

HashSet

HashSet基于哈希表实现,具有较快的插入和查找性能。
HashSet不保证元素的顺序,即不保证迭代顺序与插入顺序-致。
HashSet允许null元素。
适用于需要快速查找且不需要元素有序的情况。


LinkedHashSet:


LinkedHashSet是HashSet的子类,内部使用链表维护元素的插入顺序。
因此,LinkedHashSet可以保证迭代顺序与插入顺序一 致。
LinkedHashSet允许null元素。
适用于需要保持元素插入顺序的情况。

TreeSet:


TreeSet基于红黑树实现,具有按照元素的自然顺序或者指定比较器进行排序的功能。
TreeSet不允许null元素。
TreeSet提供了- -些附加的操作,如获取最小值、最大值等。
适用于需要有序集合的情况。


EnumSet:


EnumSet是专门用于枚举类型的Set实现,只能包含枚举类型的值。
EnumSet是一-个高效的且专门门]针对枚举类型设计的实现。
EnumSet坏允许null元素。

通用的操作

set.add("Apple");
set.remove("Banana");
boolean containsApple = set.contains("Apple");
int size = set.size();
set.clear();
​
for (String fruit : set) {
    System.out.println(fruit);
}
​
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    System.out.println(fruit);
}
​
boolean isEmpty = set.isEmpty();
​
// 转换为Object类型的数组
Object[] array = set.toArray();
​
// 转换为指定类型的数组
String[] stringArray = set.toArray(new String[set.size()]);

5. Stack


Stack(栈)是Java中的一种经典数据结构,它遵循先进后出(LIFO,Last-In-First-Out)的原则,即最后压入栈的元素最先被弹出。在Java中,Stack类继承自Vector类,因此它是线程安全的,并且允许在任意位置插入和删除元素。

stack.push(3);
​
// 获取栈顶元素并弹出
int top = stack.pop(); // top = 3
​
// 获取栈顶元素但不弹出
int peeked = stack.peek(); // peeked = 2
​
// 判断栈是否为空
boolean isEmpty = stack.empty(); // false
​
// 搜索指定元素在栈中的位置
int position = stack.search(2); // position = 2

6 .Queue

ArrayDeque

ArrayDeque和LinkedList都实现了Queue接口,因此它们具有相似的操作方法。这包括了向队列
中添加元素、从队列中移除元素、获取队列的头部元素等。

PriorityQueue

PriorityQueue是Java中实现了队列接口(Queue) 的一种特殊队列实现,它是基于优先级堆(Priority
Heap)实现的。PriorityQueue 中的元素按照其自然顺序或者指定的比较器进行排序,优先级高的元素先被移除。


特点:
1.基于优先级堆: PriorityQueue 使用优先级堆作为底层数据结构,保证了队列中的元素是有序的。
2.按优先级排序: PriorityQueue 中的元素按照其自然顺序或者指定的比较器进行排序,优先级高的元素
先被移除。
3.不允许null元素: PriorityQueue 不允许添加null元素。

add(E e) 或 offer(E e):向队列中添加元素。
remove() 或 poll():移除并返回队列中优先级最高的元素。
peek():返回队列中优先级最高的元素,但不移除。
size():返回队列中元素的个数。
isEmpty():判断队列是否为空。
clear():清空队列中的所有元素。
​
// 创建堆 默认是小根堆
// 创建大根堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());

总结:

一、几个常用类的区别 


1.ArrayList: 元素单个,效率高,多用于查询 
2.Vector: 元素单个,线程安全,多用于查询 
3.LinkedList:元素单个,多用于插入和删除 
4.HashMap: 元素成对,元素可为空 
5.HashTable: 元素成对,线程安全,元素不可为空 


二、Vector、ArrayList和LinkedList 


大多数情况下,从性能上来说ArrayList最好,但是当集合内的元素需要频繁插入、删除时LinkedList会有比较好的表现,但是它们三个性能都比不上数组,另外Vector是线程同步的。所以: 
如果能用数组的时候(元素类型固定,数组长度固定),请尽量使用数组来代替List; 
如果没有频繁的删除插入操作,又不用考虑多线程问题,优先选择ArrayList; 
如果在多线程条件下使用,可以考虑Vector; 
如果需要频繁地删除插入,LinkedList就有了用武之地; 
如果你什么都不知道,用ArrayList没错。

  • 30
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值