Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8: Merging two Lists containing objects by key

I have two lists:

List<Server> servers1 = new ArrayList<>();
Server s1 = new Server("MyServer");
s1.setAttribute1("Attribute1");
servers1.add(s1);

List<Server> servers2 = new ArrayList<>();
Server s2 = new Server("MyServer");
s2.setAttribute2("Attribute2");
servers2.add(s2);

servers1 contains servers with a name and an attribute1 (but no attribute2).
servers2 contains servers with a name and an attribute2 (but no attribute1).

public class Server {
   private String name;
   private String attribute1;
   private String attribute2;

   public Server(String name) { 
       this.name = name;
       this.attribute1 = "";
       this.attribute2 = "";
   }

   //Getters & Setters

}

Does anyone know how I can merge these two lists to one list containing each Server only once (by name) but with both attributes?

There are servers which only exist in one or the other list. The final list should contain all servers.

    List<Server> servers1 = new ArrayList<>();
    Server s1 = new Server("MyServer");
    s1.setAttribute1("Attribute1");

    Server s2 = new Server("MyServer2");
    s2.setAttribute1("Attribute1.2");

    servers1.add(s1);
    servers1.add(s2);

    List<Server> servers2 = new ArrayList<>();
    Server s3 = new Server("MyServer");
    s3.setAttribute2("Attribute2");

    Server s4 = new Server("MyServer3");
    s4.setAttribute2("Attribute2.2");

    servers2.add(s3);
    servers2.add(s4);

should result in:

[Server [name=MyServer, attribute1=Attribute1, attribute2=Attribute2],

Server [name=MyServer2, attribute1=Attribute1.2, attribute2=]]

Server [name=MyServer3, attribute1=, attribute2=Attribute2.2]]

//SOLUTION (thx everybody for the help!)

Map<String, Server> serverMap1 = Stream.concat(servers1.stream(), servers2.stream())
            .collect(Collectors.toMap(Server::getName, Function.identity(), 
            (server1, server2) -> {
                server1.setAttribute2(server2.getAttribute2()); 
                return server1; 
            }));
like image 248
Nibor Avatar asked Jan 12 '17 12:01

Nibor


People also ask

How do you combine two lists of objects?

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 combine multiple objects into one in Java?

concat(first, second, Object. class); It can be used with different data types, and it accepts two source arrays along with the class literal to return the combined array.

Can you concatenate lists in Java?

Use addAll () method to concatenate the given list1 and list2 into the newly created list.


1 Answers

Convert each list to map and merge it (I use Lombok to not write boilerplate code):

@Data
@NoArgsConstructor
@AllArgsConstructor
class Server {
    private String name;
    private String attribute1;
    private String attribute2;
}

public class ServerMain {

    public static void main(String[] args) {

        List<Server> servers1 = Arrays.asList(
                new Server("name1", "attr1.1", null),
                new Server("name2", "attr1.2", null));

        List<Server> servers2 = Arrays.asList(
                new Server("name1", null, "attr2.1"),
                new Server("name2", null, "attr2.2"));

        Map<String, Server> serverMap1 = servers1.stream().collect(Collectors.toMap(Server::getName, Function.identity()));
        Map<String, Server> serverMap2 = servers2.stream().collect(Collectors.toMap(Server::getName, Function.identity()));

        serverMap1.keySet().forEach(key -> serverMap1.merge(key,
                serverMap2.get(key),
                (server1, server2) -> {
                    server1.setAttribute2(server2.getAttribute2());
                    return server1;
                }));


        System.out.println(serverMap1);
    }
}
like image 56
Dmitry Gorkovets Avatar answered Nov 11 '22 17:11

Dmitry Gorkovets