How to efficiently merge two lists in Java?
Try this to create an immutable list containing all the elements, by performing a shallow copy. Beware that changes to the source lists will be reflected in the resulting list (so the immutability in reality depends on the immutability / access to the input lists).
public class MergedList<T> extends AbstractList<T> {
private final List<T>[] lists;
private final int size;
@SafeVarargs
MergedList(List<T>... lists) {
this.lists = lists.clone();
this.size = Arrays.stream(lists).mapToInt(list -> list.size()).sum();
}
@Override
public T get(int index) {
for (List<T> list : lists)
if (index < list.size())
return list.get(index);
else
index -= list.size();
throw new IndexOutOfBoundsException("index");
}
@Override
public int size() {
return size;
}
}
and
List<Integer> a = List.of(1, 2, 3, 4);
List<Integer> b = List.of(5, 6, 7);
List<Integer> c = new MergedList<>(a, b);
System.out.println(c);
output
[1, 2, 3, 4, 5, 6, 7]
Considering that the original list is updated, it might be better to remove the field size
and do this:
@Override
public int size() {
return Arrays.stream(lists).mapToInt(list -> list.size()).sum();
}
Combine multiple lists in Java
Java 8 has an easy way of doing it with the help of Stream API shown in the code below. We have basically created a stream with all the lists , and then as we need the individual contents of the lists, there is a need to flatten it with flatMap
and finally collect the elements in a List
.
List<Integer>list1=Arrays.asList(1,2,3);
List<Integer>list2=Arrays.asList(4,5,6);
List<Integer>list3=Arrays.asList(7,8,9);
List<Integer>list4=Arrays.asList(10,0,-1);
List<Integer> newList = Stream.of(list1, list2, list3,list4)
.flatMap(Collection::stream)
.collect(Collectors.toList());
System.out.println(newList); // prints [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, -1]
How can I Merge two Lists of custom objects of a Different Type using Java 8
In order to achieve that, firstly, you can create two maps based on the two lists using id
as a key.
Then create a stream over the key sets of these maps. Then inside the map()
operation you need to create a new Employee
object for every key by using passing a name
extracted from the employeeList
city
taken from the personById
.
When id
is not present in either of the maps the object returned by get()
will be null
and attempt to invoke method on it will triger the NullPointerException
. In order to handle this situation, we can make use of Null-object pattern, by defining two variables that could be safely accessed and will be provided as an argument to getOfDefault()
.
Then collect the stream element into a list with Collectors.toList()
.
public static void main(String[] args) {
List<Employee> employeeList = Stream.of(
new Employee("100","Alex",""),
new Employee("200","Rida",""),
new Employee("300","Ganga",""))
.collect(Collectors.toList());
List<Person> personList = Stream.of(
new Person("100","Atlanta"),
new Person("300","Boston"),
new Person("400","Pleasanton"))
.collect(Collectors.toList());
Map<String, Employee> employeeById = employeeList.stream()
.collect(Collectors.toMap(Employee::getId, Function.identity()));
Map<String, Person> personById = personList.stream()
.collect(Collectors.toMap(Person::getId, Function.identity()));
Person nullPerson = new Person("", null); // null-object
Employee nullEmployee = new Employee("", null, null); // null-object
List<Employee> result = Stream.concat(employeeById.keySet().stream(),
personById.keySet().stream())
.distinct() // eliminating duplicated keys
.map(key -> new Employee(key,
employeeById.getOrDefault(key, nullEmployee).getName(),
personById.getOrDefault(key, nullPerson).getCity()))
.collect(Collectors.toList());
result.forEach(System.out::println);
}
Output
Employee{id='100', name='Alex', city='Atlanta'}
Employee{id='200', name='Rida', city='null'}
Employee{id='300', name='Ganga', city='Boston'}
Employee{id='400', name='null', city='Pleasanton'}
How to join 2 lists in Java-8 such that element at same indexes from the 2 list come together in the resultant list
You can use IntStream
with indices of those lists:
IntStream.range(0, codeList.size())
.mapToObj(i -> codeList.get(i) + "{" + nameList.get(i) + "}")
.collect(Collectors.joining("|"));
Java 8: merging two Lists containing objects by Id
Collections to sort should work for this.
newList.addAll(oldList);
Collections.sort(newList, Comparator.comparing(Employee::getPersonalNumber) );
The key is that, "This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort."
Since cannot sort the new list, I take that to mean you don't know the order of the new list. You can do it the ol' N^2 method.
for(int i = 0; i<newList.size(); i+=2){
String newNum = newList.get(i).getPersonalNumber();
Employee old = oldList.stream().filter(
emp->newNum.equals(
emp.getPersonalNumber()
)
).findFirst().orElse(null);
newList.add(i+1, old);
oldList.remove(old); //not nescessary?
}
Combining two lists of different object types and sorting the combined list
Change List<Object>
to List<CustomInterface>
in
List<Object> x= new ArrayList<>();
provided that both your A
and B
classes implements CustomInterface
public List<CustomInterface> sortedAndMergedData(List<A> a, List<B> b) {
List<CustomInterface> x= new ArrayList<>();
x.addAll(a);
x.addAll(b);
Collections.sort(x, new CustomComprator());
return x;
}
Related Topics
Custom Method for Update Query With Spring Data Mongorepository
Encode Base64 Cannot Find Symbol Error
How to Reload Properties With Spring
Resource Leak: 'In' Is Never Closed
How to Instantiate a Class by Name in Java
Is There a Concurrent List in Java's Jdk
Difference Between Regex [A-Z] and [A-Za-Z]
Swing Grouplayout: Resizing and Limiting Component Sizes
It Is a Bad Practice to Use Sun's Proprietary Java Classes
What's the Difference Between Fx:Id and Id: in Javafx
Using Prepared Statements to Set Table Name
Jtable Not Showing Up on Jframe (Java)
Jsp Tricks to Make Templating Easier
How to Initialise a Static Map
How to Use Optional Parameters in Java