Adding two lists of own type

  • A+
Category:Languages

I have a simple User class with a String and an int property.

I would like to add two Lists of users this way:

  • if the String equals then the numbers should be added and that would be the its new value.
  • The new list should include all users with the proper values.

Like this:

List1: { [a:2], [b:3] } List2: { [b:4], [c:5] } ResultList: {[a:2], [b:7], [c:5]} 

User definition:

public class User {      private String name;     private int comments; } 

my method:

public List<User> addTwoList(List<User> first, List<User> sec) {     List<User> result = new ArrayList<>();     for (int i=0; i<first.size(); i++) {         Boolean bsin = false;         Boolean isin = false;         for (int j=0; j<sec.size(); j++) {             isin = false;              if (first.get(i).getName().equals(sec.get(j).getName())) {                 int value= first.get(i).getComments() + sec.get(j).getComments();                 result.add(new User(first.get(i).getName(), value));                 isin = true;                 bsin = true;             }             if (!isin) {result.add(sec.get(j));}         }         if (!bsin) {result.add(first.get(i));}     }     return result;       } 

But it adds a whole lot of things to the list.

 


This is better done via the toMap collector:

 Collection<User> result = Stream     .concat(first.stream(), second.stream())     .collect(Collectors.toMap(         User::getName,         u -> new User(u.getName(), u.getComments()),         (l, r) -> {             l.setComments(l.getComments() + r.getComments());             return l;         }))     .values(); 
  • First, concatenate both the lists into a single Stream<User> via Stream.concat.
  • Second, we use the toMap collector to merge users that happen to have the same Name and get back a result of Collection<User>.

if you strictly want a List<User> then pass the result into the ArrayList constructor i.e. List<User> resultSet = new ArrayList<>(result);


Kudos to @davidxxx, you could collect to a list directly from the pipeline and avoid an intermediate variable creation with:

List<User> result = Stream     .concat(first.stream(), second.stream())     .collect(Collectors.toMap(          User::getName,          u -> new User(u.getName(), u.getComments()),          (l, r) -> {               l.setComments(l.getComments() + r.getComments());               return l;          }))     .values()     .stream()     .collect(Collectors.toList()); 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: