Java 的map集合体系

上一篇我们学习了 Collection 体系的核心接口与实现类,本文将继续深入,讲解集合的遍历方式、泛型的作用,以及另一大体系 ——Map 集合

一、集合的遍历方式

遍历集合是开发中高频操作,Java 提供了多种遍历方式,各有适用场景。

1. 普通 for 循环(仅 List 可用)

通过索引遍历,仅适用于实现了List接口的集合(如 ArrayList、LinkedList)。

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

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

2. 增强 for 循环(foreach)

语法简洁,适用于所有 Collection 集合,但无法在遍历中修改集合结构(如删除元素)。

Set<String> set = new HashSet<>();
set.add("Java");
set.add("Python");

for (String s : set) {
    System.out.println(s);
}

3. 迭代器(Iterator)

最通用的遍历方式,支持在遍历中安全修改集合(通过remove()方法)。

Collection<String> coll = new ArrayList<>();
coll.add("1");
coll.add("2");
coll.add("3");

Iterator<String> it = coll.iterator();
while (it.hasNext()) {
    String s = it.next();
    if ("2".equals(s)) {
        it.remove(); // 安全删除当前元素
    }
}
System.out.println(coll); // [1, 3]

4. 列表迭代器(ListIterator)

List接口特有的迭代器,支持向前 / 向后遍历修改元素插入元素

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

ListIterator<String> lit = list.listIterator(list.size()); // 从末尾开始
while (lit.hasPrevious()) {
    System.out.println(lit.previous()); // 输出:C、B、A
}

二、集合中的泛型 <E>

泛型是 Java 的重要特性,用于限制集合中元素的类型,避免运行时类型转换异常,提高代码安全性。

1. 泛型的作用

// 无泛型:需手动强转,且可能存不同类型元素
Collection coll = new ArrayList();
coll.add("Java");
coll.add(123); // 编译不报错,运行时无异常

String s = (String) coll.get(1); // 运行时异常:ClassCastException

// 有泛型:编译期检查类型,避免错误
Collection<String> coll2 = new ArrayList<>();
// coll2.add(123); // 编译报错,只能存String

2. 泛型通配符

  • <?>:无界通配符,匹配任意类型。
  • <? extends E>:上界通配符,匹配 E 或 E 的子类。
  • <? super E>:下界通配符,匹配 E 或 E 的父类。
public class GenericDemo {
    public static void printList(Collection<? extends Number> list) {
        for (Number n : list) {
            System.out.println(n);
        }
    }
    
    public static void main(String[] args) {
        List<Integer> intList = Arrays.asList(1, 2, 3);
        List<Double> doubleList = Arrays.asList(1.1, 2.2);
        printList(intList); // 允许,Integer是Number的子类
        printList(doubleList); // 允许,Double是Number的子类
    }
}

三、可变参数与工具类

JDK 提供了便捷的工具类,简化集合与数组的操作。

1. 可变参数

用于接收任意数量的同类型参数,语法为类型... 参数名

public class VarargsDemo {
    public static void printArgs(String... args) {
        for (String s : args) {
            System.out.println(s);
        }
    }
    
    public static void main(String[] args) {
        printArgs("A");
        printArgs("A", "B", "C");
    }
}

2. 数组工具类(Arrays)

提供数组的排序、查找、转集合等操作。

import java.util.Arrays;
import java.util.List;

public class ArraysDemo {
    public static void main(String[] args) {
        int[] arr = {3, 1, 2};
        Arrays.sort(arr); // 排序
        System.out.println(Arrays.toString(arr)); // [1, 2, 3]
        
        List<Integer> list = Arrays.asList(1, 2, 3); // 数组转List
    }
}

3. 集合工具类(Collections)

提供集合的排序、查找、同步控制等操作。

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

public class CollectionsDemo {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(1);
        list.add(2);
        
        Collections.sort(list); // 排序
        System.out.println(list); // [1, 2, 3]
        
        Collections.reverse(list); // 反转
        System.out.println(list); // [3, 2, 1]
        
        // 线程安全的集合
        List<String> syncList = Collections.synchronizedList(new ArrayList<>());
    }
}

四、Map 集合体系:键值对的存储

Map接口用于存储键值对(Key-Value),键唯一,值可重复。常用实现类有HashMapTreeMapHashtableLinkedHashMap

1. HashMap:基于哈希表的 Map(推荐)

  • 底层结构:哈希表(数组 + 链表 / 红黑树),键无序、唯一,允许键为null(仅一个)。
  • 性能:查询、增删效率高(时间复杂度 O (1))。
public class HashMapDemo {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("Java", 100);
        map.put("Python", 90);
        map.put("Java", 95); // 覆盖原value
        
        System.out.println(map.get("Java")); // 95
        System.out.println(map.containsKey("Python")); // true
        
        // 遍历方式1:遍历键
        for (String key : map.keySet()) {
            System.out.println(key + ":" + map.get(key));
        }
        
        // 遍历方式2:遍历键值对
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }
}

2. TreeMap:可排序的 Map

  • 底层结构:红黑树,键可排序(自然排序或自定义比较器)、唯一
  • 适用场景:需要按键排序的场景。
public class TreeMapDemo {
    public static void main(String[] args) {
        // 自然排序(String实现了Comparable)
        Map<String, Integer> map = new TreeMap<>();
        map.put("C", 3);
        map.put("A", 1);
        map.put("B", 2);
        
        System.out.println(map); // {A=1, B=2, C=3}(按键排序)
    }
}

3. Hashtable:线程安全的 Map(已过时)

  • 特点:方法加了synchronized锁,线程安全但性能低,不允许键或值为 null
  • 替代方案:优先用HashMap,多线程场景用ConcurrentHashMap

4. LinkedHashMap:有序的 HashMap

  • 底层结构:哈希表 + 链表,键有序(插入顺序或访问顺序)、唯一
  • 适用场景:需要保证键的插入顺序或访问顺序的场景。
public class LinkedHashMapDemo {
    public static void main(String[] args) {
        Map<String, Integer> map = new LinkedHashMap<>();
        map.put("A", 1);
        map.put("B", 2);
        map.put("C", 3);
        
        System.out.println(map); // {A=1, B=2, C=3}(保持插入顺序)
    }
}

总结

集合框架是 Java 开发的必备技能,掌握后能大幅提升数据处理效率:

  • 遍历选择:需修改集合用Iterator,否则用增强 for 或普通 for(List)。
  • 泛型使用:始终为集合指定泛型,避免类型转换异常。
  • Map 选择:选HashMap(性能优)、LinkedHashMap(需顺序)或TreeMap(需排序)。

至此,Java 集合体系的核心知识点已全部讲解完毕。建议结合实际场景多练习,才能真正做到融会贯通!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值