lambda - Java 8 streams reduce and combine List items to Map -


i need create map keys of name1/2 summing values value1/2.

what cleanest way rewrite using java 8 streams?

class item {      private string name1;     private integer value1;     private string name2;     private integer value2;      public item(final string name1, final integer value1, final string name2, final integer value2) {         this.name1 = name1;         this.value1 = value1;         this.name2 = name2;         this.value2 = value2;     }     //getters , setters } 
list<item> list = lists.newarraylist(                 new item("aaa", 1, "bbb", 2),                 new item("bbb", 5, "ccc", 3),                 new item("aaa", 8, "bbb", 7),                 new item("bbb", 2, "aaa", 5));  map<string, integer> map = maps.newhashmap();  (item item : list) {     map.merge(item.name1, item.value1, integer::sum);     map.merge(item.name2, item.value2, integer::sum); }  system.out.println(map);//{aaa=14, ccc=3, bbb=16} 

a possible solution flat map each item stream made 2 entries: each entry composed of name , corresponding value. then, collected map summing values of values having same key. since there no built-in pair hold both values, can use abstractmap.simpleentry.

map<string, integer> map =     list.stream()         .flatmap(i -> stream.of(new abstractmap.simpleentry<>(i.name1, i.value1), new abstractmap.simpleentry<>(i.name2, i.value2)))         .collect(collectors.tomap(map.entry::getkey, map.entry::getvalue, integer::sum)); 

alternatively, might simpler use custom collect call. accumulator merges each key, have in for loop body. tricky part combiner, in case merges 2 maps iterating on entries of second map , merging them first one.

map<string, integer> map =         list.stream()             .collect(                 hashmap::new,                 (m, i) -> {                     m.merge(i.name1, i.value1, integer::sum);                     m.merge(i.name2, i.value2, integer::sum);                 },                 (m1, m2) -> m2.foreach((k, v) -> m1.merge(k, v, integer::sum))             ); 

Comments

Popular posts from this blog

javascript - How to get current YouTube IDs via iMacros? -

c# - Maintaining a program folder in program files out of date? -

emulation - Android map show my location didn't work -