Collections.max和Collections.min通过遍历集合查找极值,要求元素可比较或提供Comparator,适用于简洁获取最大最小值,但需注意空集合抛异常及null处理。

在Java中,当我们需要从一个集合里找出最大的或最小的元素时,
Collections.max
Collections.min
Collections.max(Collection<? extends T> coll)
Collections.min(Collection<? extends T> coll)
Comparable
如果集合中的元素没有实现
Comparable
Collections.max(Collection<? extends T> coll, Comparator<? super T> comp)
Collections.min(Collection<? extends T> coll, Comparator<? super T> comp)
Comparator
需要注意的是,如果集合为空,这两个方法都会抛出
NoSuchElementException
null
Comparable
Comparator
null
NullPointerException
立即学习“Java免费学习笔记(深入)”;
示例代码:
import java.util.*;
public class CollectionExtremes {
public static void main(String[] args) {
// 示例1:使用Integer集合
List<Integer> numbers = Arrays.asList(10, 2, 8, 15, 5);
System.out.println("原始数字列表: " + numbers);
try {
Integer maxNumber = Collections.max(numbers);
Integer minNumber = Collections.min(numbers);
System.out.println("最大数字: " + maxNumber); // 输出: 15
System.out.println("最小数字: " + minNumber); // 输出: 2
} catch (NoSuchElementException e) {
System.out.println("集合为空,无法找到最大或最小元素。");
}
// 示例2:空集合的情况
List<String> emptyList = new ArrayList<>();
try {
Collections.max(emptyList);
} catch (NoSuchElementException e) {
System.out.println("尝试从空集合中查找最大值,抛出异常: " + e.getMessage());
}
// 示例3:使用自定义对象和Comparator
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
System.out.println("\n原始人物列表: " + people);
// 按年龄查找最大值(使用Lambda表达式作为Comparator)
Person oldestPerson = Collections.max(people, Comparator.comparingInt(Person::getAge));
System.out.println("年龄最大的人: " + oldestPerson.getName() + " (" + oldestPerson.getAge() + "岁)"); // 输出: Charlie (35岁)
// 按年龄查找最小值
Person youngestPerson = Collections.min(people, Comparator.comparingInt(Person::getAge));
System.out.println("年龄最小的人: " + youngestPerson.getName() + " (" + youngestPerson.getAge() + "岁)"); // 输出: Bob (25岁)
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}处理自定义对象时,
Collections.max
Collections.min
Person
1. 实现 Comparable
Comparable<T>
compareTo
Comparable
Comparator
Collections.max
Collections.min
这种方式的优点是,一旦定义了自然排序,所有使用
Comparable
TreeSet
TreeMap
Arrays.sort
2. 提供 Comparator
Comparator
Comparator
Comparator
Collections.max
Collections.min
Comparator
我个人的看法是, 多数情况下,我更倾向于使用
Comparator
Comparator
import java.util.*;
// 示例:自定义对象
class Product implements Comparable<Product> {
private String name;
private double price;
private int stock;
public Product(String name, double price, int stock) {
this.name = name;
this.price = price;
this.stock = stock;
}
public String getName() { return name; }
public double getPrice() { return price; }
public int getStock() { return stock; }
@Override
// 定义自然排序:按价格升序
public int compareTo(Product other) {
return Double.compare(this.price, other.price);
}
@Override
public String toString() {
return "Product{" + "name='" + name + '\'' + ", price=" + price + ", stock=" + stock + '}';
}
}
public class CustomObjectMaxMin {
public static void main(String[] args) {
List<Product> products = Arrays.asList(
new Product("Laptop", 1200.00, 50),
new Product("Mouse", 25.50, 200),
new Product("Keyboard", 75.00, 100),
new Product("Monitor", 300.00, 75)
);
System.out.println("原始产品列表:\n" + products);
// 1. 使用Comparable (自然排序:按价格升序)
Product cheapestProduct = Collections.min(products); // 找到价格最低的
Product mostExpensiveProduct = Collections.max(products); // 找到价格最高的
System.out.println("\n按价格自然排序:");
System.out.println("最便宜的产品: " + cheapestProduct);
System.out.println("最贵的产品: " + mostExpensiveProduct);
// 2. 使用Comparator (自定义排序:按库存量)
Comparator<Product> byStock = Comparator.comparingInt(Product::getStock);
Product leastStockProduct = Collections.min(products, byStock); // 找到库存最少的
Product mostStockProduct = Collections.max(products, byStock); // 找到库存最多的
System.out.println("\n按库存自定义排序:");
System.out.println("库存最少的产品: " + leastStockProduct);
System.out.println("库存最多的产品: " + mostStockProduct);
// 3. 使用Comparator (自定义排序:按名称降序)
Comparator<Product> byNameDesc = Comparator.comparing(Product::getName).reversed();
Product maxNameProduct = Collections.max(products, byNameDesc); // 按名称降序,找到“最大”的
System.out.println("\n按名称降序排序,找到“最大”的(即字母序靠后的): " + maxNameProduct);
}
}尽管
Collections.max
Collections.min
性能考量:
时间复杂度:O(n) 这两个方法的工作原理其实非常直接,就是遍历集合中的所有元素,进行逐一比较,从而找到最大或最小的那个。所以,它们的时间复杂度是 O(n),其中 n 是集合中元素的数量。这意味着,当你的集合非常大时,这个操作可能会消耗相对较多的时间。 对我来说,这通常不是一个小集合(比如几十、几百个元素)的瓶颈,但如果面对几十万、上百万甚至更多元素的集合,并且需要频繁调用这两个方法,那确实需要重新审视一下设计了。
比较操作的开销: 除了遍历,每次比较操作本身也有开销。如果你的
Comparable.compareTo
Comparator.compare
潜在陷阱:
NoSuchElementException
Collection
Collections.max
Collections.min
NoSuchElementException
collection.isEmpty()
List<Integer> emptyNumbers = new ArrayList<>();
if (!emptyNumbers.isEmpty()) {
Integer max = Collections.max(emptyNumbers);
} else {
System.out.println("空集合,无法获取最大值。");
}NullPointerException
null
null
Comparable
Comparator
null
NullPointerException
Integer
compareTo
null
null
null
max
min
null
Comparator
null
null
Comparator
null
null
null
List<String> namesWithNull = new ArrayList<>(Arrays.asList("Alice", null, "Bob"));
// 尝试直接查找最大值会抛出 NullPointerException
try {
// Collections.max(namesWithNull); // 运行时会抛出 NullPointerException
// 正确做法:
String maxName = Collections.max(namesWithNull, Comparator.nullsLast(Comparator.naturalOrder()));
System.out.println("处理null后的最大名字: " + maxName); // Bob
} catch (NullPointerException e) {
System.out.println("集合包含null元素且未处理: " + e.getMessage());
}类型不兼容: 集合中的所有元素必须是相互可比较的。如果你在一个
List<Object>
Integer
String
ClassCastException
可变对象: 如果集合中存储的是可变对象,并且其
compareTo
compare
max
min
在我看来,了解这些陷阱,特别是
NoSuchElementException
NullPointerException
Collections.max/min
TreeSet
PriorityQueue
确实,
Collections.max
Collections.min
1. Java 8 Stream API:stream().max()
stream().min()
Stream
max(Comparator<? super T> comparator)
min(Comparator<? super T> comparator)
Optional<T>
NoSuchElementException
优点:
Optional
parallelStream()
缺点:
Collections.max/min
示例:
import java.util.*;
import java.util.stream.Collectors;
public class StreamMaxMin {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(10, 2, 8, 15, 5);
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 使用Stream查找最大/最小数字
Optional<Integer> maxNum = numbers.stream().max(Comparator.naturalOrder());
Optional<Integer> minNum = numbers.stream().min(Comparator.naturalOrder());
maxNum.ifPresent(n -> System.out.println("Stream最大数字: " + n)); // 15
minNum.ifPresent(n -> System.out.println("Stream最小数字: " + n)); // 2
// 处理空集合
List<Integer> emptyList = new ArrayList<>();
Optional<Integer> maxEmpty = emptyList.stream().max(Comparator.naturalOrder());
System.out.println("空集合的Stream最大值: " + maxEmpty.orElse(0)); // 0 (提供默认值)
// 使用自定义Comparator查找最长的名字
Optional<String> longestName = names.stream().max(Comparator.comparingInt(String::length));
longestName.ifPresent(s -> System.out.println("Stream最长的名字: " + s)); // Charlie
}
}2. 手动遍历集合: 这是最基础、最原始的方法。通过一个
for-each
Iterator
优点:
Optional
缺点:
Collections.max/min
null
示例:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ManualMaxMin {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(10, 2, 8, 15, 5);
if (numbers.isEmpty()) {
System.out.println("手动遍历:集合为空。");
return;
}
Integer max = numbers.get(0);
Integer min = numbers.get(0);
for (int i = 1; i < numbers.size(); i++) {
Integer current = numbers.get(i);
if (current == null) { // 手动处理null
continue;
}
if (current > max) {
max = current;
}
if (current < min) {
min = current;
}
}
System.out.println("手动遍历最大数字: " + max); // 15
System.out.println("手动遍历最小数字: " + min); // 2
}
}3. 使用排序数据结构(TreeSet
PriorityQueue
TreeSet
first()
last()
PriorityQueue
peek()
Comparator
peek()
优点:
O(1)
O(log n)
缺点:
O(log n)
示例:
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.TreeSet;
public class SortedDataStructureMaxMin {
public static void main(String[] args) {
// 使用TreeSet
TreeSet<Integer> sortedNumbers = new TreeSet<>(Arrays.asList(10, 2, 8, 15, 5));
System.out.println("TreeSet最小值: " + sortedNumbers.first()); // 2
System.out.println("TreeSet最大值: " + sortedNumbers.last()); // 以上就是Java中使用Collections.max和Collections.min的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号