considering following function:
public void execute4() { file filepath = new file(filepathdata); file[] files = filepath.listfiles((file filepathdata) -> filepathdata.getname().endswith("cdr")); list<cdr> cdrs = new arraylist<cdr>(); arrays.aslist(files).parallelstream().foreach(file -> readcdrp(cdrs, file)); cdrs.sort(cdrsorter); }
which reads list of files containing cdr , executes readcdrp() this:
private void readcdrp(list<cdr> cdrs, file file) { final cdr cdr = new cdr(file.getname()); try (bufferedreader bfr = new bufferedreader(new filereader(file))) { list<string> lines = bfr.lines().collect(collectors.tolist()); lines.parallelstream().foreach(e -> { string[] data = e.split(",", -1); cdrentry entry = new cdrentry(file.getname()); (int = 0; < data.length; i++) { entry.setfield(i, data[i]); } cdr.addentry(entry); }); if (cdr != null) { cdrs.add(cdr); } } catch (ioexception e) { e.printstacktrace(); } }
what observe , not time, either arrayindexnotbound exception @ readcdrp function on line (which awkward, list of cdr arraylist() ):
cdr.addentry(entry);
or @ last line in execute4() apply sorting.
i think issue first parallelstream execute4 not in separate space in memory second parallelstream execution inside readcdrp() , seems share wrongly data. using "seem" word can't confirm , hutch.
the questions are: code buggy bone jdk8 perspective? there workaround using same flow, using countdownlatch example? limitation of forkjoinpool ?
thanks responce....
edit(1): addentry part of class itself:
class cdr { public final string filename; private final list<cdrentry> entries = new arraylist<cdrentry>(); public cdr(string filename) { super(); this.filename = filename; } public list<cdrentry> getentries() { return entries; } public list<cdrentry> addentry(cdrentry e) { entries.add(e); return entries; } public string getfilename() { return this.filename; } }
when starting programming in functional style should prefer immutable objects can created via construction (or using builder pattern or factory method). cdrentry
class may this:
class cdrentry { private final string[] fields; private final string name; public cdrentry(string name, string[] fields) { this.name = name; this.fields = fields; } // add getters , whatever }
and cdr
class may this:
class cdr { private final string filename; private final list<cdrentry> entries; public cdr(string filename, list<cdrentry> entries) { this.filename = filename; this.entries = entries; } public list<cdrentry> getentries() { return entries; } public string getfilename() { return this.filename; } }
having such classes things become easier. rest of code can rewritten this:
public void execute4() { file filepath = new file(filepathdata); file[] files = filepath.listfiles((file data, string name) -> data.getname().endswith("cdr")); // fixed line: had compilation error list<cdr> cdrs = arrays.stream(files).parallel() .map(this::readcdrp).sorted(cdrsorter) .collect(collectors.tolist()); } private cdr readcdrp(file file) { try (bufferedreader bfr = new bufferedreader(new filereader(file))) { // i'm not sure collecting lines list // before main processing necessary return bfr.lines().parallelstream() .map(e -> new cdrentry(file.getname(), e.split(",", -1))) .collect(collectors.collectingandthen( collectors.tolist(), list -> new cdr(file.getname(), list))); } catch (ioexception e) { throw new uncheckedioexception(e); } }
in general remember foreach
not cleanest way solve tasks. may helpful when integrate streams legacy code, in general should avoided.
Comments
Post a Comment