文章目录
- ACM输入 Scanner
- **一、字符串高频API**
- **二、集合高频API**
- **三、栈(Stack)高频API**
- **1. 推荐用`Deque`替代`Stack`类**(更高效且线程不安全,适合算法场景)
- **2. 核心操作**
- **3. 经典应用场景**
- **4. 避坑指南**
- **四、链表(LinkedList)高频API**
- **1. 内置`LinkedList`类**
- **2. 核心操作**
- **3. 自定义链表节点**(LeetCode常用)
- **4. 经典应用场景**
- **5. 避坑指南**
- **五、实用代码片段**
- **1. 用栈实现队列**
- **2. 快慢指针找链表中点**
ACM输入 Scanner
import java.util.Scanner; public class ScannerDemo {public static void main(String[] args) {Scanner scan = new Scanner(System.in);// 从键盘接收数据// next方式接收字符串System.out.println("next方式接收:");// 判断是否还有输入if (scan.hasNext()) {String str1 = scan.next();System.out.println("输入的数据为:" + str1);}scan.close();}
}
$ javac ScannerDemo.java
$ java ScannerDemo
next方式接收:
runoob com
输入的数据为:runoob
可以看到 com 字符串并未输出
使用 nextLine 方法:
// 判断是否还有输入if (scan.hasNextLine()) {String str2 = scan.nextLine();System.out.println("输入的数据为:" + str2);}
runoob com
输入的数据为:runoob com
如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取。
以下是针对ACM模式刷题时,字符串和集合相关的高频Java API总结(按使用频率排序):
一、字符串高频API
- String类
String str = "abc";
// 基础操作
str.length() // 字符串长度
str.charAt(int index) // 获取字符(高频)
str.substring(int start) // 截取子串(含start)
str.substring(int start, int end) // 截取[start,end)
str.split(String regex) // 分割字符串(高频,如处理输入)
str.toCharArray() // 转字符数组(高频用于遍历)
str.equals(String other) // 比较内容(非地址)
str.indexOf(String s) // 查找子串位置// 类型转换
Integer.parseInt(str) // 字符串转整数(高频)
String.valueOf(int/double...) // 其他类型转字符串(高频)
str.toLowerCase() / toUpperCase() // 大小写转换// 其他
str.trim() // 去除首尾空格
str.replace(old, new) // 替换字符/字符串
str.contains(String s) // 是否包含子串
- StringBuilder(高频!线程不安全但更快)
StringBuilder sb = new StringBuilder();
sb.append("a") // 追加内容(高频)
sb.insert(index, "x") // 插入
sb.delete(start, end) // 删除
sb.reverse() // 反转(高频用于回文题)
sb.toString() // 转String(最终输出)
- Character
Character.isLetter()
Character.toLowerCase()
二、集合高频API
- List(ArrayList最常用)
List<Integer> list = new ArrayList<>();
// 基础操作
list.add(element) // 添加元素(高频)
list.get(int index) // 获取元素(高频)
list.size() // 元素个数(高频)
list.remove(int index) // 按索引删除
list.remove(Object o) // 按对象删除
list.contains(Object o) // 是否包含元素
list.isEmpty() // 判空// 工具方法
Collections.sort(list) // 排序(高频)
Collections.reverse(list) // 反转
Collections.max(list) / min(list) // 最大/最小值
Collections.fill(list, val) // 填充// 数组互转
Arrays.asList(T... a) // 数组转List(注意返回固定大小List)
list.toArray(new T[0]) // List转数组
- Map(HashMap最常用)
Map<K, V> map = new HashMap<>();
// 基础操作
map.put(key, value) // 添加/覆盖键值对(高频)
map.get(key) // 获取值(高频)
map.containsKey(key) // 是否包含键(高频)
map.getOrDefault(key, defaultValue) // 安全获取
map.remove(key) // 删除键
map.size() // 键值对数量// 遍历(高频)
for (Map.Entry<K, V> entry : map.entrySet())//PriorityQueue(优先队列)
PriorityQueue<Map.Entry<Character, Integer>> pq = new PriorityQueue<>((a, b) -> b.getValue() - a.getValue()
);
pq.addAll(map.entrySet());
以下是栈(Stack)和链表(LinkedList)在ACM模式刷题时的高频Java API总结,包含核心操作和避坑指南:
三、栈(Stack)高频API
1. 推荐用Deque
替代Stack
类(更高效且线程不安全,适合算法场景)
Deque<Integer> stack = new ArrayDeque<>();
2. 核心操作
方法 | 说明 | 示例 |
---|---|---|
push(e) | 入栈 | stack.push(5); |
pop() | 出栈(空栈会抛异常) | int top = stack.pop(); |
peek() | 查看栈顶元素(不删除) | int top = stack.peek(); |
isEmpty() | 判断栈是否为空 | if (stack.isEmpty()) {...} |
size() | 获取元素个数 | int len = stack.size(); |
3. 经典应用场景
- 括号匹配:用栈存储左括号,遇到右括号时弹栈匹配
- 单调栈:维护栈内元素单调性(递增/递减)
- 表达式求值:处理运算符优先级
4. 避坑指南
- 空栈检查:
pop()
和peek()
前必须检查栈是否为空,否则会抛出NoSuchElementException
- 性能对比:优先用
ArrayDeque
而非Stack
类(后者同步操作性能差)
四、链表(LinkedList)高频API
1. 内置LinkedList
类
LinkedList<Integer> list = new LinkedList<>();
2. 核心操作
方法 | 说明 | 时间复杂度 |
---|---|---|
addFirst(e) | 头部插入元素 | O(1) |
addLast(e) | 尾部插入元素 | O(1) |
removeFirst() | 删除头部元素(空链表抛异常) | O(1) |
removeLast() | 删除尾部元素(空链表抛异常) | O(1) |
getFirst() | 获取头部元素(不删除) | O(1) |
getLast() | 获取尾部元素(不删除) | O(1) |
get(int index) | 获取第index个元素(低效,慎用) | O(n) |
size() | 获取链表长度 | O(1) |
3. 自定义链表节点(LeetCode常用)
class ListNode {int val;ListNode next;ListNode(int x) { val = x; }
}
// 操作示例:反转链表
ListNode dummy = new ListNode(-1);
while (head != null) {ListNode next = head.next;head.next = dummy.next;dummy.next = head;head = next;
}
return dummy.next;
4. 经典应用场景
- 链表反转:迭代或递归修改指针指向
- 合并有序链表:双指针遍历比较
- 快慢指针:检测环、找中点(如判断回文链表)
- 虚拟头节点:简化头节点边界处理
5. 避坑指南
- 指针丢失:修改链表节点指针时,注意提前保存
next
节点 - 循环引用:操作链表后注意检查是否成环
- 性能陷阱:避免频繁调用
get(index)
(链表随机访问是O(n))
五、实用代码片段
1. 用栈实现队列
class MyQueue {Deque<Integer> inStack = new ArrayDeque<>();Deque<Integer> outStack = new ArrayDeque<>();public void push(int x) {inStack.push(x);}public int pop() {if (outStack.isEmpty()) {while (!inStack.isEmpty()) {outStack.push(inStack.pop());}}return outStack.pop();}
}
2. 快慢指针找链表中点
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {slow = slow.next; // 慢指针走1步fast = fast.next.next; // 快指针走2步
}
// slow即为中点(偶数个节点时靠左)
掌握这些API和技巧后,可以高效解决栈和链表相关的算法题,注意边界条件和指针操作的细节!