写 Java 程序几乎离不开集合框架。这篇把最常用的三大接口 List、Set、Map 讲清楚:各自的特点、常用实现类和选择方法。

List:有序、可重复

ArrayList 是最常用的实现类,底层是动态数组:

import java.util.ArrayList;
import java.util.List;

List<String> langs = new ArrayList<>();
langs.add("Java");
langs.add("Python");
langs.add("Java");          // 允许重复

System.out.println(langs.get(0));            // 按下标取:Java
System.out.println(langs.size());            // 3
System.out.println(langs.contains("Java"));  // true

langs.remove("Java");        // 删除第一个匹配项

需要按顺序访问、允许重复元素时用 List。

Set:不重复

HashSet 不保证顺序,但保证元素不重复:

import java.util.HashSet;
import java.util.Set;

Set<String> tags = new HashSet<>();
tags.add("java");
tags.add("php");
tags.add("java");            // 添加失败,元素已存在

System.out.println(tags.size());             // 2
System.out.println(tags.contains("php"));    // true

去重场景首选 Set,比如记录访问过的用户 ID。

Map:键值对

HashMap 存键值对,通过键快速查找值:

import java.util.HashMap;
import java.util.Map;

Map<String, Integer> stock = new HashMap<>();
stock.put("苹果", 10);
stock.put("香蕉", 3);

System.out.println(stock.get("苹果"));           // 10
System.out.println(stock.getOrDefault("梨", 0)); // 0(键不存在时给默认值)

stock.put("苹果", 8);            // 同一个键会覆盖旧值
stock.remove("香蕉");

// 遍历
for (Map.Entry<String, Integer> e : stock.entrySet()) {
    System.out.println(e.getKey() + " 剩 " + e.getValue());
}

怎么选:一句话口诀

  • 要顺序、可重复 → List(ArrayList)
  • 要去重、快速判断存在 → Set(HashSet)
  • 要键值映射、按键查找 → Map(HashMap)

综合小例子:词频统计

import java.util.HashMap;
import java.util.Map;

public class WordCount {
    public static void main(String[] args) {
        String[] words = {"java", "php", "java", "css", "java"};

        Map<String, Integer> count = new HashMap<>();
        for (String w : words) {
            count.put(w, count.getOrDefault(w, 0) + 1);
        }
        System.out.println(count);   // {java=3, php=1, css=1}
    }
}

词频统计是 Map 最经典的应用,getOrDefault 一行搞定"有则加一、无则置一"。

小结

  • 集合类都在 java.util 包,声明时用泛型 <类型> 保证类型安全
  • ArrayList 按下标存取,HashSet 自动去重,HashMap 按键找值
  • 遍历 Map 用 entrySet(),读取值优先用 getOrDefault()
  • 口诀:顺序 List、去重 Set、映射 Map

熟练使用这三大接口,就能应付日常开发里绝大多数的数据组织需求。