
理解 ArrayList.indexOf() 的局限性
在 java 的 arraylist 中,indexof(object o) 方法用于返回指定元素在列表中第一次出现的索引,如果列表中不包含该元素,则返回 -1。当列表中存在多个相同值的元素时,反复调用 indexof() 无论在哪个位置,它总是返回第一个匹配项的索引。这就是为什么在尝试查找所有相同元素索引时,如果仅依赖 indexof(),会导致结果不正确。例如,对于列表 [5, 5, 4, 5],list.indexof(5) 始终返回 0,即使 5 也存在于索引 1 和 3。
为了准确地找到所有匹配元素的索引,我们需要遍历 ArrayList 中的每一个元素,并逐一检查其值是否与目标值相等。
方法一:使用 for 循环遍历查找
for 循环是遍历 ArrayList 并访问每个元素的常用且直观的方式。通过这种方法,我们可以利用索引 i 逐个访问列表中的元素,并判断其是否为目标值。
示例代码:
import java.util.ArrayList;
import java.util.Scanner;
public class ArrayListIndexFinder {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
// 1. 用户输入整数填充 ArrayList
ArrayList list = new ArrayList<>();
System.out.println("请连续输入整数,输入 -1 结束列表填充:");
while (true) {
int read = Integer.valueOf(reader.nextLine());
if (read == -1) {
break;
}
list.add(read);
}
// 2. 获取用户想要查找的数字
System.out.print("您要查找哪个数字? ");
int requestedNum = Integer.valueOf(reader.nextLine());
// 3. 使用 for 循环查找所有匹配的索引
ArrayList foundIndexes = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
// 检查当前索引 i 处的元素是否与目标数字相等
if (list.get(i) == requestedNum) {
foundIndexes.add(i); // 如果相等,则将当前索引添加到结果列表中
}
}
// 4. 输出结果
if (foundIndexes.isEmpty()) {
System.out.println("数字 " + requestedNum + " 在列表中未找到。");
} else {
System.out.println("数字 " + requestedNum + " 可以在以下索引找到: " + foundIndexes);
}
reader.close(); // 关闭 Scanner
}
} 运行示例(输入):
立即学习“Java免费学习笔记(深入)”;
请连续输入整数,输入 -1 结束列表填充: 5 5 4 5 -1 您要查找哪个数字? 5
预期输出:
数字 5 可以在以下索引找到: [0, 1, 3]
方法二:使用 while 循环遍历查找
除了 for 循环,我们也可以使用 while 循环结合一个计数器来达到相同的目的。这种方法在逻辑上与 for 循环类似,只是迭代控制方式有所不同。
示例代码:
import java.util.ArrayList;
import java.util.Scanner;
public class ArrayListIndexFinderWhile { // 不同的类名以避免冲突
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
// 1. 用户输入整数填充 ArrayList
ArrayList list = new ArrayList<>();
System.out.println("请连续输入整数,输入 -1 结束列表填充:");
while (true) {
int read = Integer.valueOf(reader.nextLine());
if (read == -1) {
break;
}
list.add(read);
}
// 2. 获取用户想要查找的数字
System.out.print("您要查找哪个数字? ");
int requestedNum = Integer.valueOf(reader.nextLine());
// 3. 使用 while 循环查找所有匹配的索引
ArrayList foundIndexes = new ArrayList<>();
int count = 0; // 初始化计数器作为当前索引
while (count < list.size()) { // 当计数器小于列表大小时继续循环
// 检查当前索引 count 处的元素是否与目标数字相等
if (list.get(count) == requestedNum) {
foundIndexes.add(count); // 如果相等,则将当前索引添加到结果列表中
}
count++; // 每次循环结束,计数器自增,移动到下一个索引
}
// 4. 输出结果
if (foundIndexes.isEmpty()) {
System.out.println("数字 " + requestedNum + " 在列表中未找到。");
} else {
System.out.println("数字 " + requestedNum + " 可以在以下索引找到: " + foundIndexes);
}
reader.close(); // 关闭 Scanner
}
} 这两种方法都能够有效地遍历 ArrayList 并准确地找出所有与目标值相等的元素的索引。
注意事项与总结
- 理解 indexOf() 的设计目的: indexOf() 旨在快速找到元素的第一次出现,而不是所有出现。对于需要查找所有出现位置的场景,必须进行显式迭代。
- 循环选择: for 循环和 while 循环在功能上都可以实现遍历。通常情况下,for 循环更适合已知循环次数(如遍历集合的所有元素)的场景,代码更简洁。while 循环则在循环条件不确定或需要在循环体内手动控制计数器时更灵活。
- 性能考量: 对于 ArrayList 这种基于数组实现的列表,通过索引进行随机访问(list.get(i))的效率很高,因此这两种遍历方法在性能上差异不大,都是高效且推荐的解决方案。
- 空列表处理: 在上述代码中,如果用户输入的列表为空,或者列表中不包含目标数字,程序会正确地输出“未找到”的信息,体现了良好的健壮性。
通过本文的学习,您应该已经掌握了在 Java ArrayList 中查找所有相同元素索引的正确且高效的方法,避免了 indexOf() 方法带来的常见误区。










