集合操作常用写法
集合操作是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工具包使用
下一章节:字符串处理常用写法
返回目录:代码规范