这里先给大家推荐一篇实用的好文章:《从小改动到系统崩溃:一场“蝴蝶效应”般的Debug惊魂记!》 来自作者:bug菌
这篇文章作者详细解在读程序员的日常工作,难免要对现有代码做些“看似简单”的小改动。然而,你是否经历过这样一场灾难:一个不起眼的改动,却引发了整个系统的连锁反应,最终导致全面崩溃?这是一次“蝴蝶效应”的真实案例。
今天我要和大家分享的,是我亲历的一次小改动导致大崩溃的故事。这个故事包含了从慌乱到冷静、从无头绪到找到问题的全过程,以及其中的教训和启发。相信你读完后,不仅会会心一笑,还能从中获得一些Debug的实战经验。
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
在上期文章中,我们讨论了如何在 Java 中遍历树形结构,包括深度优先搜索 (DFS) 和广度优先搜索 (BFS) 的实现。这些遍历方式在数据结构中起着关键作用,帮助我们理解和处理复杂的层级数据。延续上期内容,树形结构中通常会涉及多个节点及其子节点的信息,而这些数据往往存储在多个对象的 List 中。在实际开发中,我们常常遇到需要将多个对象的 List 数据进行合并的场景,比如合并多个用户列表、商品列表等。
在本文中,我们将重点讲解 Java 怎么把多个对象的 List 数据合并,并探讨合并过程中的不同实现方式、优缺点,以及实际应用场景。
本文主要讨论如何在 Java 中高效合并多个对象的 List 数据。首先,我们会简要介绍 List 在 Java 中的使用,然后解析不同的 List 合并方法,并展示相应的代码实现。随后,通过具体案例展示合并操作的实际应用场景,最后对各方法的优缺点进行分析,并提供核心方法和测试用例帮助读者理解。
List 是 Java 集合框架中的重要接口,继承自 Collection,表示有序的元素集合,允许存储重复元素。Java 中常用的 List 实现类有:
ArrayList:基于动态数组实现,查询速度快,但在添加和删除大量数据时性能较差。LinkedList:基于链表实现,插入和删除操作高效,查询速度相对较慢。在日常开发中,List 常用于存储一组对象的数据,比如用户对象的列表、订单对象的列表等。
在实际开发中,常常需要将多个对象的 List 数据进行合并,例如:
通过合并 List,我们可以将分散的数据整合到一个统一的数据结构中,方便后续操作和处理。
addAll() 方法合并 List最直接的方法是使用 addAll() 方法,将一个 List 的所有元素添加到另一个 List 中。
import java.util.ArrayList;
import java.util.List;
public class ListMergeExample {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("Apple");
list1.add("Banana");
List<String> list2 = new ArrayList<>();
list2.add("Orange");
list2.add("Grapes");
// 使用 addAll() 合并两个 List
list1.addAll(list2);
// 输出合并后的 List
System.out.println("Merged List: " + list1);
}
}Merged List: [Apple, Banana, Orange, Grapes]分析:addAll() 方法会将第二个 List 中的所有元素添加到第一个 List 中,保留元素的顺序。该方法效率较高,适合用于两个或多个列表的合并。
Stream API 合并 ListJava 8 引入了 Stream API,使得合并 List 的操作更加简洁和易于扩展。通过 Stream.concat() 方法,我们可以轻松合并多个 List。
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ListMergeWithStream {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("Car");
list1.add("Bike");
List<String> list2 = new ArrayList<>();
list2.add("Bus");
list2.add("Train");
// 使用 Stream API 合并两个 List
List<String> mergedList = Stream.concat(list1.stream(), list2.stream())
.collect(Collectors.toList());
// 输出合并后的 List
System.out.println("Merged List using Stream: " + mergedList);
}
}Merged List using Stream: [Car, Bike, Bus, Train]分析:Stream.concat() 方法将两个流连接起来,再通过 collect(Collectors.toList()) 将流转换回 List。这种方法可以很方便地扩展为合并多个列表,且代码更加简洁。
Collections.addAll() 方法Collections.addAll() 是另一个简单合并 List 的方法。它允许我们将数组或多个元素快速添加到 List 中。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListMergeWithCollections {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("Dog");
list1.add("Cat");
List<String> list2 = new ArrayList<>();
list2.add("Rabbit");
list2.add("Hamster");
// 使用 Collections.addAll() 方法合并
Collections.addAll(list1, list2.toArray(new String[0]));
// 输出合并后的 List
System.out.println("Merged List using Collections: " + list1);
}
}Merged List using Collections: [Dog, Cat, Rabbit, Hamster]分析:Collections.addAll() 方法是对 addAll() 的进一步封装,它可以将一个数组或列表中的所有元素添加到另一个列表中。这种方式代码简洁,但相对不如 Stream 灵活。
有时,我们可能需要根据特定的业务逻辑合并 List,比如去重、合并时保留某些属性等。此时可以使用自定义逻辑进行合并。
import java.util.ArrayList;
import java.util.List;
class User {
String name;
int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + "}";
}
}
public class CustomListMergeExample {
public static void main(String[] args) {
List<User> list1 = new ArrayList<>();
list1.add(new User("Alice", 30));
list1.add(new User("Bob", 25));
List<User> list2 = new ArrayList<>();
list2.add(new User("Charlie", 22));
list2.add(new User("Alice", 30)); // 重复对象
List<User> mergedList = new ArrayList<>(list1);
// 自定义合并逻辑:避免重复添加
for (User user : list2) {
if (!mergedList.contains(user)) {
mergedList.add(user);
}
}
// 输出合并后的 List
System.out.println("Merged List with custom logic: " + mergedList);
}
}Merged List with custom logic: [User{name='Alice', age=30}, User{name='Bob', age=25}, User{name='Charlie', age=22}]分析:自定义逻辑通过遍历第二个 List,并检查目标 List 中是否已存在该对象,防止重复添加。这种方式适用于需要根据具体业务规则合并 List 的场景。
在电商平台中,订单可能来自不同的数据源,比如第三方支付平台、物流系统等。我们可以通过合并这些不同来源的订单列表,统一处理订单数据。
List<Order> orderListFromPayment = fetchOrdersFromPaymentSystem();
List<Order> orderListFromLogistics = fetchOrdersFromLogisticsSystem();
// 使用 Stream API 合并订单列表
List<Order> mergedOrders = Stream.concat(orderListFromPayment.stream(), orderListFromLogistics.stream())
.collect(Collectors.toList());在企业管理系统中,不同部门可能维护独立的用户列表。为了统一管理,我们需要将各部门的用户列表合并,并去除重复用户。
List<User> hrUserList = fetchUsersFromHR();
List<User> itUserList = fetchUsersFromIT();
// 使用自定义逻辑合并用户列表并去重
List<User> mergedUsers = new ArrayList<>(hrUserList);
for (User user : itUserList) {
if (!mergedUsers.contains(user)) {
mergedUsers.add(user);
}
}addAll() 和 Stream 的方式非常直观,适合合并一般的 List 数据。Stream API 不仅可以合并,还可以在合并过程中对数据进行操作,如过滤、映射等。addAll() 和 Stream 的性能都表现不错。addAll() 无法满足需求,需要自定义逻辑。addAll(Collection<? extends E> c):将指定集合中的所有元素添加到当前集合。Stream.concat(Stream<? extends T> a, Stream<? extends T> b):连接两个流,并生成一个包含所有元素的流。Collections.addAll(Collection<? super T> c, T... elements):将指定数组的所有元素添加到集合中。addAll() 方法@Test
public void testAddAll() {
List<String> list1 = Arrays.asList("A", "B");
List<String> list2 = Arrays.asList("C", "D");
list1.addAll(list2);
assertEquals(Arrays.asList("A", "B", "C", "D"), list1);
}代码解析:
如下是具体的代码解析,希望对大家有所帮助:
这段Java代码定义了一个名为 testAddAll 的测试方法,用于验证 List 接口的 addAll 方法是否能够正确地将一个列表中的所有元素添加到另一个列表的末尾。
下面是这段代码的详细解读:
@Test:这是一个JUnit注解,表示标记紧跟其后的方法为测试方法。public void testAddAll() { ... }:定义了一个名为 testAddAll 的测试方法。List<String> list1 = Arrays.asList("A", "B");:创建一个包含 "A" 和 "B" 的列表。List<String> list2 = Arrays.asList("C", "D");:创建一个包含 "C" 和 "D" 的列表。addAll 方法添加元素:list1.addAll(list2);:调用 list1 的 addAll 方法,将 list2 中的所有元素添加到 list1 的末尾。assertEquals(Arrays.asList("A", "B", "C", "D"), list1);:使用 assertEquals 断言方法验证 list1 是否包含所有预期的元素("A"、"B"、"C" 和 "D")。list1 和 list2,分别包含字符串 "A"、"B" 和 "C"、"D"。list1.addAll(list2) 方法将 list2 中的所有元素添加到 list1 的末尾。assertEquals 断言方法验证 list1 是否现在包含所有预期的元素。这个测试用例的目的是确保 List 接口的 addAll 方法能够正确地将一个列表中的元素添加到另一个列表的末尾。通过创建两个列表,使用 addAll 方法将第二个列表的元素添加到第一个列表,然后验证第一个列表的内容是否与预期相匹配,测试确认了 addAll 方法的功能。
注意:代码中使用了 Arrays.asList 方法创建列表,这是Java中一种常见的创建列表的方式。此外,测试方法的名称 testAddAll 表明它专注于测试 addAll 方法的功能。
Stream.concat() 方法@Test
public void testStreamConcat() {
List<String> list1 = Arrays.asList("X", "Y");
List<String> list2 = Arrays.asList("Z");
List<String> mergedList = Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList());
assertEquals(Arrays.asList("X", "Y", "Z"), mergedList);
}代码解析:
如下是具体的代码解析,希望对大家有所帮助:
这段Java代码定义了一个名为 testStreamConcat 的测试方法,用于验证使用Java 8的Stream API进行列表合并是否正确。
下面是这段代码的详细解读:
@Test:这是一个JUnit注解,表示标记紧跟其后的方法为测试方法。public void testStreamConcat() { ... }:定义了一个名为 testStreamConcat 的测试方法。List<String> list1 = Arrays.asList("X", "Y");:创建一个包含 "X" 和 "Y" 的列表。List<String> list2 = Arrays.asList("Z");:创建一个包含 "Z" 的列表。Stream.concat(list1.stream(), list2.stream()):调用 Stream.concat 方法,将 list1 和 list2 转换为流并连接它们。.collect(Collectors.toList()):使用 collect 方法和 Collectors.toList() 收集器将合并后的流收集到一个新的列表中。assertEquals(Arrays.asList("X", "Y", "Z"), mergedList);:使用 assertEquals 断言方法验证合并后的列表 mergedList 是否与预期的列表(包含 "X"、"Y" 和 "Z")相等。list1 和 list2,分别包含字符串 "X"、"Y" 和 "Z"。Stream.concat 方法将两个列表的流连接起来,创建一个新的流。collect 方法将合并后的流收集到一个新的列表 mergedList 中。assertEquals 断言方法验证 mergedList 是否包含所有预期的元素。这个测试用例的目的是确保使用Stream API的 Stream.concat 方法能够正确地合并两个列表。通过创建两个列表,将它们转换为流,合并流,然后收集结果到新列表,最后验证结果列表是否与预期相等,测试确认了Stream API的合并功能。
注意:代码中使用了 Arrays.asList 方法创建列表,这是Java中一种常见的创建列表的方式。此外,测试方法的名称 testStreamConcat 表明它专注于测试流合并功能。
本文详细介绍了如何在 Java 中合并多个对象的 List 数据,从最常用的 addAll() 方法到灵活的 Stream API,再到自定义的合并逻辑。通过多个实际应用案例,展示了合并 List 数据在不同场景中的应用。我们分析了各个方法的优缺点,帮助读者根据需求选择最合适的合并方式。
在 Java 开发中,合并多个对象的 List 数据是常见的操作,掌握不同的合并方法和实现逻辑,能够帮助开发者提高代码效率和可读性。无论是使用简单的 addAll(),还是灵活的 Stream,亦或是定制的合并逻辑,开发者都可以根据实际场景灵活运用。
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
... ...
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
***
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。