Skip to content

集合操作常用写法 ​

集合操作是Java开发中最常用的操作之一。本文详细介绍List、Map、Set的常用写法和最佳实践,包含大量实用示例。

📋 目录 ​

🎯 一、List操作 ​

1.1 List创建和初始化 ​

创建List:

java
// 传统方式
List<String> list1 = new ArrayList<>();
List<String> list2 = new LinkedList<>();
List<String> list3 = new Vector<>();

// Arrays.asList(固定大小)
List<String> list4 = Arrays.asList("a", "b", "c");

// Collections方式
List<String> list5 = Collections.emptyList();
List<String> list6 = Collections.singletonList("a");

// Java 9+方式
List<String> list7 = List.of("a", "b", "c");
List<Integer> list8 = List.of(1, 2, 3);

// 使用Stream
List<String> list9 = Stream.of("a", "b", "c").collect(Collectors.toList());

初始化List:

java
// 初始化空List
List<String> list = new ArrayList<>();

// 初始化带初始容量
List<String> list2 = new ArrayList<>(100);

// 初始化并添加元素
List<String> list3 = new ArrayList<String>() {{
    add("a");
    add("b");
    add("c");
}};

// 使用Collections初始化
List<String> list4 = new ArrayList<>(Collections.nCopies(10, "default"));

1.2 List添加和删除 ​

添加元素:

java
List<String> list = new ArrayList<>();

// 添加单个元素
list.add("a");
list.add("b");

// 添加元素到指定位置
list.add(0, "first");

// 批量添加
list.addAll(Arrays.asList("c", "d", "e"));
list.addAll(1, Arrays.asList("x", "y"));

// 条件添加
if (!list.contains("z")) {
    list.add("z");
}

删除元素:

java
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e"));

// 根据索引删除
list.remove(0);  // 删除第一个元素

// 根据对象删除(删除第一个匹配的元素)
list.remove("b");

// 批量删除
list.removeAll(Arrays.asList("c", "d"));

// 条件删除(Java 8+)
list.removeIf(s -> s.length() > 1);

// 清空List
list.clear();

// 保留指定元素
list.retainAll(Arrays.asList("a", "b"));

1.3 List查找和遍历 ​

查找元素:

java
List<String> list = Arrays.asList("a", "b", "c", "d", "e");

// 查找索引
int index = list.indexOf("c");        // 2
int lastIndex = list.lastIndexOf("c"); // 2

// 判断包含
boolean contains = list.contains("a");        // true
boolean containsAll = list.containsAll(Arrays.asList("a", "b")); // true

// 查找元素(Java 8+)
Optional<String> found = list.stream()
    .filter(s -> s.startsWith("c"))
    .findFirst();

String result = list.stream()
    .filter(s -> s.length() > 1)
    .findFirst()
    .orElse("default");

遍历List:

java
List<String> list = Arrays.asList("a", "b", "c");

// 传统for循环
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

// 增强for循环
for (String item : list) {
    System.out.println(item);
}

// 迭代器
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

// Java 8 Lambda
list.forEach(item -> System.out.println(item));
list.forEach(System.out::println);

// Stream遍历
list.stream().forEach(System.out::println);

// 带索引遍历(Java 8+)
IntStream.range(0, list.size())
    .forEach(i -> System.out.println(i + ": " + list.get(i)));

1.4 List排序和分组 ​

排序操作:

java
List<String> list = new ArrayList<>(Arrays.asList("c", "a", "b", "d"));

// 自然排序
Collections.sort(list);
// 结果:[a, b, c, d]

// 自定义排序
Collections.sort(list, (a, b) -> b.compareTo(a));
// 结果:[d, c, b, a]

// 不改变原List的排序
List<String> sorted = list.stream()
    .sorted()
    .collect(Collectors.toList());

// 多条件排序
List<Person> persons = getPersons();
Collections.sort(persons, Comparator
    .comparing(Person::getAge)
    .thenComparing(Person::getName));

// Java 8+排序
list.sort(Comparator.naturalOrder());
list.sort(Comparator.reverseOrder());
list.sort(String::compareToIgnoreCase);

分组操作:

java
List<Person> persons = getPersons();

// 按年龄分组
Map<Integer, List<Person>> byAge = persons.stream()
    .collect(Collectors.groupingBy(Person::getAge));

// 按年龄分组并计数
Map<Integer, Long> countByAge = persons.stream()
    .collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));

// 多级分组
Map<String, Map<Integer, List<Person>>> byCityAndAge = persons.stream()
    .collect(Collectors.groupingBy(
        Person::getCity,
        Collectors.groupingBy(Person::getAge)
    ));

// 分组后转换
Map<Integer, List<String>> namesByAge = persons.stream()
    .collect(Collectors.groupingBy(
        Person::getAge,
        Collectors.mapping(Person::getName, Collectors.toList())
    ));

1.5 List转换和映射 ​

转换操作:

java
List<String> list = Arrays.asList("1", "2", "3", "4", "5");

// 转换为Integer
List<Integer> integers = list.stream()
    .map(Integer::parseInt)
    .collect(Collectors.toList());

// 转换为大写
List<String> upperCase = list.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());

// 转换为对象
List<Person> persons = names.stream()
    .map(name -> new Person(name))
    .collect(Collectors.toList());

// 扁平化转换
List<List<String>> nested = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d")
);
List<String> flattened = nested.stream()
    .flatMap(Collection::stream)
    .collect(Collectors.toList());
// 结果:[a, b, c, d]

1.6 List过滤和统计 ​

过滤操作:

java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 过滤偶数
List<Integer> evens = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());

// 过滤并去重
List<Integer> unique = numbers.stream()
    .filter(n -> n > 5)
    .distinct()
    .collect(Collectors.toList());

// 多重过滤
List<Person> filtered = persons.stream()
    .filter(p -> p.getAge() > 18)
    .filter(p -> p.getCity().equals("Beijing"))
    .collect(Collectors.toList());

统计操作:

java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// 求和
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
int sum2 = numbers.stream().reduce(0, Integer::sum);

// 求平均值
double avg = numbers.stream().mapToInt(Integer::intValue).average().orElse(0.0);

// 求最大值和最小值
int max = numbers.stream().mapToInt(Integer::intValue).max().orElse(0);
int min = numbers.stream().mapToInt(Integer::intValue).min().orElse(0);

// 计数
long count = numbers.stream().filter(n -> n > 3).count();

// 使用Collectors统计
IntSummaryStatistics stats = numbers.stream()
    .collect(Collectors.summarizingInt(Integer::intValue));
// stats包含:count, sum, min, max, average

🎯 二、Map操作 ​

2.1 Map创建和初始化 ​

创建Map:

java
// HashMap
Map<String, Integer> map1 = new HashMap<>();
Map<String, Integer> map2 = new HashMap<>(16, 0.75f);

// LinkedHashMap(保持插入顺序)
Map<String, Integer> map3 = new LinkedHashMap<>();

// TreeMap(按键排序)
Map<String, Integer> map4 = new TreeMap<>();
Map<String, Integer> map5 = new TreeMap<>(Comparator.reverseOrder());

// ConcurrentHashMap(线程安全)
Map<String, Integer> map6 = new ConcurrentHashMap<>();

// 初始化Map
Map<String, Integer> map7 = new HashMap<String, Integer>() {{
    put("a", 1);
    put("b", 2);
    put("c", 3);
}};

// Java 9+
Map<String, Integer> map8 = Map.of("a", 1, "b", 2, "c", 3);

// 使用Stream创建
Map<String, Integer> map9 = Stream.of(
    new AbstractMap.SimpleEntry<>("a", 1),
    new AbstractMap.SimpleEntry<>("b", 2)
).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

2.2 Map增删改查 ​

添加和修改:

java
Map<String, Integer> map = new HashMap<>();

// 添加元素
map.put("a", 1);
map.put("b", 2);

// 如果不存在才添加
map.putIfAbsent("a", 100);  // 不会覆盖,因为"a"已存在

// 批量添加
Map<String, Integer> other = new HashMap<>();
other.put("c", 3);
other.put("d", 4);
map.putAll(other);

// 更新值
map.replace("a", 10);
map.replace("a", 10, 20);  // 只有当值为10时才替换为20

// 计算新值
map.compute("a", (k, v) -> v == null ? 1 : v + 1);
map.computeIfAbsent("e", k -> 100);
map.computeIfPresent("a", (k, v) -> v * 2);

// 合并值
map.merge("a", 1, (oldValue, newValue) -> oldValue + newValue);

删除操作:

java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);

// 根据Key删除
map.remove("a");

// 根据Key和Value删除
map.remove("b", 2);  // 只有当Key="b"且Value=2时才删除

// 条件删除
map.entrySet().removeIf(entry -> entry.getValue() < 2);

// 清空Map
map.clear();

查询操作:

java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);

// 获取值
Integer value = map.get("a");              // 1
Integer value2 = map.getOrDefault("c", 0); // 0(不存在返回默认值)

// 判断包含
boolean hasKey = map.containsKey("a");     // true
boolean hasValue = map.containsValue(1);   // true

// 获取所有键
Set<String> keys = map.keySet();

// 获取所有值
Collection<Integer> values = map.values();

// 获取所有Entry
Set<Map.Entry<String, Integer>> entries = map.entrySet();

2.3 Map遍历 ​

遍历Map:

java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);

// 遍历Key
for (String key : map.keySet()) {
    System.out.println(key + " = " + map.get(key));
}

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

// 遍历Value
for (Integer value : map.values()) {
    System.out.println(value);
}

// Java 8 Lambda遍历
map.forEach((key, value) -> System.out.println(key + " = " + value));

// Stream遍历
map.entrySet().stream()
    .forEach(entry -> System.out.println(entry.getKey() + " = " + entry.getValue()));

// 过滤并遍历
map.entrySet().stream()
    .filter(entry -> entry.getValue() > 1)
    .forEach(System.out::println);

2.4 Map转换和过滤 ​

转换操作:

java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);

// 转换Key
Map<String, Integer> keyTransformed = map.entrySet().stream()
    .collect(Collectors.toMap(
        e -> e.getKey().toUpperCase(),
        Map.Entry::getValue
    ));

// 转换Value
Map<String, String> valueTransformed = map.entrySet().stream()
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        e -> String.valueOf(e.getValue())
    ));

// 过滤Map
Map<String, Integer> filtered = map.entrySet().stream()
    .filter(e -> e.getValue() > 1)
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue
    ));

2.5 Map合并和分组 ​

合并Map:

java
Map<String, Integer> map1 = new HashMap<>();
map1.put("a", 1);
map1.put("b", 2);

Map<String, Integer> map2 = new HashMap<>();
map2.put("b", 3);
map2.put("c", 4);

// 合并(相同Key的值相加)
Map<String, Integer> merged = Stream.concat(
    map1.entrySet().stream(),
    map2.entrySet().stream()
).collect(Collectors.toMap(
    Map.Entry::getKey,
    Map.Entry::getValue,
    Integer::sum
));
// 结果:{a=1, b=5, c=4}

// 使用merge合并
Map<String, Integer> result = new HashMap<>(map1);
map2.forEach((key, value) -> 
    result.merge(key, value, Integer::sum)
);

Map分组:

java
List<Person> persons = getPersons();

// 按年龄分组并转换为Map
Map<Integer, List<Person>> byAge = persons.stream()
    .collect(Collectors.groupingBy(Person::getAge));

// 分组并统计数量
Map<Integer, Long> countByAge = persons.stream()
    .collect(Collectors.groupingBy(
        Person::getAge,
        Collectors.counting()
    ));

// 分组并收集为Set
Map<Integer, Set<String>> namesByAge = persons.stream()
    .collect(Collectors.groupingBy(
        Person::getAge,
        Collectors.mapping(Person::getName, Collectors.toSet())
    ));

🎯 三、Set操作 ​

3.1 Set创建和操作 ​

创建Set:

java
// HashSet
Set<String> set1 = new HashSet<>();
Set<String> set2 = new HashSet<>(Arrays.asList("a", "b", "c"));

// LinkedHashSet(保持插入顺序)
Set<String> set3 = new LinkedHashSet<>();

// TreeSet(排序)
Set<String> set4 = new TreeSet<>();
Set<String> set5 = new TreeSet<>(Comparator.reverseOrder());

// Java 9+
Set<String> set6 = Set.of("a", "b", "c");

// 使用Stream
Set<String> set7 = Stream.of("a", "b", "c")
    .collect(Collectors.toSet());

Set运算:

java
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
Set<Integer> set2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8));

// 并集
Set<Integer> union = new HashSet<>(set1);
union.addAll(set2);
// 结果:[1, 2, 3, 4, 5, 6, 7, 8]

// 交集
Set<Integer> intersection = new HashSet<>(set1);
intersection.retainAll(set2);
// 结果:[4, 5]

// 差集
Set<Integer> difference = new HashSet<>(set1);
difference.removeAll(set2);
// 结果:[1, 2, 3]

// Java 8 Stream方式
Set<Integer> union2 = Stream.concat(set1.stream(), set2.stream())
    .collect(Collectors.toSet());

Set<Integer> intersection2 = set1.stream()
    .filter(set2::contains)
    .collect(Collectors.toSet());

3.2 Set转换和过滤 ​

转换和过滤:

java
Set<String> set = new HashSet<>(Arrays.asList("apple", "banana", "cherry"));

// 转换
Set<String> upperCase = set.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toSet());

// 过滤
Set<String> filtered = set.stream()
    .filter(s -> s.length() > 5)
    .collect(Collectors.toSet());

// 去重
List<String> list = Arrays.asList("a", "b", "a", "c", "b");
Set<String> unique = new HashSet<>(list);

🎯 四、集合转换 ​

4.1 集合类型转换 ​

类型转换:

java
// List转Set
List<String> list = Arrays.asList("a", "b", "c", "a");
Set<String> set = new HashSet<>(list);

// Set转List
Set<String> set2 = new HashSet<>(Arrays.asList("a", "b", "c"));
List<String> list2 = new ArrayList<>(set2);

// List转数组
List<String> list3 = Arrays.asList("a", "b", "c");
String[] array = list3.toArray(new String[0]);

// 数组转List
String[] array2 = {"a", "b", "c"};
List<String> list4 = Arrays.asList(array2);

// Map转List
Map<String, Integer> map = new HashMap<>();
List<String> keys = new ArrayList<>(map.keySet());
List<Integer> values = new ArrayList<>(map.values());
List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());

4.2 集合并行处理 ​

并行流:

java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 并行求和
int sum = numbers.parallelStream()
    .mapToInt(Integer::intValue)
    .sum();

// 并行过滤
List<Integer> evens = numbers.parallelStream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());

// 并行转换
List<String> strings = numbers.parallelStream()
    .map(String::valueOf)
    .collect(Collectors.toList());

📖 学习资源 ​

官方文档 ​

书籍推荐 ​

  • 《Java并发编程实战》 - Brian Goetz

✅ 学习检查清单 ​

  • [ ] 已掌握List的常用操作
  • [ ] 已掌握Map的常用操作
  • [ ] 已掌握Set的常用操作
  • [ ] 已熟悉集合转换方法
  • [ ] 已掌握Stream API的使用
  • [ ] 已了解并行处理

上一章节:Guava工具包使用
下一章节:字符串处理常用写法
返回目录:代码规范