import java.util.*; import java.util.function.*; import java.util.stream.*; class StreamUsage { // a few different examples can be uncommented/run from here. public static void main(String[] args){ main0(new String[]{}); // main1(new String[]{}); // main2(new String[]{}); // main3(new String[]{}); } public static void main0(String[] args){ // ------------------------------------------------------------------------- // old fashioned naive way: many stages of loops, extra data. int[] xs = {1,2,3,4,5,6,7,8,9,10}; // count how many evens there are. int numEvens = 0; for (int i=0; ix%2==0) .sum(); System.out.println("sum of evens: "+sum3); // ------------------------------------------------------------------------- // variant showing that filter takes an instance of an interface (named IntPredicate). // this shows the syntactic nicety of lambdas over anonymous classes that implement // the only function of the Functional Interface. int sum4 = Arrays .stream(xs) .filter(new IntPredicate(){@Override public boolean test(int v){ return v%2==0;}}) .sum(); System.out.println("sum of evens: "+sum4); // ------------------------------------------------------------------------- // another variant that builds its own summation via reduce: int sum5 = Arrays.stream(xs) . filter(x->x%2==0) . reduce(0,(a,b)->a+b); System.out.println("sum of evens: "+sum5); // ------------------------------------------------------------------------- // variant that saves a Predicate to a variable to use when filtering. // Predicate is more general than IntPredicate, so we're going with a List version. // Useful when you'll use the same predicate repeatedly. Predicate even = n -> n%2==0; List ys = Arrays.asList(1,2,3,4,5,6,7,8,9,10); int sum6 = ys.stream() // get the stream .filter(even) // filter out odds .mapToInt(x->x) // convert Stream to IntStream .sum(); // use IntStream::sum. System.out.println("sum of evens: "+sum6); // ------------------------------------------------------------------------- // another variant reminding us we can make classes that implement the functional interface // that our stream operations may need. class EvenChecker implements Predicate{ @Override public boolean test(Integer x){ return x%2==0; } }; int sum7 = ys.stream() .filter(new EvenChecker()) .mapToInt(x->x) .sum(); System.out.println("sum of evens: "+sum7); } public static ArrayList people = new ArrayList(Arrays.asList( new Person("Lemon",5), new Person("Tango",92), new Person("Random",42), new Person("Toddler",2), new Person("Foo",22), new Person("Mark",36), new Person("Alison",37), new Person("Carrie",39), new Person("Stephanie",39), new Person("Julie",40) )); public static void main1 (String[] args){ Predicate canVote = (Person x) -> x.age>=18; // can infer that x must be a Person; don't need the lambda parameter's type. Predicate canVoteV2 = x -> x.age>=18; Predicate evenP = x -> x%2==0; Stream st = people.stream(); st = st.filter(canVote); IntStream agesStream = st.mapToInt( (Person p) -> p.age); agesStream = agesStream.map (x -> x+1); System.out.println("next year, this year's eligible voters will be these ages:"); // forEach is "terminal operation" - no stream of values comes out. agesStream.forEach( (int age) -> System.out.println(age)); // alternative: // agesStream.forEach( System.out :: println ); } public static void main2 (String[] args){ Predicate canVote = (Person x) -> x.age>=18; Predicate canVoteV2 = x -> x.age>=18; Predicate evenP = x -> x%2==0; // print all thirty-somethings with prime ages who have an i in their names: System.out.println("all 30-somethings with prime ages and an 'i' in their name:"); people.stream() .filter((Person p)->30<=p.age && p.age <= 39) .filter((Person p)-> prime(p.age)) .filter((Person p)-> p.name.contains("i")) .forEach(p -> System.out.println(p)) ; // same idea, but lambda parameters' types are inferred. people.stream() .filter( p ->30<=p.age && p.age <= 39) // no need to indicate the lambda parameter's type. .filter( p -> prime(p.age)) .filter( p -> p.name.contains("i")) .forEach (System.out::println) // special syntax for a lambda: compare to previous statement. ; } public static boolean prime(int n){ if (n<2) return false; for (int i=2; i xs = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7,8)); System.out.println("the list: "+xs); int evensProduct = xs.stream().filter(x -> x%2==0).reduce(1, (a,b)->a*b); System.out.println("product of evens:" + evensProduct); // 2*4*6*8 == 384 List> pairs = Arrays.asList(new Pair<>(1,1), new Pair<>(1,3), new Pair<>(2,6), new Pair<>(3,10), new Pair<>(5,15), new Pair<>(8,21), new Pair<>(13,28), new Pair<>(21,36), new Pair<>(34,45)); System.out.println("the pairs: "+pairs); List evenLefts = pairs.stream() . map(p -> p.left) . filter(x->x%2==0) . collect(Collectors.toList()); System.out.println("even lefts: "+evenLefts); long numEvenRights = pairs.stream() .map(p -> p.right) .filter(x->x%2==0) .count(); System.out.println("number of even rights: "+numEvenRights); // four. String[] ghosts = {"Blinky","Pinky","Inky","Clyde"}; // Optional, because we might not have had any items in the array. Optional combo = Arrays.stream(ghosts) . reduce((rest,s) -> rest+","+s); // decides how to handle the empty case (with ""). String ans = combo.orElse(""); System.out.println("ghost names reduced: "+ans); System.out.println("ghost names one-liner: " +Arrays.stream(ghosts) .reduce((rest,s) -> rest+","+s) .orElse("") ); List vals = Arrays.asList(1,2,3,4,2,3,4,2,3,4,2,4,2,4); System.out.println("mode(vals): "+mode(vals)); } public static List mode(List xs){ // get the list of unique values. List uniques = xs.stream() .distinct() .collect(Collectors.toList()); // initialize a mapping from values to counts. Map counts = new TreeMap<>(); // set up each counter to zero. uniques.stream().forEach(x -> counts.put(x,0)); // count each item. xs.stream().forEach(x -> counts.put(x,counts.get(x)+1)); // find max. int max = counts.keySet().stream() .reduce(0,(z,x)->counts.get(x)>z?counts.get(x):z); // filter out keys that occurred the most. List modes = counts.keySet().stream() .filter(x -> counts.get(x)==max) .collect(Collectors.toList()); return modes; } public static boolean prime_v2(int n){ // base cases still handled directly. if (n<2){ return false; } // build a thing that generates ints from 2 and up IntSupplier twoAndUp = new IntSupplier(){ int x=2; @Override public int getAsInt(){ return x++;} }; // gratuitous use of streams here. return IntStream .generate(twoAndUp) // start with ints 2,3,4,... .limit(Math.max(0,n-2)) // only keep enough through (n-1) .filter(i-> n%i==0) // only keep ones that divide n evenly .count() == 0; // are there any left? No? then n is prime. } } class MoreUsage { public static void go(){ int[] xs = {1,2,3,4,5,6,7,8,9}; class EvenChecker implements Predicate{ @Override public boolean test(Integer x){ return x % 2 == 0; } }; Predicate even = new EvenChecker(); even = x -> x%2==0; int sum = 0; for (int x : xs){ if (even.test(x)){ sum += x; } } System.out.println("sum:"+sum); class IntPred implements IntPredicate{ @Override public boolean test(int x){ return x%2==0;} }; IntStream vals = Arrays.stream(xs); vals = vals.filter(new IntPred()); int ans = vals.sum(); System.out.println("sum: "+sum); ans = Arrays.stream(xs).filter(new IntPred()).sum(); System.out.println("sum: "+sum); IntPredicate ip = new IntPred(); ans = Arrays.stream(xs).filter(ip).sum(); System.out.println("sum: "+sum); abstract class AbsCheck implements IntPredicate{ }; ip = new AbsCheck(){ @Override public boolean test(int x){ return x%2==0;} }; ans = Arrays.stream(xs).filter(ip).sum(); System.out.println("sum: "+sum); ans = Arrays.stream(xs).filter(new AbsCheck(){ @Override public boolean test(int x){ return x%2==0;} }).sum(); System.out.println("sum: "+sum); ans = Arrays.stream(xs) . filter(new IntPredicate() { @Override public boolean test(int x){ return x%2==0; } }) . sum(); System.out.println("sum: "+sum); ans = Arrays.stream(xs).filter( (int x) -> x%2==0 ).sum(); System.out.println("sum: "+sum); ans = Arrays.stream(xs).filter( (int x) -> { boolean yes = true; if (x%2!=0){ yes = false; } return yes; } ).sum(); System.out.println("sum: "+sum); } } class Person{ String name; int age; public Person(String name, int age){ this.name=name; this.age=age; } @Override public String toString(){ return String.format("P(%s,%s)",name,age); } } class Pair{ L left; R right; Pair(L left, R right){ this.left=left; this.right=right; } @Override public String toString() { return String.format("(%s,%s)",left,right);} }