CodeGym /课程 /JAVA 25 SELF /在 Java 集合中查找与排序元素

在 Java 集合中查找与排序元素

JAVA 25 SELF
第 29 级 , 课程 4
可用

1. 在集合中查找元素

使用标准方法进行查找

当我们有一个列表,例如名字列表:

List<String> names = List.of("Anna", "Boris", "Viktoriya", "Anna", "Dmitriy");

Java 提供了几个便捷的查找方法:

  • contains(Object o) — 检查集合中是否包含该元素。
  • indexOf(Object o) — 返回元素第一次出现的索引(如果未找到则为 -1)。
  • lastIndexOf(Object o) — 返回元素最后一次出现的索引(或 -1)。

示例:

System.out.println(names.contains("Anna"));      // true
System.out.println(names.indexOf("Anna"));       // 0
System.out.println(names.lastIndexOf("Anna"));   // 3
System.out.println(names.contains("Sergey"));    // false

事实: 对于 Set 这类集合,没有 indexOflastIndexOf 方法 — Set 根本没有索引,只有唯一值。

按条件查找

有时需要找到满足某个条件的元素,而不是某个确定的值。例如,找到第一个长度大于 6 的名字。普通的 for 循环就很合适:一旦找到符合条件的元素——使用 break 跳出即可。

List<String> names = List.of("Anna", "Boris", "Viktoriya", "Anna", "Dmitriy");

String found = null;
for (String name : names) {
    if (name.length() > 6) {
        found = name;
        break; // 找到第一个符合条件的元素后即可退出循环
    }
}
System.out.println(found); // Viktoriya

查找最大值与最小值

对于元素可比较的集合(例如数字),可以使用 Collections 快速找到最大值与最小值。

List<Integer> numbers = List.of(10, 5, 20, 7, 20, 3);

int max = Collections.max(numbers); // 20
int min = Collections.min(numbers); // 3

System.out.println("最大值: " + max);
System.out.println("最小值: " + min);

重要: 元素必须是可比较的(实现了 Comparable),否则需要传入比较器。

2. 集合的排序

按默认规则排序列表

只能对可变列表进行排序(例如 ArrayListLinkedList)。像 SetMap 这类集合不支持直接排序。

默认按“自然顺序”排序:数字按升序,字符串按字母序。

List<Integer> numbers = new ArrayList<>(List.of(5, 1, 7, 3));
Collections.sort(numbers);
System.out.println(numbers); // [1, 3, 5, 7]

也可以通过列表的 sort 方法实现相同效果:

List<Integer> numbers = new ArrayList<>(List.of(5, 1, 7, 3));
numbers.sort(null); // null 表示:使用自然顺序
System.out.println(numbers); // [1, 3, 5, 7]

使用比较器排序

如果需要自定义规则——例如按字符串长度排序:

List<String> words = new ArrayList<>(List.of("cat", "elephant", "mukha", "rhino"));

words.sort(Comparator.comparingInt(String::length));
System.out.println(words); // [cat, elephant, mukha, rhino]

逆序:

words.sort(Comparator.comparingInt(String::length).reversed());
System.out.println(words); // [rhino, mukha, elephant, cat]

旧式写法,使用 Collections.sort

Collections.sort(words, Comparator.comparingInt(String::length));

3. 不同集合的排序特性

排序只会改变列表

排序方法(sortCollections.sort)只适用于支持元素顺序的集合(例如 List)。对于 SetMap 并未提供此类方法。

尝试对 Set 排序:

Set<Integer> mySet = new HashSet<>(List.of(3, 1, 2));
Collections.sort(mySet); // 编译错误:sort 需要的是 List!

如果需要从 Set 得到一个已排序的列表:

List<Integer> sortedFromSet = new ArrayList<>(mySet);
Collections.sort(sortedFromSet);
System.out.println(sortedFromSet); // [1, 2, 3]

对 Map 排序:按键和按值

无法直接对 Map 排序,但可以:

  • 获取“键-值”对的列表
  • 按所需方式对其排序
  • 必要时再收集为新的 Map

示例:按值排序

Map<String, Integer> scores = Map.of(
    "Anna", 15,
    "Boris", 20,
    "Vika", 12
);

List<Map.Entry<String, Integer>> entries = new ArrayList<>(scores.entrySet());
entries.sort(Map.Entry.comparingByValue());

for (Map.Entry<String, Integer> entry : entries) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Vika: 12
// Anna: 15
// Boris: 20

按对象字段排序

假设我们有一个用户类:

class User {
    String name;
    int age;
    User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

以及用户列表:

List<User> users = new ArrayList<>(List.of(
    new User("Anna", 22),
    new User("Boris", 18),
    new User("Vika", 25)
));

按年龄排序:

users.sort(Comparator.comparingInt(u -> u.age));
System.out.println(users); // [Boris (18), Anna (22), Vika (25)]

逆序:

users.sort(Comparator.comparingInt((User u) -> u.age).reversed());
System.out.println(users); // [Vika (25), Anna (22), Boris (18)]

4. 在查找与排序集合时的常见错误

错误 1:对不可变列表进行排序。 通过 List.of(...) 创建的列表不可修改——调用 sort 会抛出 UnsupportedOperationException

List<Integer> immutable = List.of(3, 1, 2);
immutable.sort(null); // 会抛出异常!

错误 2:直接对 Set 或 Map 排序。 排序方法不适用于 SetMap。如果需要排序,先把数据转换为列表。

错误 3:错误地比较对象。 比较整数时不要直接相减——可能发生溢出。应使用 Integer.compareComparator.comparingInt,而不是 u1.age - u2.age

// users.sort((u1, u2) -> u1.age - u2.age); // 能运行,但在溢出情况下很危险!

错误 4:在复杂查找场景下使用 contains contains 只检查完全匹配(基于 equals)。如果要按字符串的一部分或对象字段查找——请使用带条件判断的循环,或使用比较器/流。

1
任务
JAVA 25 SELF, 第 29 级, 课程 4
已锁定
在森林中跟踪动物出现 🌲🐾
在森林中跟踪动物出现 🌲🐾
1
任务
JAVA 25 SELF, 第 29 级, 课程 4
已锁定
竞技联赛比赛结果分析 🎮📊
竞技联赛比赛结果分析 🎮📊
1
调查/小测验
比较器和对象比较第 29 级,课程 4
不可用
比较器和对象比较
比较器和对象比较
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION