Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging two List of objects in java 8

People also ask

How do you combine a List of objects in Java?

One way to merge multiple lists is by using addAll() method of java. util. Collection class, which allows you to add the content of one List into another List. By using the addAll() method you can add contents from as many List as you want, it's the best way to combine multiple List.

How do I merge two stream lists?

If you need to combine more than two Streams, you can invoke the concat() method again from within the original invocation: Stream<String> combinedStream = Stream. concat( Stream. concat(collectionA.

How do you append a List to another List in Java?

Insert All Elements From One List Into Another. It is possible to add all elements from one Java List into another List . You do so using the List addAll() method. The resulting List is the union of the two lists.


If you want to implement equals and hashCode, the place to do it is inside the class Parent. Within that class add the methods like

    @Override
    public int hashCode() {
        return Objects.hash(getAttrib1(), getAttrib2(), getAttrib3(),
            // …
                            getAttrib19(), getAttrib20());
    }

    @Override
    public boolean equals(Object obj) {
        if(this==obj) return true;
        if(!(obj instanceof Parent)) return false;
        Parent p=(Parent) obj;
        return Objects.equals(getAttrib1(), p.getAttrib1())
            && Objects.equals(getAttrib2(), p.getAttrib2())
            && Objects.equals(getAttrib3(), p.getAttrib3())
            // …
            && Objects.equals(getAttrib19(), p.getAttrib19())
            && Objects.equals(getAttrib20(), p.getAttrib20());
    }

If you did this, distinct() invoked on a Stream<Parent> will automatically do the right thing.


If you don’t want (or can’t) change the class Parent, there is no delegation mechanism for equality, but you may resort to ordering as that has a delegation mechanism:

Comparator<Parent> c=Comparator.comparing(Parent::getAttrib1)
        .thenComparing(Parent::getAttrib2)
        .thenComparing(Parent::getAttrib3)
        // …
        .thenComparing(Parent::getAttrib19)
        .thenComparing(Parent::getAttrib20);

This defines an order based on the properties. It requires that the types of the attributes itself are comparable. If you have such a definition, you can use it to implement the equivalent of a distinct(), based on that Comparator:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
        .filter(new TreeSet<>(c)::add)
        .collect(Collectors.toList());

There is also a thread-safe variant, in case you want to use it with parallel streams:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
        .filter(new ConcurrentSkipListSet<>(c)::add)
        .collect(Collectors.toList());

For example:

public class Parent {

    public int no;
    public String name;

    @Override
    public int hashCode() {
        return (no << 4) ^ name.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Parent))
            return false;
        Parent o = (Parent)obj;
        return this.no == o.no && this.name.equals(o.name);
    }
}

Override the equals and hashCode methods in Parent class to avoid duplicates from the lists. This will give you the exact result what you want.