文
章
目
录
章
目
录
在算法题的“战场”上,Java的各类工具类堪称解题的得力“武器”。很多刷题平台缺少智能补全和提示功能,记住这些工具类及其用法就显得尤为重要。下面就来详细介绍在刷算法题时常用的Java工具类。
一、队列(Queue)相关工具类
(一)普通队列(Queue)
Queue
是Java中很常用的接口,ArrayDeque
是实现Deque
接口的一个类,它既可以当作普通队列(遵循先进先出,即FIFO原则)使用,也能当成双端队列(既可以在队首操作,也能在队尾操作)。
// 创建一个队列,泛型指定为Integer类型
Queue<Integer> queue = new ArrayDeque<>();
// 常用方法如下:
// 1. 元素入队
// add方法用于添加元素到队列尾部,如果队列已满,会抛出`IllegalStateException`异常
queue.add(10);
// offer方法同样是添加元素到队列尾部,不过队列已满时,它不会抛出异常,而是返回`false`
queue.offer(20);
// 2. 元素出队
// remove方法移除并返回队列头部的元素,如果队列为空,会抛出`NoSuchElementException`异常
int firstElement = queue.remove();
// poll方法也是移除并返回队列头部的元素,但队列为空时,它返回null
Integer firstElementOrNull = queue.poll();
// 3. 查看队头元素
// element方法返回队列头部的元素,但不会移除它,如果队列为空,会抛出`NoSuchElementException`异常
int headElement = queue.element();
// peek方法返回队列头部的元素,队列为空时返回null
Integer headElementOrNull = queue.peek();
// 4. 其他常用方法
// size方法返回队列中的元素数量
int size = queue.size();
// isEmpty方法用于检查队列是否为空
boolean isEmpty = queue.isEmpty();
// clear方法用于清空队列
queue.clear();
// 5. 双端队列操作
// 虽然`ArrayDeque`可以当作普通队列,但它还支持双端队列的操作
// addFirst方法将元素添加到队列头部
queue.addFirst(5);
// addLast方法将元素添加到队列尾部
queue.addLast(15);
// removeFirst方法移除并返回队列头部的元素
int first = queue.removeFirst();
// removeLast方法移除并返回队列尾部的元素
int last = queue.removeLast();
// getFirst方法返回队列头部的元素
int head = queue.getFirst();
// getLast方法返回队列尾部的元素
int tail = queue.getLast();
(二)优先队列(PriorityQueue)
PriorityQueue
是基于优先级堆实现的队列,元素按照优先级顺序出队,默认是最小堆,即最小的元素优先出队。下面是它的使用示例:
// 匿名实现比较器,用于指定元素的排序规则
public static Comparator<Customer> idComparator = new Comparator<Customer>() {
@Override
public int compare(Customer c1, Customer c2) {
// 这里按ID升序排列
return c1.getId() - c2.getId();
}
};
// 创建优先队列,指定初始容量为7,并使用上面定义的比较器
Queue<Customer> customerPriorityQueue = new PriorityQueue<>(7, idComparator);
/*
更简洁的写法: 使用Lambda表达式实现比较器
Queue<Customer> customerPriorityQueue = new PriorityQueue<>(7, (c1, c2) -> c1.getId() - c2.getId());
*/
// 添加元素到优先队列
customerPriorityQueue.add(new Customer(5));
customerPriorityQueue.add(new Customer(1));
customerPriorityQueue.add(new Customer(3));
需要注意的是,PriorityQueue
不是线程安全的。如果在多线程环境中使用,建议使用java.util.concurrent.PriorityBlockingQueue
。
二、栈(Stack)相关工具类
在Java中,实现栈功能的类有多种,常用的有以下3种:
// 方式一:使用ArrayDeque实现栈
Deque<Integer> stack1 = new ArrayDeque<>();
// 方式二:使用LinkedList实现栈
Deque<Integer> stack2 = new LinkedList<>();
// 方式三:使用Stack类实现栈(不过这个类设计较老,不太推荐使用)
Stack<Integer> stack3 = new Stack<>();
这3种实现方式都有一些常用方法:
void push(E e)
:把元素压入栈顶。E pop()
:移除并返回栈顶元素。E peek()
:返回栈顶元素,但不移除。boolean isEmpty()
:检查栈是否为空。int size()
:返回栈中元素的数量。void clear()
:清空栈。
它们之间也存在一些区别,具体如下:
特性 | ArrayDeque |
Stack |
LinkedList |
---|---|---|---|
底层数据结构 | 动态循环数组 | 动态数组(继承自Vector ) |
双向链表 |
线程安全 | 不安全 | 安全(通过同步机制实现) | 不安全 |
性能 | 高效(大部分操作时间复杂度为O(1)) | 较低(存在同步开销) | 高效(大部分操作时间复杂度为O(1)) |
推荐使用场景 | 栈或双端队列 | 不推荐使用(设计较老) | 栈或双端队列 |
随机访问 | 不支持 | 支持 | 不支持 |
额外功能 | 支持双端队列操作 | 有search() 方法 |
支持双端队列操作 |
三、数组(Arrays)工具类
Arrays
类提供了很多方便操作数组的方法,例如:
// 整数数组求和
int total = Arrays.stream(nums).sum();
// 整数数组获取最小值
int min = Arrays.stream(nums).min().getAsInt();
// 对数组进行排序
Arrays.sort(nums);
// 比较两个数组是否相等
Arrays.equals(nums1, nums2);
四、字符(Character)相关工具类
在处理字符时,Character
类提供了一些实用的方法:
// 判断字符是否是字母或数字
Character.isLetterOrDigit(ch1);
// 将字符转为小写(对字母而言,如果字符已经是小写或不是字母,则返回原字符)
Character.toLowerCase(ch1);
五、字符串相关工具类
(一)字符串数组拼接
// 使用指定的分隔符,将字符串数组拼接成一个字符串
String.join(" ", strs);
(二)字符串构建
// 创建一个StringBuffer对象,用于构建字符串
StringBuffer cur = new StringBuffer();
// 向StringBuffer中追加字符串
cur.append(str);
// 删除指定区间的字符,这里删除从start开始到字符串末尾的字符
cur.delete(start, cur.length());
(三)字符串转字符数组
// 将字符串转换为字符数组
char[] sc = str.toCharArray();
六、随机数生成相关工具类
在Java中,生成随机数有两种常见方式:
(一)使用Random类
// 创建Random对象
Random random = new Random();
// 生成一个0到9之间的随机整数
int a = random.nextInt(10);
// 生成一个0到9之间的随机long整数
long b = random.nextLong(10);
// 生成一个0到10(不包含)之间的随机浮点数
double c = random.nextDouble(10);
(二)使用Math.random()方法
// `Math.random()`是`Math`类的静态方法,返回一个`[0.0, 1.0)`范围内的伪随机`double`值。
// 通过乘以一个范围值并强制转换为`int`,可以生成一个随机整数
int num = (int) (Math.random() * 10); // 生成一个0到9的随机整数
这两种方法的区别如下:
特性 | Random.nextInt(int bound) |
Math.random() + 强制转换 |
---|---|---|
类 | Random 类 |
Math 类 |
方法 | nextInt(int bound) |
Math.random() |
返回值 | [0, bound) 范围内的int |
[0.0, 1.0) 范围内的double |
随机性 | 伪随机数,基于种子 | 伪随机数,基于系统时间 |
性能 | 较高 | 较低(涉及浮点数运算和转换) |
线程安全 | 不安全 | 安全(静态方法) |
适用场景 | 需要生成多个随机数时 | 生成单个随机数或简单场景 |
七、集合相关工具类
(一)元素排序
在集合中对元素进行排序,可以使用Collections.sort()
方法,示例如下:
// 使用匿名内部类实现比较器,按值降序排列
Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
// 这里实现降序排列
return o2.getValue().compareTo(o1.getValue());
}
});
// 使用Lambda表达式简化代码
Collections.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
// 对于简单的比较规则,可以使用`Comparator.comparing`方法。例如:Comparator.comparingInt(Customer::getId)
Collections.sort(list, Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()));
(二)元素删除
在集合中删除元素时,需要注意不同集合的删除方法:
// list集合的remove()方法,参数传的是索引,这里删除list中最后一个元素
list.remove(list.size() - 1);
// hashMap集合的remove()方法,参数传的是key,删除指定key对应的元素
hashMap.remove(val);
(三)元素交换
// 交换集合中指定位置的两个元素
Collections.swap(curList, i, first);
八、基本类型转换相关工具类
在处理数据类型转换时,经常会用到一些方法,例如将字符串转换为整型:
// 将字符串转换为整型
Integer a = Integer.parseInt(s);
本文详细介绍了刷算法题时常用的Java工具类,内容后续还会持续更新和完善。希望这些知识能帮助大家在算法题的学习和练习中理解得更透彻。