collections.indexofsublist和lastindexofsublist用于查找连续子列表在源列表中首次或最后一次出现的起始索引,仅支持严格逐元素equals比较,空子列表始终返回0,null输入抛npe,时间复杂度o(n×m)。

Java 中 Collections.indexOfSubList 和 Collections.lastIndexOfSubList 是用于在源列表中查找**连续子列表首次或最后一次出现位置**的静态方法。它们不支持模糊匹配、正则或自定义比较逻辑,只做严格、顺序、逐元素的 equals 比较。
核心行为与限制
这两个方法要求目标子列表必须是**连续、有序、完全相等**的一段元素。它们不是“查找包含某几个元素”,而是“查找一段和 target 完全一致的连续序列”。
- 返回的是子列表在源列表中的起始索引(从 0 开始),找不到返回 -1
- 内部使用
equals()逐个比较元素,因此元素类型需正确重写equals(如 String、Integer 默认可用;自定义类需确保语义合理) - 空列表
Collections.emptyList()作为子列表时,indexOfSubList总返回 0(按规范,空序列被视为出现在每个位置开头) - 若源列表为
null或子列表为null,直接抛NullPointerException
典型使用场景
适用于日志解析、协议帧识别、简单模板匹配等需要定位固定模式连续片段的场合,比如:
- 从一串操作指令列表中查找
[START, INIT, CONFIG]首次出现位置 - 在字节缓冲区(用
List<byte></byte>表示)中定位某个协议头[0x55, 0xAA, 0x00] - 检查 ArrayList 是否以特定前缀开头(此时用
subList(0, n)构造 target 即可)
常见误区与替代方案
容易误以为它们能实现“子集查找”或“乱序匹配”,实际不能。遇到以下需求应换方式:
- 查找非连续元素(如“包含 A、B、C,不要求相邻”)→ 用 Stream + filter 或手动遍历判断
- 忽略大小写或自定义相等逻辑 → 自行实现循环比对,用
Objects.equals(a, b)或自定义谓词 - 性能敏感且频繁调用 → 注意这两个方法时间复杂度为 O(n×m),n 是源列表长度,m 是子列表长度;大数据量建议预建索引或改用字符串 KMP 等算法(若元素可拼接)
- 需要所有匹配位置 → 它们只返回第一个/最后一个,需自己遍历收集
简单示例代码
以下演示基本用法和边界情况:
List<string> source = Arrays.asList("a", "b", "c", "b", "c", "d");
List<string> target = Arrays.asList("b", "c");
int first = Collections.indexOfSubList(source, target); // 返回 1
int last = Collections.lastIndexOfSubList(source, target); // 返回 3
List<string> notFound = Arrays.asList("x", "y");
int miss = Collections.indexOfSubList(source, notFound); // 返回 -1
List<string> empty = Collections.emptyList();
int emptyPos = Collections.indexOfSubList(source, empty); // 返回 0
</string></string></string></string>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











