迭代器:
迭代器的使用分 3 步:获取迭代器 → 判断是否有下一个元素 → 获取元素 / 删除元素,核心 API 是:
iterator():从集合获取迭代器对象hasNext():判断是否还有下一个元素(避免越界)next():获取当前元素并移动指针remove():删除刚获取的元素(唯一安全的遍历中删除方式)
1. 基础遍历(所有集合通用:List/Set/Map)
示例 1:遍历 List(最常用)
java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("Go");
// 1. 获取迭代器
Iterator<String> iterator = list.iterator();
// 2. 遍历:hasNext() 判断,next() 获取
while (iterator.hasNext()) {
// 3. 获取当前元素
String element = iterator.next();
System.out.println("遍历到:" + element);
// 【可选】遍历中删除元素(只有迭代器的 remove() 不会报错)
if ("Python".equals(element)) {
iterator.remove(); // 删除刚获取的 "Python"
}
}
// 遍历后验证:Python 已被删除
System.out.println("删除后的集合:" + list); // 输出 [Java, Go]
}
}
示例 2:遍历 Set(和 List 写法完全一致)
java
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class IteratorSetDemo {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()) {
Integer num = iterator.next();
System.out.println(num);
}
}
}
示例 3:遍历 Map(先转成 Set 再用迭代器)
Map 本身没有迭代器,需要先转成 entrySet()/keySet()(推荐 entrySet(),效率更高):
java
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class IteratorMapDemo {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("A", 10);
map.put("B", 20);
map.put("C", 30);
// 方式1:遍历键值对(推荐)
Iterator<Entry<String, Integer>> entryIterator = map.entrySet().iterator();
while (entryIterator.hasNext()) {
Entry<String, Integer> entry = entryIterator.next();
System.out.println("键:" + entry.getKey() + ",值:" + entry.getValue());
}
// 方式2:只遍历键
Iterator<String> keyIterator = map.keySet().iterator();
while (keyIterator.hasNext()) {
String key = keyIterator.next();
System.out.println("键:" + key + ",值:" + map.get(key));
}
}
}
、迭代器的避坑点(新手必看)
- 必须先 hasNext (),再 next () :直接调用 next () 会导致
NoSuchElementException(没有下一个元素); - remove () 只能在 next () 之后调用 :没调用 next () 就删,会抛
IllegalStateException; - 迭代器是一次性的:遍历完后,迭代器指针到末尾,不能重复用,需重新获取:
一、必须用迭代器的 3 个核心场景
1. 遍历集合时需要删除元素(最常用)
这是迭代器唯一不可替代 的场景 ------ 普通 for / 增强 for 要么报错、要么漏元素,只有迭代器的 remove() 能安全删除。
业务示例:
- 筛选集合:删除列表中 "状态为失效" 的用户、删除 Set 中 "值小于 0" 的数字;
- 清理数据:遍历订单列表,删除 "已取消" 的订单。
反例(增强 for 必报错):
java
List<Order> orderList = getOrderList();
// 增强 for 遍历删除 → 抛 ConcurrentModificationException
for (Order order : orderList) {
if (order.getStatus() == 0) { // 0=已取消
orderList.remove(order); // 报错!
}
}
正确写法(迭代器):
java
Iterator<Order> it = orderList.iterator();
while (it.hasNext()) {
Order order = it.next();
if (order.getStatus() == 0) {
it.remove(); // 安全删除,不报错、不漏元素
}
}
2. 遍历未知类型的集合(通用遍历)
如果你写的是通用工具类(比如框架、公共方法),不知道传入的集合是 List/Set/Queue,迭代器是所有集合通用的遍历方式。
业务示例:
- 写一个 "打印任意集合内容" 的工具方法:
java
// 通用工具方法:支持所有实现 Iterable 接口的集合
public static void printCollection(Iterable<?> collection) {
Iterator<?> it = collection.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
// 调用:List/Set 都能传
List<String> list = new ArrayList<>();
Set<Integer> set = new HashSet<>();
printCollection(list);
printCollection(set);
3. 遍历并发集合(避免并发修改异常)
多线程场景下,使用 CopyOnWriteArrayList/ConcurrentHashMap 等并发集合时,迭代器是弱一致性的(不会抛异常),而普通遍历可能出问题。
java
// 并发集合的迭代器遍历(安全)
CopyOnWriteArrayList<String> concurrentList = new CopyOnWriteArrayList<>();
concurrentList.add("a");
concurrentList.add("b");
Iterator<String> it = concurrentList.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
// 即使主线程修改集合,迭代器也不会报错(弱一致性)
concurrentList.add("c");
}
二、不需要用迭代器的场景(用更简洁的写法)
如果只是 "单纯遍历、不修改集合",迭代器的写法反而繁琐,优先用更简单的方式:
1. 单纯遍历(无修改)→ 增强 for 循环 /forEach
java
// 增强 for 循环(最简洁)
List<String> list = new ArrayList<>();
for (String s : list) {
System.out.println(s);
}
// Java 8+ forEach(Lambda 更简洁)
list.forEach(s -> System.out.println(s));
// 或方法引用
list.forEach(System.out::println);
2. 需要下标操作 → 普通 for 循环
如果遍历过程中需要用到 "元素的下标"(比如定位位置、按索引修改),直接用普通 for 循环:
java
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
// 按下标修改元素
for (int i = 0; i < list.size(); i++) {
if (i == 1) {
list.set(i, "new value"); // 通过下标修改
}
}
3. 流式处理(Java 8+)→ Stream API
如果需要 "过滤、映射、聚合" 等复杂操作,优先用 Stream,比迭代器更优雅:
java
List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5);
// 过滤出偶数并打印(无需迭代器)
numList.stream()
.filter(num -> num % 2 == 0)
.forEach(System.out::println);

- 业务代码:知道是 List/Set,单纯遍历 → 增强 for 就行;
- 工具代码:不知道传入什么集合,需要通用适配 → 迭代器更严谨。
Hutool工具:
官方文档地址在这里:https://hutool.cn/docs


1. hutool-aop
功能:JDK 动态代理封装,在非 IOC 环境下实现 AOP 切面(比如日志、权限校验)
java
// 定义切面
AspectHandler handler = new AspectHandler() {
@Override
public boolean before(Object target, Method method, Object[] args) {
System.out.println("方法执行前:" + method.getName());
return true;
}
};
// 代理目标对象
UserService userService = new UserService();
UserService proxy = ProxyUtil.proxy(userService, handler);
proxy.sayHello(); // 执行时会触发before切面
这个一般用不到因为咱们一般就必须用spring。
2. hutool-bloomFilter
功能:布隆过滤器,用于判断一个元素是否存在于集合中(适合大数据量场景,如缓存穿透防护)。
Go
BitMapBloomFilter filter = new BitMapBloomFilter(1000);
filter.add("https://www.baidu.com");
System.out.println(filter.contains("https://www.baidu.com")); // true
System.out.println(filter.contains("https://www.google.com")); // false
3. hutool-cache
功能:简单缓存实现(FIFO、LRU、Timed 等策略),用于本地缓存。
java
public class LRUTest {
public static void main(String[] args) {
Cache<String, String> cache = CacheUtil.newLRUCache(3);
cache.put("key1", "value1");
cache.put("key2", "value2");
cache.put("key3", "value3");
// 关键:访问key1,刷新它的「最后使用时间」,使其成为"较新使用"的元素
cache.get("key1");
cache.put("key4", "value4"); // 触发淘汰,此时最久未被使用的是key2
System.out.println(cache.get("key1")); // value1(未被淘汰)
System.out.println(cache.get("key2")); // null(被淘汰)
}
}
java
import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
public class HutoolCacheStrategyTest {
public static void main(String[] args) throws InterruptedException {
// 1. LRU+定时过期(容量2,元素2秒过期)
Cache<String, String> lruCache = CacheUtil.newLRUCache(2, 2000);
lruCache.put("k1", "v1");
lruCache.put("k2", "v2");
lruCache.get("k1"); // 刷新k1的访问时间
lruCache.put("k3", "v3"); // 淘汰k2(LRU:k2最久未访问)
System.out.println(lruCache.get("k2")); // null
// 等待3秒,k1/k3过期
Thread.sleep(3000);
System.out.println(lruCache.get("k1")); // null(已过期)
// 2. FIFO+定时过期(容量2,元素2秒过期)
Cache<String, String> fifoCache = CacheUtil.newFIFOCache(2, 2000);
fifoCache.put("k1", "v1");
fifoCache.put("k2", "v2");
fifoCache.get("k1"); // FIFO无视访问,不影响顺序
fifoCache.put("k3", "v3"); // 淘汰k1(FIFO:k1最先插入)
System.out.println(fifoCache.get("k1")); // null
}
}
4. hutool-core(核心,必用)
功能:包含 Bean 操作、日期、字符串、集合等各种 Util,是 Hutool 的基础。
java
// 字符串判空
String str = null;
System.out.println(StrUtil.isEmpty(str)); // true
// 日期格式化
String now = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
System.out.println(now); // 2026-02-19 15:30:00
// Bean转Map
User user = new User("张三", 20);
Map<String, Object> map = BeanUtil.beanToMap(user);
System.out.println(map); // {name:张三, age:20}
5. hutool-cron
功能:定时任务模块,支持类 Crontab 表达式,用于执行定时任务。
java
// 定义任务
CronUtil.schedule("*/2 * * * * *", (Task) () -> System.out.println("每2秒执行一次"));
// 启动定时任务
CronUtil.start();
// 10秒后停止
ThreadUtil.sleep(10000);
CronUtil.stop();
6. hutool-crypto
功能:加密解密模块,支持对称(AES)、非对称(RSA)和摘要算法(MD5、SHA)。
java
// MD5加密
String md5 = SecureUtil.md5("123456");
System.out.println(md5); // e10adc3949ba59abbe56e057f20f883e
// AES加密解密
AES aes = SecureUtil.aes();
String encrypt = aes.encryptBase64("敏感数据");
String decrypt = aes.decryptStr(encrypt);
System.out.println(decrypt); // 敏感数据
7. hutool-db
功能:JDBC 封装,基于 ActiveRecord 思想,简化数据库操作(无需写大量 JDBC 代码)。
java
// 初始化数据源
DataSource ds = new DruidDataSource();
// 执行查询
List<Map<String, Object>> list = DbUtil.findAll(ds, "user");
System.out.println(list);
8. hutool-dfa
功能:基于 DFA 模型的多关键字查找,用于敏感词过滤。
java
WordTree wordTree = new WordTree();
wordTree.addWord("敏感词1");
wordTree.addWord("敏感词2");
// 查找文本中的敏感词
String text = "这是包含敏感词1的文本";
List<String> words = wordTree.matchAll(text, -1, false, false);
System.out.println(words); // [敏感词1]
9. hutool-extra
功能:扩展模块,对第三方组件封装(邮件、模板引擎、二维码、FTP 等)
java
// 生成二维码图片
QrCodeUtil.generate("https://github.com", 300, 300, FileUtil.file("qrcode.png"));
邮件功能(封装 JavaMail)
Hutool 封装了邮件发送的核心逻辑,支持普通文本邮件、带附件 / 图片的邮件,无需手动构建复杂的 Session 和 MimeMessage。
java
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
public class MailExample {
public static void main(String[] args) {
// 1. 配置邮件账户(以QQ邮箱为例,需开启SMTP并获取授权码)
MailAccount account = new MailAccount();
account.setHost("smtp.qq.com"); // SMTP服务器地址
account.setPort(465); // SMTP端口(QQ邮箱是465,网易是25)
account.setAuth(true); // 开启认证
account.setFrom("你的QQ邮箱@qq.com"); // 发件人
account.setUser("你的QQ邮箱@qq.com"); // 用户名(同发件人)
account.setPass("你的QQ邮箱SMTP授权码"); // 授权码(不是登录密码)
account.setSslEnable(true); // QQ邮箱需开启SSL
// 2. 发送普通文本邮件
MailUtil.send(account,
"收件人邮箱@xxx.com", // 收件人
"Hutool邮件测试", // 标题
"这是Hutool封装的邮件发送示例", // 内容
false); // 是否为HTML格式(false=纯文本)
// 3. 发送带附件的邮件(扩展用法)
// MailUtil.send(account, CollUtil.newArrayList("收件人1@xxx.com", "收件人2@xxx.com"),
// "带附件的邮件", "邮件内容",
// true, // HTML格式
// FileUtil.file("D:/test.txt")); // 附件文件
}
}
模板引擎(封装 FreeMarker/Beetl 等)
java
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
public class TemplateExample {
public static void main(String[] args) {
// 1. 配置模板引擎(指定模板文件目录,使用FreeMarker)
// TemplateConfig参数:模板目录、模板引擎类型(FreeMarker/Beetl/Enjoy)
TemplateConfig config = new TemplateConfig("D:/templates", TemplateConfig.ResourceMode.FILE);
TemplateEngine engine = TemplateUtil.createEngine(config);
// 2. 准备模板数据
Map<String, Object> data = new HashMap<>();
data.put("name", "张三");
data.put("age", 25);
// 3. 加载模板文件(假设D:/templates下有test.ftl文件,内容:你好${name},年龄${age})
Template template = engine.getTemplate("test.ftl");
// 4. 渲染模板并输出
StringWriter writer = new StringWriter();
template.render(data, writer);
System.out.println(writer.toString()); // 输出:你好张三,年龄25
// 5. 也可直接渲染字符串模板(无需文件)
String templateStr = "Hello ${name}, age ${age}";
String result = TemplateUtil.render(templateStr, data);
System.out.println(result); // 输出:Hello 张三, age 25
}
}
二维码功能(封装 ZXing)
Hutool 简化了 ZXing 的二维码生成 / 解析逻辑,一行代码即可生成二维码图片,无需手动处理 BitMatrix。
java
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import java.awt.Color;
public class QrCodeExample {
public static void main(String[] args) {
// 1. 生成简单二维码(默认配置,内容为URL,保存到本地)
QrCodeUtil.generate(
"https://www.baidu.com", // 二维码内容
QrConfig.create(), // 默认配置(尺寸300x300)
"D:/qrcode.png" // 保存路径
);
// 2. 自定义二维码配置(尺寸、颜色、边距)
QrConfig config = new QrConfig(400, 400); // 尺寸400x400
config.setForeColor(Color.BLUE.getRGB()); // 前景色(二维码颜色)
config.setBackColor(Color.WHITE.getRGB()); // 背景色
config.setMargin(1); // 边距(越小二维码越大)
QrCodeUtil.generate(
"Hutool二维码测试",
config,
"D:/qrcode_custom.png"
);
// 3. 解析二维码图片
String content = QrCodeUtil.decode("D:/qrcode.png");
System.out.println("解析结果:" + content); // 输出:https://www.baidu.com
}
}
FTP 功能(封装 JDK 原生 FTP)
Hutool 封装了 FTP 的连接、上传、下载、删除等操作,无需手动处理 FTPClient 的连接和关闭。
java
import cn.hutool.extra.ftp.Ftp;
import cn.hutool.extra.ftp.FtpConfig;
import java.io.File;
public class FtpExample {
public static void main(String[] args) {
// 1. 配置FTP连接信息
FtpConfig config = new FtpConfig();
config.setHost("127.0.0.1"); // FTP服务器地址
config.setPort(21); // FTP端口(默认21)
config.setUser("ftp用户名"); // 登录用户名
config.setPass("ftp密码"); // 登录密码
config.setTimeout(30000); // 超时时间(毫秒)
// 2. 创建FTP客户端(try-with-resources自动关闭连接)
try (Ftp ftp = new Ftp(config)) {
// 3. 上传文件(本地文件→FTP服务器目录)
ftp.upload(
"/ftp/test", // FTP服务器目标目录(不存在会自动创建)
new File("D:/local/test.txt") // 本地文件
);
// 4. 下载文件(FTP服务器文件→本地目录)
ftp.download(
"/ftp/test/test.txt", // FTP服务器文件路径
new File("D:/download/test.txt") // 本地保存路径
);
// 5. 删除FTP服务器文件
ftp.delFile("/ftp/test/test.txt");
// 6. 列出FTP目录下的文件
String[] files = ftp.ls("/ftp/test");
for (String file : files) {
System.out.println("FTP文件:" + file);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
JSONPath(解析 JSON):
java
import cn.hutool.extra.json.JSONUtil;
import cn.hutool.extra.jsonpath.JsonPathUtil;
String json = "{\"user\":{\"name\":\"张三\",\"age\":25}}";
String name = JsonPathUtil.extract(json, "$.user.name");
System.out.println(name); // 输出:张三
拼音转换:
java
import cn.hutool.extra.pinyin.PinyinUtil;
String pinyin = PinyinUtil.getPinyin("中国", ""); // 转成无分隔符拼音
System.out.println(pinyin); // 输出:zhongguo
身份证验证:
java
import cn.hutool.extra.idcard.IdcardUtil;
boolean isLegal = IdcardUtil.isValidCard("110101199003074512");
System.out.println("身份证是否合法:" + isLegal);
10. hutool-http
功能:基于 HttpURLConnection 的 HTTP 客户端封装,简化 HTTP 请求。
java
// 发送GET请求
String result = HttpUtil.get("https://www.baidu.com");
System.out.println(result);
// 发送POST请求
Map<String, Object> param = MapUtil.of("key", "value");
String postResult = HttpUtil.post("https://example.com", param);
11. hutool-log
功能:自动识别日志实现的门面(SLF4J、Log4j 等),统一日志 API。
java
Log log = LogFactory.get();
log.info("这是一条日志信息");
log.error("这是一条错误日志", new RuntimeException("测试异常"));
一、hutool-log 真正的用处(3 个核心场景)
1. 【最核心】换日志框架不用改代码(解耦)
假设你现在项目用的是 Log4j2,后来想换成 Logback:
- 不用 hutool-log:你要把代码里所有
org.apache.logging.log4j.Logger改成org.slf4j.Logger,逐行改、逐类改,容易漏、容易错; - 用 hutool-log:代码里只写
cn.hutool.log.Log,底层自动适配 Log4j2/Logback/SLF4J,一行代码都不用改。
本质:把你的代码和底层日志框架 "解耦" 了。
- 【最实用】兼容各种日志场景,避免 "日志用不了"
有些老项目 / 第三方包可能混用多种日志框架(比如既有 Log4j1,又有 SLF4J),直接用原生 API 可能出现:
- 日志打不出来;
- 日志级别不生效;
- 报
ClassNotFoundException。
hutool-log 会自动识别当前环境的日志实现,帮你 "抹平差异",不管底层是啥,你调用 log.info() 都能正常输出。
- 【小便利】API 更简洁,少写冗余代码
原生 SLF4J 写日志要先声明:
java
// 原生 SLF4J
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger log = LoggerFactory.getLogger(YourClass.class);
用 hutool-log 可以一行搞定:
java
// hutool-log
import cn.hutool.log.LogUtil;
private static final Log log = LogUtil.get(); // 自动识别当前类,不用传 YourClass.class
建议用的场景:
- 多模块 / 多项目整合,可能混用不同日志框架;
- 老项目迁移,想低成本切换日志实现;
- 想统一团队的日志调用风格,减少新人写错。
12. hutool-script
功能:脚本执行封装,支持执行 JavaScript 等脚本。
java
// 执行JavaScript脚本
String script = "1 + 2 * 3";
Object result = ScriptUtil.eval("js", script);
System.out.println(result); // 7
13. hutool-setting
功能:更强大的配置文件和 Properties 封装,支持多级配置、类型转换。
java
// 读取配置文件
Setting setting = new Setting("config.setting");
String name = setting.getStr("user.name");
int age = setting.getInt("user.age");
System.out.println(name + " " + age);
java
import cn.hutool.setting.Setting;
public class HutoolSettingTest {
public static void main(String[] args) {
// 1. 加载配置文件(自动处理路径,无需手动关流)
Setting setting = new Setting("config.setting");
// 2. 读字符串(支持多级key,也支持完整key)
String dbUrl = setting.getStr("db", "url"); // 多级写法:(一级key, 二级key)
String redisHost = setting.getStr("redis.host"); // 兼容完整key写法
// 3. 读数字/布尔(自动转换,直接设默认值,无需手动转)
int dbPoolSize = setting.getInt("db", "pool.size", 10); // 默认值10
boolean dbEnable = setting.getBool("db", "enable", false); // 默认值false
int redisPort = setting.getInt("redis", "port", 6379);
System.out.println("数据库连接池大小:" + dbPoolSize);
System.out.println("是否启用数据库:" + dbEnable);
}
}
14. hutool-system
功能:系统参数调用封装(JVM 信息、操作系统信息等)。
java
// 获取JVM内存信息
long totalMemory = SystemUtil.getTotalMemory();
long freeMemory = SystemUtil.getFreeMemory();
System.out.println("总内存:" + totalMemory + ",空闲内存:" + freeMemory);
15. hutool-json
功能:轻量级 JSON 实现,支持 Bean 与 JSON 互转。
java
// Bean转JSON
User user = new User("张三", 20);
String json = JSONUtil.toJsonStr(user);
System.out.println(json); // {"name":"张三","age":20}
// JSON转Bean
User user2 = JSONUtil.toBean(json, User.class);
System.out.println(user2.getName()); // 张三
16. hutool-captcha
功能:图片验证码实现,用于生成登录验证码。
java
// 生成验证码图片
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100);
String code = captcha.getCode();
System.out.println("验证码:" + code);
captcha.write(FileUtil.file("captcha.png"));
17. hutool-poi
功能:针对 POI 的 Excel 和 Word 封装,简化 Office 文件操作。
java
// 读取Excel
ExcelReader reader = ExcelUtil.getReader("test.xlsx");
List<List<Object>> data = reader.read();
System.out.println(data);
// 写入Excel
List<String> row1 = CollUtil.newArrayList("姓名", "年龄");
List<String> row2 = CollUtil.newArrayList("张三", "20");
List<List<String>> rows = CollUtil.newArrayList(row1, row2);
ExcelWriter writer = ExcelUtil.getWriter("output.xlsx");
writer.write(rows);
writer.close();
18. hutool-socket
功能:基于 Java NIO 和 AIO 的 Socket 封装,简化网络编程。
java
NioClient client = new NioClient(InetAddress.getByName("localhost"), 1234);
client.send("Hello Server");
String resp = client.read();
System.out.println(resp);
client.close();
19. hutool-jwt
功能:JSON Web Token (JWT) 封装实现,用于生成和解析 JWT。
java
// 生成JWT
String token = JWTUtil.createToken(MapUtil.of("userId", "123"), "secretKey".getBytes());
System.out.println(token);
// 解析JWT
Map<String, Object> payload = JWTUtil.parseToken(token, "secretKey".getBytes());
System.out.println(payload.get("userId")); // 123