Java 8 post grouping by -


i have list of objects of class job, every object has collection of tags (networks), collection mutable , has no impact on hashcode , objects equality.

what need list of unique job objects , each such object combine tags, example, have list:

[{position: "cto", dates: "2012-2014", city: "new york", networks: ["foo"]}, {position: "cto", dates: "2012-2014", city: "new york", networks: ["bar"]}]

this should reduced [{position: "cto", dates: "2012-2014", city: "new york", networks: ["foo", "bar"]}]

public class job {     private final string position;     private final string dates;     private final integer startyear;     private final integer endyear;     private final string city;     private set<networktype> networks;      public string getposition() {         return position;     }      public string getdates() {         return dates;     }      public string getcity() {         return city;     }      public set<networktype> getnetworks() {         return networks;     }      public void setnetworks(set<networktype> networks) {         this.networks = networks;     }      public integer getstartyear() {         return startyear;     }      public integer getendyear() {         return endyear;     }      @override     public boolean equals(object o) {         if (this == o) {             return true;         }         if (!(o instanceof job)) {             return false;         }         job job = (job) o;         return objects.equals(position, job.position) &&                 objects.equals(dates, job.dates) &&                 objects.equals(city, job.city);     }      @override     public int hashcode() {         return objects.hash(position, dates, city);     } } 

this actual job class code, , how implemented operation:

    map<job, list<job>> jobsmap = jobs.stream().collect(collectors.groupingby(job -> job));     jobsmap.keyset().stream()             .peek(job -> jobsmap.get(job).stream().foreach(j -> job.getnetworks().addall(j.getnetworks())))             .sorted(comparator.comparing((job o) -> objects.firstnonnull(o.getendyear(), integer.max_value))                     .reversed())             .collect(collectors.tolist()); 

but feel bad code, since using external map inside stream , wonder there way in 1 chain without intermediate transformations. appreciate valid criticism implementation of functionality. thank you!

assuming merge networks first occurrence of particular job find, can in 1 (rather complex) line:

import static java.util.stream.collectors.*; import static java.util.function.function.identity;  map<job, optional<job>> collect = jobs.stream()     .collect(groupingby(identity(), reducing((l, r) -> {         l.networks().addall(r.networks());         return l;     }))); 

i have used fluent accessors because cannot bothered type get

so. how work?

first stream jobs , call collectors.groupingby on function.identity(), gives map<job, list<job>>.

but don't want list<job> - collectors.reducing comes in. passed downstream collector of groupingby.

the downstream collector responsible creating value part of map - in case reduce found jobs 1 job.

reducing((l, r) -> {     l.networks().addall(r.networks());     return l; } 

so takes 2 job items, , returns one. it's fold operation, bifunction return value in turn each job. add networks() new job existing job.

obviously gives map<string, optional<job>>, collapsing simple job.

i cannot see way make list directly...


in order process map<job, optional<job>> list<job> following can used:

collect.values().stream()     .map(optional::get)     .collect(tolist); 

so, potentially whole lot in 1 line:

list<job> collect = jobs.stream()     .collect(groupingby(identity(), reducing((l, r) -> {         l.networks().addall(r.networks());         return l;     })))     .values().stream()     .map(optional::get)     .collect(tolist); 

although, readability of questionable.


Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -