import java.nio.file.*; import java.util.*; import java.util.stream.*; /** * Fun with Java 8 pipelines/streams of strings * * @author Chris Bailey-Kellogg, Dartmouth CS 10, Fall 2016 */ public class StringStreams { /** * Returns an igPay atinLay version of the string */ static String toPigLatin(String s) { int i = 0; while (i for example "+(ex++)); console.nextLine(); // Print out their lengths Stream.of("hi", "there") .map(String::length) .forEach(System.out::println); System.out.println(" for example "+(ex++)); console.nextLine(); // Translate each to pig Latin Stream.of("mary", "had", "a", "little", "lamb", "it's", "fleece", "was", "white", "as", "snow") .map(StringStreams::toPigLatin) .forEach(System.out::println); System.out.println(" for example "+(ex++)); console.nextLine(); // Keep only three-letter words List words = Arrays.asList("the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"); words.stream() .filter(w -> w.length() == 3) .forEach(System.out::println); System.out.println(" for example "+(ex++)); console.nextLine(); // Keep only three-letter words, removing duplicates and sorting words.stream() .filter(w -> w.length() == 3) .distinct() .sorted() .forEach(System.out::println); System.out.println(" for example "+(ex++)); console.nextLine(); // Let's get word counts this way! String page = "Pretend that this string was loaded from a web page. We won't go to all that trouble here. This string contains multiple words. And multiple copies of multiple words. And multiple words with multiple copies. It is to be used as a test to demonstrate how sets work in removing redundancy by keeping only one copy of each thing. Is it very very redundant in having more than one copy of some words?"; String[] pageWords = page.split("[ .,?!]+"); // split on punctuation and white space Map wordCounts = Stream.of(pageWords) .map(String::toLowerCase) .collect(Collectors.groupingBy((String w) -> w, Collectors.counting())); System.out.println(wordCounts); System.out.println(" for example "+(ex++)); console.nextLine(); // Or how many words start with each letter Map firstLetterCounts = Stream.of(pageWords) .map(String::toLowerCase) .collect(Collectors.groupingBy((String w) -> w.charAt(0), Collectors.counting())); System.out.println(firstLetterCounts); System.out.println(" for example "+(ex++)); console.nextLine(); // Or letter counts (using single-character Strings for simplicity) Map charCounts = Stream.of(pageWords) .map(String::toLowerCase) .map(w -> w.split("")) .flatMap(Arrays::stream) .collect(Collectors.groupingBy((String c) -> c, Collectors.counting())); System.out.println(charCounts); System.out.println(" for example "+(ex++)); console.nextLine(); // Can process a file, here Romeo & Juliet, limiting output Files.lines(Paths.get("inputs/shakespeare/romeoAndJuliet.txt")) .map(line -> line.split("\\W+")) .flatMap(Arrays::stream) .map(String::toLowerCase) .filter(w -> w.length() == 4) .distinct() .sorted() .limit(25) .forEach(System.out::println); System.out.println(" for example "+(ex++)); console.nextLine(); // How many 4-letter words? long count = Files.lines(Paths.get("inputs/shakespeare/romeoAndJuliet.txt")) .map(line -> line.split("\\W+")) .flatMap(Arrays::stream) .map(String::toLowerCase) .filter(w -> w.length() == 4) .distinct() .count(); System.out.println("# 4-letter words:"+count); System.out.println(" for example "+(ex++)); console.nextLine(); // By length Files.lines(Paths.get("inputs/shakespeare/romeoAndJuliet.txt")) .map(line -> line.split("\\W+")) .flatMap(Arrays::stream) .map(String::toLowerCase) .distinct() .sorted((w1,w2) -> w2.length() - w1.length()) .limit(25) .forEach(System.out::println); System.out.println(" for example "+(ex++)); console.nextLine(); // Average word length double len = Files.lines(Paths.get("inputs/shakespeare/romeoAndJuliet.txt")) .map(line -> line.split("\\W+")) .flatMap(Arrays::stream) .mapToDouble(String::length) .average() .getAsDouble(); System.out.println("average length over all words: "+len); System.out.println("All done!"); } }