本文目录导读:

我来通过几个实际案例,手把手教你Java集合合并的操作。
基础集合合并案例
案例1:两个List合并(去重)
import java.util.*;
import java.util.stream.Collectors;
public class ListMergeExample {
public static void main(String[] args) {
// 准备数据
List<String> list1 = Arrays.asList("Java", "Python", "C++", "Java");
List<String> list2 = Arrays.asList("Python", "Go", "Rust", "JavaScript");
// 方法1:使用HashSet去重合并
Set<String> mergedSet = new HashSet<>(list1);
mergedSet.addAll(list2);
List<String> mergedList = new ArrayList<>(mergedSet);
System.out.println("方法1 - HashSet合并: " + mergedList);
// 方法2:使用Stream API
List<String> streamMerged = Stream.concat(list1.stream(), list2.stream())
.distinct()
.collect(Collectors.toList());
System.out.println("方法2 - Stream合并: " + streamMerged);
}
}
案例2:两个Map合并
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MapMergeExample {
public static void main(String[] args) {
Map<String, Integer> map1 = new HashMap<>();
map1.put("A", 10);
map1.put("B", 20);
map1.put("C", 30);
Map<String, Integer> map2 = new HashMap<>();
map2.put("B", 25); // 相同key
map2.put("D", 40);
map2.put("E", 50);
// 方法1:使用putAll(简单覆盖)
Map<String, Integer> merged1 = new HashMap<>(map1);
merged1.putAll(map2);
System.out.println("简单覆盖合并: " + merged1);
// 方法2:使用merge(自定义合并逻辑)
Map<String, Integer> merged2 = new HashMap<>(map1);
map2.forEach((key, value) ->
merged2.merge(key, value, Integer::sum) // 相同key时值相加
);
System.out.println("值相加合并: " + merged2);
// 方法3:使用Stream
Map<String, Integer> merged3 = Stream.concat(
map1.entrySet().stream(),
map2.entrySet().stream()
)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v1 + v2 // 冲突时相加
));
System.out.println("Stream合并: " + merged3);
}
}
实际业务场景案例
案例3:用户信息合并
import java.util.*;
import java.util.stream.Collectors;
class User {
private Long id;
private String name;
private String email;
private String phone;
public User(Long id, String name, String email, String phone) {
this.id = id;
this.name = name;
this.email = email;
this.phone = phone;
}
// getters and setters
public Long getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
public String getPhone() { return phone; }
public void setName(String name) { this.name = name; }
public void setEmail(String email) { this.email = email; }
public void setPhone(String phone) { this.phone = phone; }
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "', email='" + email + "', phone='" + phone + "'}";
}
}
public class UserMergeExample {
public static void main(String[] args) {
// 模拟从不同数据源获取的用户信息
List<User> usersFromDB = Arrays.asList(
new User(1L, "张三", "zhangsan@email.com", null),
new User(2L, "李四", null, "13800138000"),
new User(3L, "王五", "wangwu@email.com", "13900139000")
);
List<User> usersFromCache = Arrays.asList(
new User(1L, null, null, "13600136000"), // 补充电话
new User(2L, null, "lisi@email.com", null), // 补充邮箱
new User(4L, "赵六", "zhaoliu@email.com", "13700137000") // 新用户
);
// 合并用户信息(以DB数据为主,补充缓存数据)
Map<Long, User> userMap = usersFromDB.stream()
.collect(Collectors.toMap(User::getId, user -> user));
for (User cacheUser : usersFromCache) {
Long userId = cacheUser.getId();
if (userMap.containsKey(userId)) {
// 已存在用户,补充信息
User existingUser = userMap.get(userId);
if (existingUser.getName() == null && cacheUser.getName() != null) {
existingUser.setName(cacheUser.getName());
}
if (existingUser.getEmail() == null && cacheUser.getEmail() != null) {
existingUser.setEmail(cacheUser.getEmail());
}
if (existingUser.getPhone() == null && cacheUser.getPhone() != null) {
existingUser.setPhone(cacheUser.getPhone());
}
} else {
// 新用户,直接添加
userMap.put(userId, cacheUser);
}
}
System.out.println("合并后的用户信息:");
userMap.values().forEach(System.out::println);
}
}
案例4:订单数据合并统计分析
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
class Order {
private Long orderId;
private LocalDate date;
private Double amount;
private String category;
public Order(Long orderId, LocalDate date, Double amount, String category) {
this.orderId = orderId;
this.date = date;
this.amount = amount;
this.category = category;
}
public Long getOrderId() { return orderId; }
public LocalDate getDate() { return date; }
public Double getAmount() { return amount; }
public String getCategory() { return category; }
}
public class OrderMergeExample {
public static void main(String[] args) {
// 分页查询的订单数据
List<Order> page1 = Arrays.asList(
new Order(1L, LocalDate.now(), 100.0, "电子产品"),
new Order(2L, LocalDate.now(), 200.0, "图书"),
new Order(3L, LocalDate.now().minusDays(1), 150.0, "电子产品")
);
List<Order> page2 = Arrays.asList(
new Order(4L, LocalDate.now().minusDays(1), 300.0, "服装"),
new Order(5L, LocalDate.now().minusDays(2), 250.0, "图书"),
new Order(6L, LocalDate.now().minusDays(2), 180.0, "电子产品")
);
// 合并所有订单
List<Order> allOrders = new ArrayList<>();
allOrders.addAll(page1);
allOrders.addAll(page2);
// 按类别统计总销售额
Map<String, Double> salesByCategory = allOrders.stream()
.collect(Collectors.groupingBy(
Order::getCategory,
Collectors.summingDouble(Order::getAmount)
));
System.out.println("按类别销售统计:");
salesByCategory.forEach((category, total) ->
System.out.println(category + ": " + total + "元")
);
// 按日期统计销售额
Map<LocalDate, Double> salesByDate = allOrders.stream()
.collect(Collectors.groupingBy(
Order::getDate,
Collectors.summingDouble(Order::getAmount)
));
System.out.println("\n按日期销售统计:");
salesByDate.forEach((date, total) ->
System.out.println(date + ": " + total + "元")
);
}
}
高级合并技巧
案例5:高效合并大量数据
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class LargeDataMergeExample {
// 批量合并优化
public static <T> List<T> batchMerge(List<List<T>> batches) {
if (batches == null || batches.isEmpty()) {
return Collections.emptyList();
}
// 计算总大小预分配容量
int totalSize = batches.stream().mapToInt(List::size).sum();
List<T> result = new ArrayList<>(totalSize);
// 批量添加
for (List<T> batch : batches) {
result.addAll(batch);
}
return result;
}
// 并行合并(大数据量时使用)
public static Map<Long, String> parallelMerge(Map<Long, String> map1, Map<Long, String> map2) {
Map<Long, String> result = new ConcurrentHashMap<>(map1);
map2.entrySet().parallelStream().forEach(entry ->
result.merge(entry.getKey(), entry.getValue(), (v1, v2) -> v1 + " | " + v2)
);
return result;
}
public static void main(String[] args) {
// 模拟多批数据
List<List<String>> batches = new ArrayList<>();
batches.add(Arrays.asList("A", "B", "C"));
batches.add(Arrays.asList("D", "E", "F"));
batches.add(Arrays.asList("G", "H", "I"));
// 批量合并
List<String> merged = batchMerge(batches);
System.out.println("批量合并结果: " + merged);
// 并行合并Map
Map<Long, String> map1 = new HashMap<>();
map1.put(1L, "张三");
map1.put(2L, "李四");
Map<Long, String> map2 = new HashMap<>();
map2.put(2L, "李四2");
map2.put(3L, "王五");
Map<Long, String> result = parallelMerge(map1, map2);
System.out.println("并行合并结果: " + result);
}
}
最佳实践建议
性能优化原则:
// 不好的做法
List<String> result = new ArrayList<>();
for (List<String> batch : batches) {
result.addAll(batch); // 多次扩容
}
// 好的做法
int totalSize = batches.stream().mapToInt(List::size).sum();
List<String> result = new ArrayList<>(totalSize); // 预分配容量
for (List<String> batch : batches) {
result.addAll(batch);
}
线程安全合并:
import java.util.concurrent.ConcurrentHashMap;
// 多线程环境下的安全合并
public class ThreadSafeMerge {
private ConcurrentHashMap<String, Integer> counter = new ConcurrentHashMap<>();
public void mergeData(Map<String, Integer> data) {
data.forEach((key, value) ->
counter.merge(key, value, Integer::sum)
);
}
}
这些案例覆盖了大多数常见的集合合并场景,根据实际业务需求选择合适的合并策略,注意性能优化和线程安全。