在Java开发中,查找数组或列表的最大值、最小值以及对应的索引是非常常见的需求,不同的数据结构和使用场景对应着不同的实现方式,下面会逐一介绍。

一、查找基本类型数组的极值及索引
1.1 循环遍历实现
最基础的方式是通过循环遍历数组,逐个比较元素大小,同时记录极值和对应的索引。以下是int类型数组的示例:
public class ArrayExtremeDemo {
public static void main(String[] args) {
int[] arr = {12, 45, 7, 89, 23, 89};
// 假设数组非空,初始化最大值为第一个元素,索引为0
int max = arr[0];
int maxIndex = 0;
int min = arr[0];
int minIndex = 0;
// 从第二个元素开始遍历
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
maxIndex = i;
}
if (arr[i] < min) {
min = arr[i];
minIndex = i;
}
}
System.out.println("最大值:" + max + ",索引:" + maxIndex);
System.out.println("最小值:" + min + ",索引:" + minIndex);
}
}
这种方式的时间复杂度是O(n),适合所有基本类型数组,只需要替换对应的类型即可。需要注意的是,如果数组存在重复的最大值或最小值,上述代码会记录第一次出现的索引,如果需要记录最后一次出现的索引,可以调整判断条件为arr[i] >= max和arr[i] <= min。
1.2 处理空数组的情况
如果数组可能为空或者长度为0,直接访问第一个元素会抛出异常,需要先做校验:
public static void findExtremeInArray(int[] arr) {
if (arr == null || arr.length == 0) {
System.out.println("数组为空,无法查找极值");
return;
}
// 后续遍历逻辑同上
}
二、查找对象数组的极值及索引
如果是对象数组,比如自定义类的数组,需要比较对象的某个属性,这时候可以通过实现Comparable接口或者使用Comparator来比较。以下是自定义User类的示例:
import java.util.Comparator;
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
}
public class ObjectArrayDemo {
public static void main(String[] args) {
User[] users = {new User("张三", 20), new User("李四", 35), new User("王五", 18)};
if (users == null || users.length == 0) {
System.out.println("数组为空");
return;
}
User maxUser = users[0];
int maxIndex = 0;
User minUser = users[0];
int minIndex = 0;
// 使用Comparator比较age属性
Comparator<User> ageComparator = Comparator.comparingInt(User::getAge);
for (int i = 1; i < users.length; i++) {
if (ageComparator.compare(users[i], maxUser) > 0) {
maxUser = users[i];
maxIndex = i;
}
if (ageComparator.compare(users[i], minUser) < 0) {
minUser = users[i];
minIndex = i;
}
}
System.out.println("年龄最大的用户:" + maxUser.getAge() + ",索引:" + maxIndex);
System.out.println("年龄最小的用户:" + minUser.getAge() + ",索引:" + minIndex);
}
}
三、查找列表的极值及索引
3.1 使用Collections工具类
对于List类型的数据,Java的Collections工具类提供了max和min方法,可以直接获取极值,再结合indexOf方法获取索引:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
List<Integer> numList = new ArrayList<>();
numList.add(12);
numList.add(45);
numList.add(7);
numList.add(89);
numList.add(23);
if (numList == null || numList.isEmpty()) {
System.out.println("列表为空");
return;
}
// 获取最大值和最小值
Integer max = Collections.max(numList);
Integer min = Collections.min(numList);
// 获取索引
int maxIndex = numList.indexOf(max);
int minIndex = numList.indexOf(min);
System.out.println("最大值:" + max + ",索引:" + maxIndex);
System.out.println("最小值:" + min + ",索引:" + minIndex);
}
}
这里需要注意,如果列表中有重复的最大值,indexOf返回的是第一次出现的索引,如果需要最后一次出现的索引,可以使用lastIndexOf方法。
3.2 自定义对象列表的查找
如果是自定义对象的列表,同样可以使用Collections的max和min方法,传入自定义的Comparator:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class UserListDemo {
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User("张三", 20));
userList.add(new User("李四", 35));
userList.add(new User("王五", 18));
if (userList.isEmpty()) {
System.out.println("列表为空");
return;
}
// 按年龄查找最大值和最小值
User maxAgeUser = Collections.max(userList, Comparator.comparingInt(User::getAge));
User minAgeUser = Collections.min(userList, Comparator.comparingInt(User::getAge));
int maxIndex = userList.indexOf(maxAgeUser);
int minIndex = userList.indexOf(minAgeUser);
System.out.println("年龄最大的用户年龄:" + maxAgeUser.getAge() + ",索引:" + maxIndex);
System.out.println("年龄最小的用户年龄:" + minAgeUser.getAge() + ",索引:" + minIndex);
}
}
四、不同场景的实现选择
可以通过以下表格对比不同实现方式的适用场景:
| 数据结构 | 实现方式 | 适用场景 |
|---|---|---|
| 基本类型数组 | 循环遍历 | 所有基本类型数组,需要控制索引记录规则 |
| 对象数组 | 循环+Comparator | 需要按自定义属性比较的场景 |
| 列表 | Collections工具类 | 快速实现,不需要自定义遍历逻辑 |
在实际开发中,可以根据数据结构和是否需要自定义比较规则选择合适的实现方式,同时不要忽略空集合的校验,避免出现空指针异常。