Thursday, 15 January 2015

java - For Loop Replacement: For Loops to Filters -



java - For Loop Replacement: For Loops to Filters -

i'm working on assignment computer science iii class (java programming), , in have encode file based on huffman coding.

import java.util.scanner; import java.util.arraylist; import java.io.*; import java.util.collections; import java.util.stringtokenizer; public class client { public static void main(string[] args) throws ioexception { // todo code application logic here scanner in = new scanner(system.in); system.out.println("enter filename read from."); string filename = in.nextline(); file file = new file(filename); scanner inputfile = new scanner(file); string line, word; stringtokenizer token; arraylist<character> chars = new arraylist<>(); while(inputfile.hasnext()){ line = inputfile.nextline(); arraylist<character> linechar = new arraylist<>(); (int i=0; i<line.length(); i++){ if (line.charat(i)!=' '){ linechar.add(line.charat(i)); } } chars.addall(linechar); } arraylist<character> prob = new arraylist<character>(); (int i=0; i<chars.size(); i++){ if (!prob.contains(chars.get(i))){ prob.add(chars.get(i)); } } (int i=0; i<prob.size(); i++){ system.out.print("frequency of " + prob.get(i)); system.out.println(": " + ((double)collections.frequency(chars, prob.get(i)))/chars.size()); }

i working on in netbeans ide , followed suggestions. changed lastly 2 loops to:

chars.stream().filter((char1) -> (!prob.contains(char1))).foreach((char1) -> { prob.add(char1); }); prob.stream().map((prob1) -> { system.out.print("frequency of " + prob1); homecoming prob1; }).foreach((prob1) -> { system.out.println(": " + ((double) collections.frequency(chars, prob1)) / chars.size()); });

i really, really, intrigued this, find hard trace everything. operates in same way loops , after testing see -does- work, want understand why , how. can give me insight?

netbeans did refactor code utilize java 8 streams, can done much better. example, appears prob supposed contain distinct list of characters. in java 8, can this:

list<character> prob = chars.stream() .distinct() .collect(collectors.tolist());

but using prob calculate how many times each character appears in chars. streams, can without first making prob list:

map<character, long> freq = chars.stream() .collect( collectors.groupingby( x->x, collectors.counting() ) );

the static methods in collections class imported statically, above written as:

map<character, long> freq = chars.stream() .collect(groupingby(x->x, counting());

that means, take stream of chars , create map. key of map char (that's x->x does) , value of map count of how many times char occurs in chars.

but that's not all! first half of method goes on lines of file , collects chars. can rewritten streams well:

stream<character> charstream = files.lines(paths.get(filename)) .flatmap(line -> line.chars().maptoobj(i->(char) i));

file.lines(..) gives stream of lines. flatmap part bit cryptic, unrolls every string stream of individual chars , joins streams have 1 big stream of chars.

and set together:

public static void main(string[] args) throws ioexception { scanner in = new scanner(system.in); system.out.println("enter filename read from."); string filename = in.nextline(); map<character, long> freq = files.lines(paths.get(filename)) .flatmap(line -> line.chars().maptoobj(i -> (char) i)) .collect(groupingby(x -> x, counting())); long total = freq.values().stream().maptolong(x->x).sum(); freq.foreach((chr, count) -> system.out.format("frequency of %s: %s%n", chr, ((double) count) / total) ); }

edit:

to output frequencies in sorted order, (using import static java.util.comparator.*):

freq.entryset().stream() .sorted(comparing(e->e.getvalue(), reverseorder())) .foreach(e -> system.out.format("frequency of %s: %s%n", e.getkey(), (double) e.getvalue() / total));

we take map of character count, stream entries, sort them values in reverse order , print each 1 out.

java for-loop filter stream file-processing

No comments:

Post a Comment