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