下载工作台
Java 编程实战

集合框架:List、Set、Map

试读上半部分 · 解锁后可读全文

第 8 章 · 集合框架:List、Set、Map

本章目标:掌握 Java 集合框架核心接口与实现类——ArrayListHashSetHashMap;熟练使用 Iterator 遍历与删除;理解 ComparableComparator 排序规则;完成 toolkit-demo 商品列表与去重标签练习。

学时建议:4~5 小时(含 1.5 小时跟练)

前置:完成 ch04 数组与 String;ch05 面向对象;ch06 接口与枚举。


8.1 集合框架概览

Java 集合位于 java.util 包,分为两大体系:

Collection(单列)
├── List   — 有序、可重复(ArrayList、LinkedList)
├── Set    — 不重复(HashSet、TreeSet)
└── Queue  — 队列(LinkedList、PriorityQueue)

Map(双列,键值对)
└── HashMap、TreeMap、LinkedHashMap
接口典型实现特点
ListArrayList随机访问快,尾部增删快
SetHashSet基于哈希,无序、不重复
MapHashMap键唯一,查找 O(1) 平均

工程原则:默认选 ArrayListHashMap;需要排序时用 TreeSet / TreeMapCollections.sort()


8.2 ArrayList 基础

ArrayList 底层是动态数组,适合读多写少、按索引访问的场景。

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

public class ListDemo {
    public static void main(String[] args) {
        List<String> books = new ArrayList<>();
        books.add("Java 基础");
        books.add("Web 开发");
        books.add("数据分析");
        books.add("Web 开发");  // List 允许重复

        System.out.println(books.size());       // 4
        System.out.println(books.get(0));       // Java 基础
        System.out.println(books.contains("Web 开发"));  // true

        books.remove(1);
        books.set(0, "Java 进阶");

        for (int i = 0; i < books.size(); i++) {
            System.out.println(i + ": " + books.get(i));
        }
    }
}
方法说明
add(e) / add(i, e)追加或插入
get(i)按索引取值
remove(i) / remove(o)按索引或对象删除
size()元素个数
isEmpty()是否为空
clear()清空

泛型List<String> 编译期检查类型,避免 (String) list.get(0) 强转。


8.3 HashSet 去重

HashSet 基于 HashMap 实现,元素不重复,不保证顺序。

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

public class SetDemo {
    public static void main(String[] args) {
        Set<String> tags = new HashSet<>();
        tags.add("热销");
        tags.add("新品");
        tags.add("热销");   // 重复元素被忽略
        tags.add("限时");

        System.out.println(tags.size());  // 3

        for (String tag : tags) {
            System.out.println(tag);
        }

        if (tags.contains("新品")) {
            tags.remove("新品");
        }
    }
}
场景是否用 Set
用户访问过的 URL 去重HashSet
需要按插入顺序去重LinkedHashSet
需要排序的去重TreeSet
需要按下标访问❌ 用 List

注意:自定义类放入 HashSet 需正确实现 equals()hashCode()(ch05 §5.6 已学,两者必须成对重写)。


8.4 HashMap 键值映射

HashMap 是最常用的 Map 实现,键唯一,允许一个 null 键。

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

public class MapDemo {
    public static void main(String[] args) {
        Map<String, Integer> stock = new HashMap<>();
        stock.put("BK-001", 120);
        stock.put("BK-002", 45);
        stock.put("BK-003", 89);

        System.out.println(stock.get("BK-001"));     // 120
        System.out.println(stock.getOrDefault("BK-999", 0));  // 0

        stock.put("BK-002", 50);  // 覆盖旧值

        for (Map.Entry<String, Integer> entry : stock.entrySet()) {
            System.out.println(entry.getKey() + " => " + entry.getValue());
        }

        for (String sku : stock.keySet()) {
            System.out.println(sku);
        }
    }
}
方法说明
put(k, v)插入或更新
get(k)取值,无键返回 null
getOrDefault(k, default)安全取值
containsKey(k)是否包含键
entrySet()键值对集合,便于遍历

toolkit-demo 场景:用 Map<String, Integer> 统计日志中各路径出现次数。


8.5 遍历方式对比

List<String> items = new ArrayList<>();
items.add("A");
items.add("B");
items.add("C");

// 1. for-each(推荐)
for (String s : items) {
    System.out.println(s);
}

// 2. 索引 for(需要下标时)
for (int i = 0; i < items.size(); i++) {
    System.out.println(items.get(i));
}

// 3. Iterator(遍历时安全删除)
import java.util.Iterator;

Iterator<String> it = items.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("B")) {
        it.remove();  // 不能用 items.remove(s) 在 for-each 中
    }
}
方式适用
for-each只读遍历
Iterator遍历时删除元素
索引 for需要位置信息

8.6 Iterator 详解

Iterator 是集合的统一遍历接口:

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

public class IteratorDemo {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);

        Iterator<Integer> it = nums.iterator();
        while (it.hasNext()) {
            int n = it.next();
            if (n % 2 == 0) {
                it.remove();
            }
        }
        System.out.println(nums);  // [1, 3]
    }
}
方法说明
hasNext()是否还有下一个
next()取下一个并前进
remove()删除当前元素(只能调用一次 next 后)

ListIterator(List 专用)还支持 previous() 与双向遍历,选修了解即可。


8.7 Comparable 自然排序

以下内容需解锁后阅读

试读已结束。解锁本章 ¥5.00,或开通年度会员畅读全部教程。
年度会员 ¥199.00/年; 小紫 AI 工作台有效会员 ¥99.00/年

正文仅在服务端鉴权后下发,未付费无法获取下半部分内容。