diff --git a/pom.xml b/pom.xml index 10e5035e..08559757 100644 --- a/pom.xml +++ b/pom.xml @@ -31,19 +31,32 @@ + + + ${basedir}/src/main/java + + **/*.properties + **/*.xml + + + + ${basedir}/src/main/resources + + org.apache.maven.plugins maven-compiler-plugin - 3.1 + 3.8.0 - 1.9 - 1.9 + 13 + 13 org.apache.maven.plugins maven-shade-plugin + 3.2.3 package diff --git a/src/main/java/lambdasinaction/chap1/C1FilteringApples.java b/src/main/java/lambdasinaction/chap1/C1FilteringApples.java new file mode 100644 index 00000000..79bb6d5d --- /dev/null +++ b/src/main/java/lambdasinaction/chap1/C1FilteringApples.java @@ -0,0 +1,126 @@ +/* + * www.laughlast666.org Inc. + * Copyright (c) 2020-2020 All rights reserved. + */ + +package lambdasinaction.chap1; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; + +public class C1FilteringApples { + + public static void main(String... args) { + + List inventory = Arrays.asList(new Apple(80, "green"), + new Apple(155, "green"), + new Apple(120, "red")); + // + List greenApples1 = filterApples(inventory, new Predicate() { + @Override + public boolean test(Apple apple) { + return isGreenApple(apple); + } + }); + // + List greenApples2 = filterApples(inventory, (Apple apple) -> isGreenApple(apple)); + // + List greenApples3 = filterApples(inventory, (apple -> isGreenApple(apple))); + // + List greenApples4 = filterApples(inventory, C1FilteringApples::isGreenApple); + // + C1FilteringApples c1FilteringApples = new C1FilteringApples(); + List greenApples5 = filterApples(inventory, c1FilteringApples::isGreenApple4Demo); + // + List inventory1 = new ArrayList<>(inventory); + inventory1.add(new Apple(166, "green")); + List greenHeavyApples = filterApples(inventory1, new Predicate() { + @Override + public boolean test(Apple apple) { + return isGreenApple(apple) && isHeavyApple(apple); + } + }); + // + List greenHeavyApples1 = filterApples(inventory1, apple -> isGreenApple(apple) && isHeavyApple(apple)); + + } + + public static List filterGreenApples(List inventory) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if (isGreenApple(apple)) { + result.add(apple); + } + } + return result; + } + + public static List filterHeavyApples(List inventory) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if (isHeavyApple(apple)) { + result.add(apple); + } + } + return result; + } + + public boolean isGreenApple4Demo(Apple apple) { + return "green".equals(apple.getColor()); + } + + public static boolean isGreenApple(Apple apple) { + return "green".equals(apple.getColor()); + } + + public static boolean isHeavyApple(Apple apple) { + return apple.getWeight() > 150; + } + + public static List filterApples(List inventory, Predicate p) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if (p.test(apple)) { + result.add(apple); + } + } + System.out.println(result); + return result; + } + + public static class Apple { + private int weight = 0; + private String color = ""; + + public Apple(int weight, String color) { + this.weight = weight; + this.color = color; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String toString() { + return "Apple{" + + "color='" + color + '\'' + + ", weight=" + weight + + '}'; + } + } + +} diff --git a/src/main/java/lambdasinaction/chap2/C2FilteringApples.java b/src/main/java/lambdasinaction/chap2/C2FilteringApples.java new file mode 100644 index 00000000..eabb2265 --- /dev/null +++ b/src/main/java/lambdasinaction/chap2/C2FilteringApples.java @@ -0,0 +1,169 @@ +package lambdasinaction.chap2; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class C2FilteringApples { + + public static void main(String... args) { + + List inventory = Arrays.asList(new Apple(80, "green"), new Apple(155, "green"), + new Apple(120, "red")); + + // [Apple{color='green', weight=80}, Apple{color='green', weight=155}] + List greenApples = filterApplesByColor(inventory, "green"); + System.out.println(greenApples); + + // [Apple{color='red', weight=120}] + List redApples = filterApplesByColor(inventory, "red"); + System.out.println(redApples); + + // [Apple{color='green', weight=80}, Apple{color='green', weight=155}] + List greenApples2 = filter(inventory, new AppleColorPredicate()); + // added by ll6 + System.out.println("-- inline4greenapples --"); + List greenApples22 = filter(inventory, new ApplePredicate() { + @Override + public boolean test(Apple a) { + return "green".equals(a.getColor()); + } + }); + // added by ll6 + System.out.println("-- lambda4greenapples --"); + List greenApples23 = filter(inventory, apple -> "green".equals(apple.getColor())); + // [Apple{color='green', weight=155}] + List heavyApples = filter(inventory, new AppleWeightPredicate()); + // added by ll6 + System.out.println("-- inline4heavyapples --"); + List heavyApples21 = filter(inventory, new ApplePredicate() { + @Override + public boolean test(Apple a) { + return a.getWeight() > 150; + } + }); + // added by ll6 + System.out.println("-- lambda4heavyapples --"); + List heavyApples22 = filter(inventory, apple -> apple.getWeight() > 150); + // [] + List redAndHeavyApples = filter(inventory, new AppleRedAndHeavyPredicate()); + + // added by ll6 + System.out.println("-- lambda4redAndheavyapples --"); + List heavyApples23 = filter(inventory, apple -> "red".equals(apple.getColor()) + && apple.getWeight() > 150); + // [Apple{color='red', weight=120}] + List redApples2 = filter(inventory, new ApplePredicate() { + @Override + public boolean test(Apple a) { + return "red".equals(a.getColor()); + } + }); + + // added by ll6 + System.out.println("-- lambda4redapples --"); + List redApples21 = filter(inventory, apple -> "red".equals(apple.getColor())); + } + + public static List filterGreenApples(List inventory) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if ("green".equals(apple.getColor())) { + result.add(apple); + } + } + return result; + } + + public static List filterApplesByColor(List inventory, String color) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if (apple.getColor().equals(color)) { + result.add(apple); + } + } + return result; + } + + public static List filterApplesByWeight(List inventory, int weight) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if (apple.getWeight() > weight) { + result.add(apple); + } + } + return result; + } + + + public static List filter(List inventory, ApplePredicate p) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if (p.test(apple)) { + result.add(apple); + } + } + System.out.println(result); + return result; + } + + public static class Apple { + private int weight = 0; + private String color = ""; + + public Apple(int weight, String color) { + this.weight = weight; + this.color = color; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + @Override + public String toString() { + return "Apple{" + + "color='" + color + '\'' + + ", weight=" + weight + + '}'; + } + } + + interface ApplePredicate { + public boolean test(Apple a); + } + + static class AppleWeightPredicate implements ApplePredicate { + @Override + public boolean test(Apple apple) { + return apple.getWeight() > 150; + } + } + + static class AppleColorPredicate implements ApplePredicate { + @Override + public boolean test(Apple apple) { + return "green".equals(apple.getColor()); + } + } + + static class AppleRedAndHeavyPredicate implements ApplePredicate { + @Override + public boolean test(Apple apple) { + return "red".equals(apple.getColor()) + && apple.getWeight() > 150; + } + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap3/C3ExecuteAround.java b/src/main/java/lambdasinaction/chap3/C3ExecuteAround.java new file mode 100644 index 00000000..ade70e73 --- /dev/null +++ b/src/main/java/lambdasinaction/chap3/C3ExecuteAround.java @@ -0,0 +1,49 @@ +package lambdasinaction.chap3; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +public class C3ExecuteAround { + + public static final String CHAP_3_DATA_TXT = "lambdasinaction/chap3/data.txt"; + + public static void main(String... args) throws IOException { + + // method we want to refactor to make more flexible + String result = processFileLimited(CHAP_3_DATA_TXT); + System.out.println(result); + + System.out.println("---"); + + // added by ll6 + String oneLine = processFile(CHAP_3_DATA_TXT, bufferedReader -> bufferedReader.readLine()); + System.out.println(oneLine); + + System.out.println("---2---"); + String twoLines = processFile(CHAP_3_DATA_TXT, bufferedReader -> bufferedReader.readLine() + "\n" + + bufferedReader.readLine() + ); + System.out.println(twoLines); + + } + + public static String processFileLimited(String fileName) throws IOException { + try (BufferedReader br = + new BufferedReader(new FileReader(fileName))) { + return br.readLine(); + } + } + + // added by lala + public interface BufferedReaderProcessor { + public String readFile(BufferedReader br) throws IOException; + } + + // + public static String processFile(String fileName, BufferedReaderProcessor brp) throws IOException { + try (BufferedReader br = new BufferedReader(new FileReader(fileName))) { + return brp.readFile(br); + } + } +} diff --git a/src/main/java/lambdasinaction/chap3/C3Lambdas.java b/src/main/java/lambdasinaction/chap3/C3Lambdas.java new file mode 100644 index 00000000..261ab223 --- /dev/null +++ b/src/main/java/lambdasinaction/chap3/C3Lambdas.java @@ -0,0 +1,83 @@ +package lambdasinaction.chap3; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +public class C3Lambdas { + public static void main(String... args) { + + // + Runnable r = () -> { + System.out.println("Hi,Lambda!"); + }; + Runnable r2 = () -> System.out.println("Hi,Lambda again!"); + r.run(); + r2.run(); + // + List inventory = Arrays.asList(new Apple(80, "green"), + new Apple(155, "green"), + new Apple(166, "green"), + new Apple(120, "red")); + List redApples = filter(inventory, (Apple a) -> "red".equals(a.getColor())); + List greenApples = filter(inventory, apple -> "green".equals(apple.getColor())); + List heavyApples = filter(inventory, apple -> apple.getWeight() > 150); + List greenAndHeavyApples = filter(inventory, (Apple a) -> "green".equals(a.getColor()) + && a.getWeight() > 150); + // + Comparator cmpByWeight = (a1, a2) -> a1.getWeight().compareTo(a2.getWeight()); + inventory.sort(cmpByWeight); + System.out.println(inventory); + + + } + + public static List filter(List inventory, ApplePredicate p) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if (p.test(apple)) { + result.add(apple); + } + } + System.out.println(result); + return result; + } + + public static class Apple { + private int weight = 0; + private String color = ""; + + public Apple(int weight, String color) { + this.weight = weight; + this.color = color; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String toString() { + return "Apple{" + + "color='" + color + '\'' + + ", weight=" + weight + + '}'; + } + } + + interface ApplePredicate { + public boolean test(Apple a); + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap3/C3LambdasCompound.java b/src/main/java/lambdasinaction/chap3/C3LambdasCompound.java new file mode 100644 index 00000000..ffc71176 --- /dev/null +++ b/src/main/java/lambdasinaction/chap3/C3LambdasCompound.java @@ -0,0 +1,9 @@ +package lambdasinaction.chap3; + +public class C3LambdasCompound { + public static void main(String... args) { + + // + + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap3/C3Sorting.java b/src/main/java/lambdasinaction/chap3/C3Sorting.java new file mode 100644 index 00000000..9cea6115 --- /dev/null +++ b/src/main/java/lambdasinaction/chap3/C3Sorting.java @@ -0,0 +1,80 @@ +package lambdasinaction.chap3; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +public class C3Sorting { + + public static void main(String... args) { + + // 1 + List inventory = new ArrayList<>(); + inventory.addAll(Arrays.asList(new Apple(80, "green"), + new Apple(155, "green"), + new Apple(120, "red"))); + //added by ll6 + + AppleComparatorByWeight comparatorByWeight = new AppleComparatorByWeight(); + inventory.sort(comparatorByWeight); + System.out.println(inventory); + // + inventory.set(1, new Apple(30, "green")); + inventory.sort(comparatorByWeight); + System.out.println(inventory); + // + inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())); + System.out.println(inventory); + // + inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight())); + System.out.println(inventory); + // + inventory.set(1, new Apple(10, "red")); + inventory.sort(Comparator.comparing(Apple::getWeight)); + System.out.println(inventory); + + } + + // + static class AppleComparatorByWeight implements Comparator { + @Override + public int compare(Apple a1, Apple a2) { + return a1.getWeight().compareTo(a2.getWeight()); + } + } + + public static class Apple { + private Integer weight = 0; + private String color = ""; + + public Apple(Integer weight, String color) { + this.weight = weight; + this.color = color; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String toString() { + return "Apple{" + + "color='" + color + '\'' + + ", weight=" + weight + + '}'; + } + } + +} diff --git a/src/main/java/lambdasinaction/chap4/C4StreamBasic.java b/src/main/java/lambdasinaction/chap4/C4StreamBasic.java new file mode 100644 index 00000000..545e102f --- /dev/null +++ b/src/main/java/lambdasinaction/chap4/C4StreamBasic.java @@ -0,0 +1,51 @@ +package lambdasinaction.chap4; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import static java.util.Comparator.comparing; +import static java.util.stream.Collectors.toList; + +public class C4StreamBasic { + + public static void main(String... args) { + // Java 7 + getLowCaloricDishesNamesInJava7(Dish.menu).forEach(System.out::println); + + System.out.println("---"); + + // Java 8 + getLowCaloricDishesNamesInJava8(Dish.menu).forEach(System.out::println); + + } + + public static List getLowCaloricDishesNamesInJava7(List dishes) { + List lowCaloricDishes = new ArrayList<>(); + for (Dish d : dishes) { + if (d.getCalories() < 400) { + lowCaloricDishes.add(d); + } + } + Collections.sort(lowCaloricDishes, new Comparator() { + @Override + public int compare(Dish d1, Dish d2) { + return Integer.compare(d1.getCalories(), d2.getCalories()); + } + }); + List lowCaloricDishesName = new ArrayList<>(); + for (Dish d : lowCaloricDishes) { + lowCaloricDishesName.add(d.getName()); + } + return lowCaloricDishesName; + } + + public static List getLowCaloricDishesNamesInJava8(List dishes) { + return dishes.stream() + .filter(dish -> dish.getCalories() < 400) + .sorted(comparing(Dish::getCalories)) + .map(Dish::getName) + .collect(toList()); + } +} diff --git a/src/main/java/lambdasinaction/chap4/C4StreamVsCollection.java b/src/main/java/lambdasinaction/chap4/C4StreamVsCollection.java new file mode 100644 index 00000000..81a9ccd2 --- /dev/null +++ b/src/main/java/lambdasinaction/chap4/C4StreamVsCollection.java @@ -0,0 +1,18 @@ +package lambdasinaction.chap4; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + + +public class C4StreamVsCollection { + + public static void main(String... args) { + List names = Arrays.asList("Java8", "Lambdas", "In", "Action"); + Stream s = names.stream(); + s.forEach(System.out::println); + // s must be assigned again because streams can be consumed only once + s = names.stream(); + s.forEach(System.out::println); + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap5/C5BuildingStreams.java b/src/main/java/lambdasinaction/chap5/C5BuildingStreams.java new file mode 100644 index 00000000..6f9ecb99 --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/C5BuildingStreams.java @@ -0,0 +1,78 @@ +package lambdasinaction.chap5; + +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.function.IntSupplier; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class C5BuildingStreams { + public static final String CHAP_5_DATA_TXT = "lambdasinaction/chap5/data.txt"; + + public static void main(String... args) throws Exception { + + System.out.println("---- Stream.of "); + Stream stringStream = Stream.of("Java 8", "Lambda", "In", "Action"); + stringStream.map(String::toUpperCase).forEach(System.out::println); + + System.out.println("---- Stream.empty "); + Stream emptyStream = Stream.empty(); + + System.out.println("---- Array.stream"); + int[] numbers = {1, 3, 5, 7}; + System.out.println(Arrays.stream(numbers).sum()); + + System.out.println("---- Stream.iterate"); + Stream.iterate(0, n -> n + 2).limit(5).forEach(System.out::println); + + System.out.println("---- fibonnaci via Stream.iterate"); + Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]}).limit(10) + .forEach(t -> System.out.println("(" + t[0] + ", " + t[1] + ")")); + Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]}).limit(10).map(t -> t[0]) + .forEach(System.out::println); + System.out.println("---- ramdom via Stream.generate"); + Stream.generate(Math::random).limit(10).forEach(System.out::println); + + System.out.println("---- one number via Stream.generate"); + Stream.generate(() -> 1).limit(5).forEach(System.out::println); + IntStream.generate(new IntSupplier() { + @Override + public int getAsInt() { + return 2; + } + }).limit(5).forEach(System.out::println); + + System.out.println("---- fibonnaci via IntSupplier"); + IntSupplier fib = new IntSupplier() { + private int previous = 0; + private int current = 0; + + @Override + public int getAsInt() { + //the 1st time and the 1st number: 0 + if (0 == this.current) { + this.current = 1; + } else { + int nextValue = this.previous + this.current; + this.previous = this.current; + this.current = nextValue; + } + return this.previous; + } + }; + IntStream.generate(fib).limit(10).forEach(System.out::println); + + System.out.println("---- Nio stream etc "); + + Files.lines(Paths.get(CHAP_5_DATA_TXT), Charset.defaultCharset()) + .flatMap(line -> Arrays.stream(line.split(" "))) + .distinct().forEach(System.out::println); + + long wordsCount = Files.lines(Paths.get(CHAP_5_DATA_TXT), Charset.defaultCharset()) + .flatMap(line -> Arrays.stream(line.split(" "))).distinct().count(); + System.out.println("There are " + wordsCount + " unique words in " + CHAP_5_DATA_TXT); + + } +} diff --git a/src/main/java/lambdasinaction/chap5/C5Filtering.java b/src/main/java/lambdasinaction/chap5/C5Filtering.java new file mode 100644 index 00000000..c449a2df --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/C5Filtering.java @@ -0,0 +1,51 @@ +package lambdasinaction.chap5; + +import lambdasinaction.chap4.Dish; + +import java.util.Arrays; +import java.util.List; + +import static java.util.stream.Collectors.toList; +import static lambdasinaction.chap4.Dish.menu; + +public class C5Filtering { + + public static void main(String... args) { + + System.out.println("---- Filtering with predicate ----"); + List vegetarianMenu = menu.stream() + .filter(Dish::isVegetarian) + .collect(toList()); + vegetarianMenu.forEach(System.out::println); + + System.out.println("---- Skipping elements ----"); + List skippedMenu = menu.stream() + .filter(Dish::isVegetarian) + .skip(3) + .collect(toList()); + skippedMenu.forEach(System.out::println); + + System.out.println("---- Truncating elements ----"); + List limit3Menu = menu.stream() + .filter(Dish::isVegetarian) + .limit(3) + .collect(toList()); + limit3Menu.forEach(System.out::println); + + System.out.println("---- Choosing unique elements ----"); + List uniqueMenu = menu.stream() + .map(Dish::getCalories) + .distinct() + .sorted() + .collect(toList()); //TODO: .forEach here error + uniqueMenu.forEach(System.out::println); + + System.out.println("---- Choosing unique numbers ----"); + List numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); + numbers.stream() + .filter(i -> i % 2 == 0) + .distinct() + .forEach(System.out::println); //TODO: .forEach here okay + + } +} diff --git a/src/main/java/lambdasinaction/chap5/C5Finding.java b/src/main/java/lambdasinaction/chap5/C5Finding.java new file mode 100644 index 00000000..74ced978 --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/C5Finding.java @@ -0,0 +1,23 @@ +package lambdasinaction.chap5; + +import lambdasinaction.chap4.Dish; + +import java.util.Optional; + +import static lambdasinaction.chap4.Dish.menu; + +public class C5Finding { + + public static void main(String... args) { + System.out.println(menu.stream().anyMatch(Dish::isVegetarian) ? "Vegetarian Friendly" : "No Vegetarial"); + System.out.println(menu.stream().anyMatch(dish -> dish.getCalories() < 1000) ? "All Fit" : "Non All Fit"); + System.out.println(menu.stream().noneMatch(dish -> dish.getCalories() >= 1000) ? "All Fit" : "Non All Fit"); + + Optional firstVegetarian = menu.stream().filter(Dish::isVegetarian).findFirst(); + firstVegetarian.ifPresent(dish -> System.out.println(dish.getName())); + Optional anyVegetarian = menu.stream().filter(Dish::isVegetarian).findAny(); + for (int i = 3; i-- > 0; ) + anyVegetarian.ifPresent(dish -> System.out.println(dish.equals(firstVegetarian.get()))); + } + +} diff --git a/src/main/java/lambdasinaction/chap5/C5Laziness.java b/src/main/java/lambdasinaction/chap5/C5Laziness.java new file mode 100644 index 00000000..9d82db17 --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/C5Laziness.java @@ -0,0 +1,26 @@ +package lambdasinaction.chap5; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class C5Laziness { + + public static void main(String[] args) { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8); + List twoEvenSquares = numbers.stream() + .filter(n -> { + System.out.println("filtering: " + n); + return n % 2 == 0; + }) + .map(n -> { + System.out.println("mapping: " + n); + return n * n; + }) + .limit(3) + .collect(Collectors.toList()); + + } + + +} diff --git a/src/main/java/lambdasinaction/chap5/C5Mapping.java b/src/main/java/lambdasinaction/chap5/C5Mapping.java new file mode 100644 index 00000000..29bb2532 --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/C5Mapping.java @@ -0,0 +1,40 @@ +package lambdasinaction.chap5; + +import lambdasinaction.chap4.Dish; + +import java.util.Arrays; +import java.util.List; + +import static java.util.stream.Collectors.toList; +import static lambdasinaction.chap4.Dish.menu; + +public class C5Mapping { + + public static void main(String... args) { + + // map + List dishNames = menu.stream().map(Dish::getName).collect(toList()); + System.out.println(dishNames); + List dishCalorial = menu.stream().map(Dish::getCalories).collect(toList()); + dishCalorial.forEach(System.out::println); + + // map + List words = Arrays.asList("Hi", "World!"); + List wordLengths = words.stream().map(String::length).collect(toList()); + System.out.println(wordLengths); + List upperCaseWords = words.stream().map(String::toUpperCase).collect(toList()); + upperCaseWords.forEach(System.out::println); + + // flatMap + words.stream().flatMap(line -> Arrays.stream(line.split(""))) + .distinct().forEach(System.out::println); + + // flatMap + List numbers1 = Arrays.asList(1, 2, 3, 4, 5); + List numbers2 = Arrays.asList(6, 7, 8); + List pairs = numbers1.stream() + .flatMap(i -> numbers2.stream().map(j -> new int[]{i, j})) + .filter(pair -> (pair[0] + pair[1]) % 6 == 0).collect(toList()); + pairs.forEach(pair -> System.out.println("(" + pair[0] + ", " + pair[1] + ")")); + } +} diff --git a/src/main/java/lambdasinaction/chap5/C5NumericStreams.java b/src/main/java/lambdasinaction/chap5/C5NumericStreams.java new file mode 100644 index 00000000..dc7a441e --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/C5NumericStreams.java @@ -0,0 +1,55 @@ +package lambdasinaction.chap5; + +import lambdasinaction.chap4.Dish; + +import java.util.Arrays; +import java.util.List; +import java.util.OptionalInt; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static lambdasinaction.chap4.Dish.menu; + +public class C5NumericStreams { + + public static void main(String... args) { + + List numbers = Arrays.asList(1, 2, 3, 4, 5); + numbers.forEach(System.out::println); + IntStream.rangeClosed(1, 5).forEach(System.out::println); + Arrays.stream(numbers.toArray()).forEach(System.out::println); + int calories = menu.stream() + .mapToInt(Dish::getCalories) + .reduce(0, Integer::sum); + System.out.println("Number of calories:" + calories); + + + // max and OptionalInt + OptionalInt maxCalories = menu.stream() + .mapToInt(Dish::getCalories) + .max(); + + menu.stream().mapToInt(Dish::getCalories).max() + .ifPresentOrElse(m -> System.out.println("max found :" + m), () -> System.out.println(1)); + + // numeric ranges + IntStream evenNumbers = IntStream.rangeClosed(1, 100).filter(n -> n % 2 == 0); + IntStream evenNumbers1 = IntStream.range(1, 100).filter(n -> n % 2 == 0); + + System.out.println("Even Numbers #: in rangeClosed(1,100) " + evenNumbers.count() + ", " + + "and in range(1,100) " + evenNumbers1.count()); + + Stream pythagoreanTriples = IntStream.rangeClosed(1, 20).boxed() + .flatMap(a -> IntStream.rangeClosed(a, 20).boxed() + .filter(b -> C5NumericStreams.isPerfectSquare(a * a + b * b)) + .map(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)})); + + pythagoreanTriples.forEach(t -> System.out.println(t[0] + ", " + t[1] + ", " + t[2])); + + } + + public static boolean isPerfectSquare(int n) { + return Math.sqrt(n) % 1 == 0; + } + +} diff --git a/src/main/java/lambdasinaction/chap5/C5PuttingIntoPractice.java b/src/main/java/lambdasinaction/chap5/C5PuttingIntoPractice.java new file mode 100644 index 00000000..4cb61d94 --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/C5PuttingIntoPractice.java @@ -0,0 +1,73 @@ +package lambdasinaction.chap5; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.Comparator.comparing; +import static java.util.stream.Collectors.reducing; +import static java.util.stream.Collectors.toList; + +public class C5PuttingIntoPractice { + public static void main(String... args) { + Trader raoul = new Trader("Raoul", "Cambridge"); + Trader mario = new Trader("Mario", "Milan"); + Trader alan = new Trader("Alan", "Cambridge"); + Trader brian = new Trader("Brian", "Cambridge"); + + List transactions = Arrays.asList( + new Transaction(brian, 2011, 300), + new Transaction(raoul, 2012, 1000), + new Transaction(raoul, 2011, 400), + new Transaction(mario, 2012, 710), + new Transaction(mario, 2012, 700), + new Transaction(alan, 2012, 950) + ); + + // Query 1: Find all transactions from year 2011 and sort them by value (small to high). + List transactions2011 = transactions.stream().filter(t -> 2011 == t.getYear()) + .sorted(comparing(Transaction::getValue)).collect(toList()); + transactions2011.forEach(System.out::println); + + // Query 2: What are all the unique cities where the traders work? + List cities = transactions.stream().map(t -> t.getTrader().getCity()).distinct().collect(toList()); + System.out.println("unique cities of traders:\n" + cities); + + // Query 3: Find all traders from Cambridge and sort them by name. + List traders = transactions.stream().map(Transaction::getTrader) + .filter(t -> "Cambridge".equals(t.getCity())) + .sorted(comparing(Trader::getName)).collect(toList()); + System.out.println("Traders from Cambbridges:\n" + traders); + + // Query 4: Return a string of all traders’ names sorted alphabetically. + String traderStr = transactions.stream().map(t -> t.getTrader().getName() + " ") + .sorted().distinct().reduce("", (n1, n2) -> n1 + n2); + System.out.println("All unique traders'name in one line:\n" + traderStr); + System.out.println("All unique traders'name joining in one line:\n" + + transactions.stream().map(t -> t.getTrader().getName()) + .sorted().distinct().collect(Collectors.joining(", "))); + System.out.println("All traders'name reducing in one line:\n" + + transactions.stream() + .collect(reducing("", t -> t.getTrader().getName() + " ", (n1, n2) -> n1 + n2))); + + // Query 5: Are there any trader based in Milan? + boolean milanBased = + transactions.stream().anyMatch(t -> "Milan".equals(t.getTrader().getCity())); + System.out.println("Some Trader In Milan ?\n" + milanBased); + + + // Query 6: Update all transactions so that the traders from Milan are set to Cambridge. + transactions.stream().map(Transaction::getTrader).filter(trader -> "Milan".equals(trader.getCity())) + .forEach(trader -> trader.setCity("Cambridge")); + System.out.println(transactions); + + // Query 7: What's the highest value in all the transactions? + int highestValue = + transactions.stream() + .map(Transaction::getValue) + .reduce(0, Integer::max); + System.out.println(highestValue); + System.out.println("Hightest value :" + + transactions.stream().mapToInt(Transaction::getValue).max().getAsInt()); + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap5/C5Reducing.java b/src/main/java/lambdasinaction/chap5/C5Reducing.java new file mode 100644 index 00000000..5d3023ef --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/C5Reducing.java @@ -0,0 +1,32 @@ +package lambdasinaction.chap5; + +import lambdasinaction.chap4.Dish; + +import java.util.Arrays; +import java.util.List; + +import static lambdasinaction.chap4.Dish.menu; + +public class C5Reducing { + + public static void main(String... args) { + + List numbers = Arrays.asList(1, 3, 5, 7, 9); + int sum = numbers.stream().reduce(0, (a, b) -> a + b); + System.out.println(sum); + int sum2 = numbers.stream().reduce(0, Integer::sum); + System.out.println(sum2); + + int max = numbers.stream().reduce(0, (a, b) -> Integer.max(a, b)); + System.out.println(max); + numbers.stream().reduce(Integer::max).ifPresent(System.out::println); + numbers.stream().reduce(Integer::min).ifPresent(i -> System.out.println("minimal value:" + i)); + + int calories = menu.stream() + .map(Dish::getCalories) + .reduce(0, Integer::sum); + System.out.println("Number of calories:" + calories); + + System.out.println("Sum of calories : " + menu.stream().mapToInt(Dish::getCalories).sum()); + } +} diff --git a/src/main/java/lambdasinaction/chap6/C6Grouping.java b/src/main/java/lambdasinaction/chap6/C6Grouping.java new file mode 100644 index 00000000..0b5a0139 --- /dev/null +++ b/src/main/java/lambdasinaction/chap6/C6Grouping.java @@ -0,0 +1,118 @@ +package lambdasinaction.chap6; + +import java.util.*; + +import static java.util.stream.Collectors.*; +import static lambdasinaction.chap6.Dish.dishTags; +import static lambdasinaction.chap6.Dish.menu; + +public class C6Grouping { + + enum CaloricLevel {DIET, NORMAL, FAT} + + ; + + public static void main(String... args) { + System.out.println("Dishes grouped by type: groupDishesByType()\n" + + menu.stream().collect(groupingBy(Dish::getType))); + System.out.println("Dish names grouped by type: groupDishNamesByType()\n" + + menu.stream().collect(groupingBy(Dish::getType, mapping(Dish::getName, toList())))); + System.out.println("Dish tags grouped by type: groupDishTagsByType()\n" + + menu.stream().collect(groupingBy(Dish::getType, + flatMapping(dish -> dishTags.get(dish.getName()).stream(), toSet())))); + System.out.println("Caloric dishes grouped by type: groupCaloricDishesByType()\n" + + menu.stream().collect(groupingBy(Dish::getType, + filtering(dish -> dish.getCalories() > 500, toList())))); + System.out.println("Dishes grouped by caloric level: groupDishesByCaloricLevel()\n" + + menu.stream().collect(groupingBy(dish -> getCaloricLevel(dish)))); + System.out.println("Dishes grouped by type and caloric level: groupDishedByTypeAndCaloricLevel()\n" + + menu.stream().collect(groupingBy(Dish::getType, groupingBy(dish -> getCaloricLevel(dish))))); + System.out.println("Count dishes in groups: countDishesInGroups()\n" + + menu.stream().collect(groupingBy(Dish::getType, counting()))); + System.out.println("Most caloric dishes by type: mostCaloricDishesByType() \n" + + menu.stream().collect(groupingBy(Dish::getType, maxBy(Comparator.comparingInt(Dish::getCalories))))); + System.out.println("Most caloric dishes by type:+ mostCaloricDishesByTypeWithoutOprionals() \n" + + menu.stream().collect(groupingBy(Dish::getType, + collectingAndThen(maxBy(Comparator.comparingInt(Dish::getCalories)), + Optional::get)))); + System.out.println("Sum calories by type: sumCaloriesByType() \n" + + menu.stream().collect(groupingBy(Dish::getType, summingInt(Dish::getCalories)))); + System.out.println("Caloric levels by type: caloricLevelsByType()\n" + + menu.stream().collect(groupingBy(Dish::getType, mapping(dish -> getCaloricLevel(dish), toSet())))); + } + + private static Map> groupDishesByType() { + return menu.stream().collect(groupingBy(Dish::getType)); + } + + private static Map> groupDishNamesByType() { + return menu.stream().collect(groupingBy(Dish::getType, mapping(Dish::getName, toList()))); + } + + private static Map> groupDishTagsByType() { + return menu.stream().collect(groupingBy(Dish::getType, flatMapping(dish -> dishTags.get(dish.getName()).stream(), toSet()))); + } + + private static Map> groupCaloricDishesByType() { +// return menu.stream().filter(dish -> dish.getCalories() > 500).collect(groupingBy(Dish::getType)); + return menu.stream().collect(groupingBy(Dish::getType, filtering(dish -> dish.getCalories() > 500, toList()))); + } + + private static Map> groupDishesByCaloricLevel() { + return menu.stream().collect( + groupingBy(dish -> { + return getCaloricLevel(dish); + })); + } + + private static CaloricLevel getCaloricLevel(Dish dish) { + if (dish.getCalories() <= 400) + return CaloricLevel.DIET; + else if (dish.getCalories() <= 700) + return CaloricLevel.NORMAL; + else + return CaloricLevel.FAT; + } + + private static Map>> groupDishedByTypeAndCaloricLevel() { + return menu.stream().collect( + groupingBy(Dish::getType, + groupingBy((Dish dish) -> { + return getCaloricLevel(dish); + }) + ) + ); + } + + private static Map countDishesInGroups() { + return menu.stream().collect(groupingBy(Dish::getType, counting())); + } + + private static Map> mostCaloricDishesByType() { + return menu.stream().collect( + groupingBy(Dish::getType, + reducing((Dish d1, Dish d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2))); + } + + private static Map mostCaloricDishesByTypeWithoutOprionals() { + return menu.stream().collect( + groupingBy(Dish::getType, + collectingAndThen( + reducing((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2), + Optional::get))); + } + + private static Map sumCaloriesByType() { + return menu.stream().collect(groupingBy(Dish::getType, + summingInt(Dish::getCalories))); + } + + private static Map> caloricLevelsByType() { + return menu.stream().collect( + groupingBy(Dish::getType, mapping( + dish -> { + return getCaloricLevel(dish); + }, + toSet()))); + } +}