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]

使用 Comparator 排序

如果需要自訂規則——例如,依字串長度排序:

List<String> words = new ArrayList<>(List.of("kot", "slon", "mukha", "nosorog"));

words.sort(Comparator.comparingInt(String::length));
System.out.println(words); // [kot, slon, mukha, nosorog]

反向排序:

words.sort(Comparator.comparingInt(String::length).reversed());
System.out.println(words); // [nosorog, mukha, slon, kot]

舊寫法,透過 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)。若要依部分字串或物件欄位搜尋——請使用帶條件的迴圈,或使用比較器/Stream。

1
任務
JAVA 25 SELF, 等級 29, 課堂 4
上鎖
追蹤森林中動物的出現 🌲🐾
追蹤森林中動物的出現 🌲🐾
1
任務
JAVA 25 SELF, 等級 29, 課堂 4
上鎖
分析競技聯賽比賽結果 🎮📊
分析競技聯賽比賽結果 🎮📊
1
問卷/小測驗
Comparator 和物件比較,等級 29,課堂 4
未開放
Comparator 和物件比較
Comparator 和物件比較
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION