跳到主要内容Java 算法面试基础:语法、容器与工具类总结 | 极客日志Javajava算法
Java 算法面试基础:语法、容器与工具类总结
Java 算法面试中的 ACM 与 LeetCode 两种模式差异,详细梳理了常用数据结构容器的 API 与使用场景,包括 HashSet、HashMap、ArrayList、Deque 及 PriorityQueue。同时涵盖了 String 与 StringBuilder 的特性对比、常用工具类(Arrays、Collections、Math)的核心方法,以及静态代码块等技巧,旨在帮助开发者掌握笔试与面试所需的 Java 基础语法与编码规范。
并发大师1 浏览 机试模式
一、ACM 模式(OJ 机试 / 笔试模式)
需要自己处理:输入解析、边界条件、输出格式。
特点:给定标准输入/标准输出,以是否全部 AC 为唯一标准,笔试/初筛,重点输入输出 + 边界。
ACM 模式下,Java 通常使用 BufferedReader 进行高效输入,必要时通过 while 读取 EOF(文件),避免使用 Scanner 以防性能问题(但使用简单)。
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String s = br.readLine();
String[] nums = br.readLine().trim().split("\\s+");
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(nums[i]);
}
System.out.println(n);
System.out.println(s);
System.out.println(Arrays.toString(nums));
}
}
二、LeetCode 模式(函数实现 / 面试官机试)
特点:更偏'思路 + 代码质量 + 沟通能力',只需实现函数体,现场或远程共享屏幕技术面。
没有自动补全提示功能,所以下面的常用方法名称要牢记(注意区分大小写)。
基本语法
常用容器
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
注意:Java 里面用 == ,比较的是对象的地址(除了基本类型)。
**HashSet:**无序、去重、O(1) 查找。
Set<Integer> set = new HashSet<>();
set.add(x);
set.remove(x);
set.contains(x);
set.size();
set.isEmpty();
set.clear();
Map<Integer, Integer> map = new HashMap<>();
map.put(k, v);
map.remove(k);
map.get(k);
map.containsKey(k);
map.size();
map.keySet();
map.put(x, map.getOrDefault(x, 0) + 1);
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
int key = entry.getKey();
int val = entry.getValue();
}
Map<String, Integer> map = new HashMap<>(word_map);
map1.equals(map2);
**ArrayList:**顺序容器,有序,可重复、也叫动态数组。
List<Integer> list = new ArrayList<>();
list.add(x);
list.get(i);
list.set(i, x);
list.remove(i);
list.size();
list.contains(x);
list.addAll(otherList);
for (int i = 0; i < list.size(); i++) {
int x = list.get(i);
}
**Queue / Deque:**队列 / 双端队列。
Queue<Integer> queue = new LinkedList<>();
queue.offer(x);
queue.poll();
queue.peek();
Deque<Integer> deque = new ArrayDeque<>();
dec.addFirst() / addLast();
pollFirst() / pollLast();
peekFirst() / peekLast();
while (!queue.isEmpty()) {
int x = queue.poll();
}
补充:Stack 是 Java 早期提供的栈实现,继承自 Vector,由于 Vector 是线程安全的(所有方法加了 synchronized),导致性能较差。一般使用 Deque 实现栈:
Deque<String> stack = new ArrayDeque<>();
| 栈操作 | Deque 实际调用 |
|---|
push(x) | addFirst(x) |
pop() | removeFirst() |
peek() | peekFirst() |
**PriorityQueue:**默认小根堆,Top K 问题。
PriorityQueue<Integer> pq = new PriorityQueue<>();
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
pq.offer(x);
pq.poll();
pq.peek();
pq.size();
String
String 是不可变对象,任何修改操作都会生成新的字符串(保证线程安全和字符串常量池的共享,避免安全问题)。
String s3 = s1 + s2;
s.length();
s.charAt(i);
s.substring(l);
s.substring(l, r);
s.indexOf('a');
s.indexOf("abc");
s.lastIndexOf('a');
s.equals(t);
s.equalsIgnoreCase(t);
s.startsWith("pre");
s.endsWith("suf");
s.trim();
s.strip();
String[] parts = s.split(",");
List<String> wordList = Arrays.asList(s.split("\\s+"));
s.contains("abc");
s.replace("ab", "c");
s.replaceAll("\\d+", "#");
s.isEmpty();
s.isBlank();
int x = Integer.parseInt("123");
String s = String.valueOf(123);
char[] arr = s.toCharArray();
List<String> list = List.of("a", "b", "c");
String s = String.join("-", list);
String s = String.join(",", "a", "b", "c");
StringBuilder 是可变字符串容器,用于高效拼接字符串,避免 String 在循环中频繁创建新对象。
StringBuilder sb3 = new StringBuilder("abc");
sb3.append("abc");
String s = sb3.toString();
sb3.deleteCharAt(i);
sb3.delete(l, r);
sb3.insert(i, "abc");
sb3.setCharAt(i, 'x');
sb3.reverse();
sb3.length();
sb3.setLength(0);
sb3.replace(l, r, "xyz");
StringBuilder 是可变字符串类,常用于循环中高效拼接字符串;与 StringBuffer 相比不保证线程安全但性能更好,因此在刷题和单线程场景下优先使用。
| 需求 | 推荐 |
|---|
| 少量拼接 | String |
| 循环大量拼接(一个一个拼接这种!!) | StringBuilder |
| 多线程拼接 | StringBuffer |
| 分隔符拼接 | StringJoiner(用的也不多) / String.join |
工具类
Arrays.sort(arr);
Arrays.sort(arr, 1, 4);
Arrays.sort(nums, (a, b) -> b - a);
int idx = Arrays.binarySearch(arr, 8);
Arrays.fill(dp, 0);
Arrays.equals(a, b);
Arrays.toString(arr);
int[] c = Arrays.copyOfRange(a, 0, a.length);
Integer[] nums = {1, 2, 3};
List<Integer> list = Arrays.asList(nums);
List<Integer> list = new ArrayList<>(Arrays.asList(nums));
Character.isLetter(), isUpperCase, toUpperCase, toLowerCase, isLowerCase, isDigit, isLetterOrDigit
int ans = Integer.MAX_VALUE;
**Collections 工具类:**专门操作集合 list 的静态方法。
Collections.sort(list);
Collections.reverse(list);
Collections.max(list);
Collections.min(list);
Math.abs(x)
Math.max(a, b)
Math.min(a, b)
Math.sqrt(x)
Math.pow(2, 3)
Math.floor(x)
Math.ceil(x)
Math.round(x)
Math.random()
生成随机数最常用的是 Random.nextInt(n) 生成 [0,n),生成 [l,r] 用 l + nextInt(r-l+1);Math.random() 本质也是基于 Random。
常用技巧
**构造代码块:**每创建一次对象就执行一次,在构造方法之前执行。
{
map.putAll(Map.of(
'I', 1,
'V', 5,
'X', 10,
'L', 50,
'C', 100,
'D', 500,
'M', 1000
));
}