Sharing 6 options to join lists in Java
Introduction
- Joining two or more lists is a very common operation while developing in java. There are many use cases where we need to join lists.
- For example, let’s say we need to show a list of the latest logs along with some historical logs that span up to 1-month.
- The latest messages are pushed to Kafka while historical messages reside in the database.
- Now in order to return a complete list of messages we might have to merge/join the two lists, one with the latest data and the other with historical, and then return back to the front end.
- In this article, we will discuss various options to join two lists in Java.
Option 1
- Option 1 is a more mechanical way of joining two lists. In this approach, we create a result list that will store the final joined result.
- Then we traverse each list until the size of the minimum of the two lists so that we can cover both lists for the minimum size of iteration.
- Once we finish that loop, we traverse for the remaining elements of the list which is larger in size.
- Ideally, we should avoid this approach until if its an interview, in the real world we always have a helper method that can do this job with minimum code.
public static List<Integer> joinList(List<Integer> list1, List<Integer> list2){
List<Integer> mergedList = new ArrayList<>();
int i;
for(i=0;i<Math.min(list1.size(), list2.size());i++){
mergedList.add(list1.get(i));
mergedList.add(list2.get(i));
}
if(list1.size() > list2.size()){
for(int j=i;j<list1.size();j++){
mergedList.add(list1.get(j));
}
}else {
for(int j=i;j<list2.size();j++){
mergedList.add(list2.get(j));
}
}
return mergedList;
}
- If list1 is mutable, then we can iterate over the 2nd list and add the 2nd list to the first one.
Option 2
- In this option, we use the addAll() method provided by the list. Basically, we can pass the entire list to another list.
- Here we have created a result list and added list1 first and then list2 later and returned the merged list.
public static List<Integer> joinList(List<Integer> list1, List<Integer> list2){
List<Integer> mergedList = new ArrayList<>();
mergedList.addAll(list1);
mergedList.addAll(list2);
return mergedList;
}
Option 3
- This option uses the same helper method mentioned above in option 2.
We can initialize the result list directly with list1 and then add the remaining values from list2 with addAll() method.
public static List<Integer> joinList(List<Integer> list1, List<Integer> list2){
List<Integer> mergedList = new ArrayList<>(list1);
mergedList.addAll(list2);
return mergedList;
}
- If list1 or list2 is mutable then we can also use list1.addAll(list2) or list2.addAll(list1) without the need of creating a redundant mergedlist.
Option 4
- In this option, we can use List.of introduce in JDK 9 which takes one or more lists as arguments and creates List<List<Integer>> .
- Once we have a nested list, we can stream it and perform flatmap to flatten it and convert it to List<Integer>.
public static List<Integer> joinList(List<Integer> list1, List<Integer> list2) {
return List.of(list1, list2)
.stream()
.flatMap(List::stream)
.toList();
}
- We can reduce one step by using Stream.of on multiple lists and then flatten it.
public static List<Integer> joinList(List<Integer> list1, List<Integer> list2) {
return Stream.of(list1, list2).flatMap(List::stream).toList();
}
Option 5
- We can use Stream.concat method and pass stream from a list and convert it to List.
public static List<Integer> joinList(List<Integer> list1, List<Integer> list2){
return Stream.concat(list1.stream(), list2.stream())
.collect(Collectors.toList());
}
- We can make the above code shorten by using the toList method on the stream.
public static List<Integer> joinList(List<Integer> list1, List<Integer> list2){
return Stream.concat(list1.stream(), list2.stream())
.toList()
}
Option 6
- Now we can create a much more flexible method, where we can pass n number of lists and we can join them.
- Here we are receiving n number of lists as var args and by using Arrays.stream() we can create a nested stream and then perform flatmap to create unnested streams of elements and then finally using toList() we can get joinedList as a result.
public static List<Integer> joinList(List<Integer>... lists){
return Arrays.stream(lists)
.flatMap(List::stream).toList();
}
Conclusion
- In this article, we discuss various options to join the list in java. Collection and Stream API provides different helper methods to perform these joins.
- One thing to keep in mind here is that toList() and .collect(Collectors.toList()) returns an immutable list.
- So if you need a mutable list then we have to create a List using new ArrayList(joinedList).
Before You Leave
- Let me know if I can be of any help to your career, I would love to chat or jump on a call. you can connect me over Linkedin.
- If you like this content consider supporting.
- If you want to upskill your Java skills, you should definitely check out
Java Programming Masterclass updated to Java 17
[ 750,000 students already enrolled, with 4.5 stars]