spring data - Java 8 JPA Repository Stream produce two (or more) results? -


i have java 8 stream being returned spring data jpa repository. don't think usecase unusual, there 2 (actually 3 in case), collections off of resulting stream collected.

set<long> ids = // initialized try (stream<somedatabaseentity> somedatabaseentitystream =               somedatabaseentityrepository.findsomedatabaseentitiesstream(ids)) {     set<long> thealphacomponentids = somedatabaseentitystream             .map(v -> v.getalphacomponentid())             .collect(collectors.toset());     // operations on 'thealphacomponentids' here } 

i need pull out 'beta' objects , work on too. think had repeat code, seems wrong:

try (stream<somedatabaseentity> somedatabaseentitystream =               somedatabaseentityrepository.findsomedatabaseentitiesstream(ids)) {     set<betacomponent> thebetacomponents = somedatabaseentitystream             .map(v -> v.getbetacomponent())             .collect(collectors.toset());     // operations on 'thebetacomponents' here } 

these 2 code blocks occur serially in processing. there clean way both sets processing stream once? note: not want kludgy solution makes wrapper class alpha's , beta's don't belong together.

you can refactor code putting common parts method , turning uncommon parts parameters. e.g.

public <t> set<t> getall(set<long> ids, function<somedatabaseentity, t> f) {     try(stream<somedatabaseentity> somedatabaseentitystream =           somedatabaseentityrepository.findsomedatabaseentitiesstream(ids)) {         return somedatabaseentitystream.map(f).collect(collectors.toset());     } } 

usable via

set<long> thealphacomponentids = getall(ids, v -> v.getalphacomponentid()); // operations on 'thealphacomponentids' here 

and

set<betacomponent> thebetacomponents = getall(ids, v -> v.getbetacomponent()); // operations on 'thebetacomponents' here 

note pulls “operations on … here” parts out of try block, thing, implies associated resources released earlier. requires betacomponent can processed independently of stream’s underlying resources (otherwise, shouldn’t collect set anyway). longs, know sure can processed independently.

of course, process result out of try block without moving common code method. whether original code bears duplication requires refactoring, debatable. actually, operation consists single statement within try block looks big due verbose identifiers. ask yourself, whether still deem refactoring necessary, if code looked like

set<long> alphaids, ids = // initialized try(stream<somedatabaseentity> s = repo.findsomedatabaseentitiesstream(ids)) {     alphaids = s.map(v -> v.getalphacomponentid()).collect(collectors.toset()); } // operations on 'thealphacomponentids' here 

well, different developers may come different conclusions…


if want reduce number of repository queries, can store result of query:

list<somedatabaseentity> entities; try(stream<somedatabaseentity> somedatabaseentitystream =       somedatabaseentityrepository.findsomedatabaseentitiesstream(ids)) {     entities=somedatabaseentitystream.collect(collectors.tolist()); } set<long> thealphacomponentids = entities.stream()   .map(v -> v.getalphacomponentid()).collect(collectors.toset()); // operations on 'thealphacomponentids' here set<betacomponent> thebetacomponents = entities.stream()   .map(v -> v.getbetacomponent()).collect(collectors.toset()); // operations on 'thebetacomponents' here 

Comments