// This program contains some examples of Java 8 constructs. Three of the most // important higher-order functions to understand are map, filter, and reduce. // higher order function are methods that take in methods as an argument import java.util.*; import java.util.stream.*; import java.util.function.*; public class Java8Demo { public static void main(String[] args) { listExample(); primesExample(); parallelExample(); } // some Java 8 examples using a list of strings public static void listExample() { List words = Arrays.asList("is", "mayonnaise", "an", "instrument?"); // old fashioned way to print the words System.out.println("For loop approach"); for (int i = 0; i < words.size(); i++) { System.out.print(words.get(i) + " "); } System.out.println(); System.out.println(); // Java 5 introduced the for-each loop and Iterable interface System.out.println("For-each loop approach"); for (String word : words) { System.out.print(word + " "); } System.out.println(); System.out.println(); // Java 8 introduced this idea of "Streams" System.out.println("Stream approach"); words // List .stream() // Stream .forEach(Java8Demo::printWithSpace); words // List .stream() // Stream .forEach(Java8Demo::printWithSpace); words // List .stream() // Stream .forEach((word) -> System.out.print(word + " ")); // anonymous function / lambda words // List ["i", "m", "a", "i"] .stream() // Stream "i", "m", "a" ,"i" .map((word) -> word + " ") // Stream "i ", "m ", "a " ,"i " .forEach(System.out::print); } public static void printWithSpace(String word) { System.out.println(word + " "); } // example of finding the sum of the primes between 1 and 20,000 public static void primesExample() { System.out.println("Loop-based approach"); // perform a slow operation with the iterative approach printSumIterative(20001); System.out.println("Stream approach"); // perform a slow operation and report elapsed time printSum(20001); System.out.println(); } // Prints the sum of all the primes between 1 and n // along with the time it took, done iteratively public static void printSumIterative(int n) { long start = System.currentTimeMillis(); int sum = 0; for (int i = 1; i < 20001; i++) { if (isPrimeIterative(i)) { sum += i; } } double elapsed = (System.currentTimeMillis() - start) / 1000.0; System.out.println("n = " + sum + ", time = " + elapsed); } // Returns true if n is a prime number, determined with in an // iterative manner, and false otherwise public static boolean isPrimeIterative(int n) { int factors = 0; for (int i = 1; i <= n; i++) { if (n % i == 0) { factors++; } } return factors == 2; } // times how long it takes to find the sum of the primes in the stream public static void printSum(int n) { // run the algorithm and time it long start = System.currentTimeMillis(); int sum = IntStream.range(1, n + 1) .parallel() .filter(Java8Demo::isPrime) .sum(); double elapsed = (System.currentTimeMillis() - start) / 1000.0; System.out.println("n = " + sum + ", time = " + elapsed); } // Returns true if n is a prime number, determined with a // stream, and false otherwise public static boolean isPrime(int n) { return IntStream.range(1, n + 1) .filter((num) -> n % num == 0) .reduce(0, (count, element) -> count + 1) == 2; } // it's great to be able to make a stream parallel to make a program run // faster, but sometimes that doesn't make sense, as in this example public static void parallelExample() { System.out.println("Let's print 1 through 20"); System.out.print("sequentially:"); IntStream.range(1, 21) .forEach(n -> System.out.print(" " + n)); System.out.println(); System.out.print("in parallel :"); IntStream.range(1, 21) .parallel() .forEach(n -> System.out.print(" " + n)); System.out.println(); System.out.println(); } }