diff --git a/src/main/java/lambdasinaction/chap5/BuildingStreams.java b/src/main/java/lambdasinaction/chap5/BuildingStreams.java index 15280a39..29ccb67a 100644 --- a/src/main/java/lambdasinaction/chap5/BuildingStreams.java +++ b/src/main/java/lambdasinaction/chap5/BuildingStreams.java @@ -66,6 +66,7 @@ public int getAsInt(){ }; IntStream.generate(fib).limit(10).forEach(System.out::println); + //Stream files are auto closed long uniqueWords = Files.lines(Paths.get("lambdasinaction/chap5/data.txt"), Charset.defaultCharset()) .flatMap(line -> Arrays.stream(line.split(" "))) .distinct() diff --git a/src/main/java/lambdasinaction/chap5/Exercise.java b/src/main/java/lambdasinaction/chap5/Exercise.java new file mode 100644 index 00000000..041cb0d2 --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/Exercise.java @@ -0,0 +1,77 @@ +package lambdasinaction.chap5; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toList; + +public class Exercise { + + //Quiz 5.2: Mapping + @Test + public void testMap() { + List numbers = Arrays.asList(1, 2, 3, 4, 5); + List squares = + numbers.stream() + .map(n -> n * n) + .collect(toList()); + System.out.println(squares); + } + + @Test + public void testFlatMap() { + List numbers1 = Arrays.asList(1, 2, 3); + List numbers2 = Arrays.asList(3, 4); + List pairs = + numbers1.stream() + .flatMap(i -> numbers2.stream() + .map(j -> new int[]{i, j}) + ) + .collect(toList()); + + for (int i = 0; i < pairs.size(); i ++) { + System.out.println(pairs.get(i)[0] + "," + pairs.get(i)[1]); + System.out.println("---"); + } + + List> mapPairs = + numbers1.stream() + .map(i -> numbers2.stream() + .map(j -> new int[]{i, j}) + ) + .collect(toList()); + + List numbers11 = Arrays.asList(1, 2, 3); + List numbers12 = Arrays.asList(3, 4); + List pairs1 = + numbers11.stream() + .flatMap(i -> + numbers12.stream() + .filter(j -> (i + j) % 3 == 0) + .map(j -> new int[]{i, j}) + ) + .collect(toList()); + } + + @Test + public void findFirst() { + List someNumbers = Arrays.asList(1, 2, 3, 4, 5); + Optional firstSquareDivisibleByThree = + someNumbers.stream() + .map(x -> x * x) + .filter(x -> x % 3 == 0) + .findFirst(); // 9 + firstSquareDivisibleByThree.ifPresent(System.out::println); + } + + + @Test + public void StringNull() { + String a = null; + System.out.println((String) a); + } +} diff --git a/src/main/java/lambdasinaction/chap5/FlatMappingSample.java b/src/main/java/lambdasinaction/chap5/FlatMappingSample.java new file mode 100644 index 00000000..5bd6b0fe --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/FlatMappingSample.java @@ -0,0 +1,97 @@ +package lambdasinaction.chap5; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static junit.framework.TestCase.assertEquals; + +public class FlatMappingSample { + + @Test + public void test() { + Optional s = Optional.of("test"); + assertEquals(Optional.of("TEST"), s.map(String::toUpperCase)); + } + + @Test + public void streamTest() { + String[][] array = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}}; + + // array to a stream + Stream stream1 = Arrays.stream(array); + + // x is a String[] + List result = stream1 + .filter(x -> { + for(String s : x){ // really? + if(s.equals("a")){ + return false; + } + } + return true; + }).collect(Collectors.toList()); + + // print array + result.forEach(x -> System.out.println(Arrays.toString(x))); + } + + @Test + public void StreamNothing() { + String[][] array = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}}; + + // convert array to a stream + Stream stream1 = Arrays.stream(array); + + List result = stream1 + .filter(x -> !x.equals("a")) // x is a String[], not String! + .collect(Collectors.toList()); + + System.out.println(result.size()); // 0 + + result.forEach(System.out::println); // print nothing? + } + + @Test + public void flatMapTest() { + String[][] array = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}}; + + // Java 8 + String[] result = Stream.of(array) // Stream + .flatMap(Stream::of) // Stream + .toArray(String[]::new); // [a, b, c, d, e, f] + + for (String s : result) { + System.out.println(s); + } + + String[][] array02 = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}}; + + List collect = Stream.of(array02) // Stream + .flatMap(Stream::of) // Stream + .filter(x -> !"a".equals(x)) // filter out the a + .collect(Collectors.toList()); // return a List + + collect.forEach(System.out::println); + } + + @Test + public void mapTest() { + String[][] array = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}}; + + // Java 8 + String[] result = Stream.of(array) // Stream + .flatMap(Stream::of) // Stream + .toArray(String[]::new); // [a, b, c, d, e, f] + + for (String s : result) { + System.out.println(s); + } + } + + +} diff --git a/src/main/java/lambdasinaction/chap5/NumericStreams.java b/src/main/java/lambdasinaction/chap5/NumericStreams.java index e5f8cca8..63cd3dbe 100644 --- a/src/main/java/lambdasinaction/chap5/NumericStreams.java +++ b/src/main/java/lambdasinaction/chap5/NumericStreams.java @@ -34,19 +34,34 @@ public static void main(String...args){ } System.out.println(max); + max = maxCalories.orElse(1); + + System.out.println("orElse max: " + max); + // numeric ranges IntStream evenNumbers = IntStream.rangeClosed(1, 100) .filter(n -> n % 2 == 0); System.out.println(evenNumbers.count()); + IntStream oddNumbers = IntStream.range(1, 100).filter(n -> n %2 == 0); + System.out.println("The number of oddNumbers are: " + oddNumbers.count()); + + Stream pythagoreanTriples = IntStream.rangeClosed(1, 100).boxed() .flatMap(a -> IntStream.rangeClosed(a, 100) .filter(b -> Math.sqrt(a*a + b*b) % 1 == 0).boxed() - .map(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)})); + .map(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)})); + + pythagoreanTriples.limit(5).forEach(t -> System.out.println(t[0] + ", " + t[1] + ", " + t[2])); - pythagoreanTriples.forEach(t -> System.out.println(t[0] + ", " + t[1] + ", " + t[2])); + Stream pythagoreanTriplesOneSquare = + IntStream.rangeClosed(1, 100).boxed() + .flatMap(a -> IntStream.rangeClosed(a, 100) + .mapToObj(b -> new double[]{a, b, Math.sqrt(a * a + b * b)} ) + .filter(t -> t[2]%1 == 0)); + pythagoreanTriplesOneSquare.limit(5).forEach(t -> System.out.println(t[0] + ", " + t[1] + ", " + t[2])); } diff --git a/src/main/java/lambdasinaction/chap5/Reducing.java b/src/main/java/lambdasinaction/chap5/Reducing.java index 93aed73e..7f3a2281 100644 --- a/src/main/java/lambdasinaction/chap5/Reducing.java +++ b/src/main/java/lambdasinaction/chap5/Reducing.java @@ -27,5 +27,14 @@ public static void main(String...args){ .map(Dish::getCalories) .reduce(0, Integer::sum); System.out.println("Number of calories:" + calories); + + int caloriesMin = menu.stream() + .map(Dish::getCalories) + .reduce(10000, Integer::min); + System.out.println("Number of min calories:" + caloriesMin); + + int number = menu.stream().map(d -> 1).reduce(0, Integer::sum); + + System.out.println("Number of dishes: " + number); } } diff --git a/src/main/java/lambdasinaction/chap5/TraderTransactionPractise.java b/src/main/java/lambdasinaction/chap5/TraderTransactionPractise.java new file mode 100644 index 00000000..fba97e73 --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/TraderTransactionPractise.java @@ -0,0 +1,118 @@ +package lambdasinaction.chap5; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static java.util.Comparator.comparing; + +public class TraderTransactionPractise { + + 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) + ); + + //1. Find all transactions in the year 2011 and sort them by value (small to high). + List sortedTransactions = transactions.stream().filter(transaction -> transaction.getYear() == 2011) + .sorted(Comparator.comparingInt(Transaction::getValue)).collect(Collectors.toList()); + + sortedTransactions.forEach(System.out::println); + + //2. What are all the unique cities where the traders work? + List uniqueCities = transactions.stream().map(Transaction::getTrader).distinct() + .map(Trader::getCity).distinct().collect(Collectors.toList()); + + System.out.println(uniqueCities); + + //2.2 Optimize + List uniqueOptimizeCities = transactions.stream().map(transaction -> transaction.getTrader().getCity()).distinct() + .collect(Collectors.toList()); + System.out.println(uniqueOptimizeCities); + + //3. Find all traders from Cambridge and sort them by name. + List combridgeTraders= transactions.stream() + .filter(transaction -> transaction.getTrader().getCity().equals("Cambridge")) + .map(Transaction::getTrader).distinct().sorted(comparing(Trader::getName)) + .collect(Collectors.toList()); + System.out.println(combridgeTraders); + + //4. Return a string of all traders’ names sorted alphabetically + + String name = transactions.stream().map(transaction -> transaction.getTrader().getName()).distinct() + .sorted().reduce("", (s, s2) -> s + s2); + + System.out.println(name); + + //5. Are any traders based in Milan? + boolean isInMilan = transactions.stream().map(transaction -> transaction.getTrader().getCity()) + .anyMatch("Milan"::equals); + System.out.println("Are any traders based in Milan? : " + isInMilan); + + // Query 5: Are there any trader based in Milan? + + boolean milanBased = + transactions.stream() + .anyMatch(transaction -> transaction.getTrader() + .getCity() + .equals("Milan") + ); + System.out.println(milanBased); + + //6. Print all transactions’ values from the traders living in Cambridge. + transactions.stream().filter(transaction -> + transaction.getTrader().getCity().equals("Cambridge")).map(Transaction::getValue).forEach(System.out::println); + + + //7. What’s the highest value of all the transactions? + Integer highestValue = transactions.stream().map(Transaction::getValue) + .max(Comparator.comparingInt(o -> o)).get(); + System.out.println(highestValue); + + //Use reduce + highestValue = transactions.stream().map(Transaction::getValue) + .reduce(0, Integer::max); + System.out.println(highestValue); + + + //8. Find the transaction with the smallest value. + int smallestValue = transactions.stream().map(Transaction::getValue) + .min(Comparator.comparingInt(o -> o)).get(); + System.out.println(smallestValue); + Transaction smallestValueTransaction = transactions.stream().filter(transaction -> transaction.getValue() == smallestValue) + .findFirst().get(); + System.out.println(smallestValueTransaction); + + //Use reduce + smallestValueTransaction = transactions.stream() + .reduce(smallestValueTransaction, (transaction, transaction2) -> + { + if (transaction.getValue() > transaction2.getValue()) { + return transaction2; + } else { + return transaction; + } + }); + + System.out.println(smallestValueTransaction); + + //better + Optional smallestTransaction = + transactions.stream() + .min(comparing(Transaction::getValue)); + System.out.println(smallestTransaction.get()); + + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap5/developerflatmap/Developer.java b/src/main/java/lambdasinaction/chap5/developerflatmap/Developer.java new file mode 100644 index 00000000..769b4adf --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/developerflatmap/Developer.java @@ -0,0 +1,41 @@ +package lambdasinaction.chap5.developerflatmap; + +import java.util.HashSet; +import java.util.Set; + +public class Developer { + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + private String name; + + public Set getBook() { + return book; + } + + private Set book; + + //getters, setters, toString + + public void addBook(String book) { + if (this.book == null) { + this.book = new HashSet<>(); + } + this.book.add(book); + } +} diff --git a/src/main/java/lambdasinaction/chap5/developerflatmap/FlatMapExample1.java b/src/main/java/lambdasinaction/chap5/developerflatmap/FlatMapExample1.java new file mode 100644 index 00000000..1c96552f --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/developerflatmap/FlatMapExample1.java @@ -0,0 +1,46 @@ +package lambdasinaction.chap5.developerflatmap; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class FlatMapExample1 { + public static void main(String[] args) { + + Developer o1 = new Developer(); + o1.setName("mkyong"); + o1.addBook("Java 8 in Action"); + o1.addBook("Spring Boot in Action"); + o1.addBook("Effective Java (3nd Edition)"); + + Developer o2 = new Developer(); + o2.setName("zilap"); + o2.addBook("Learning Python, 5th Edition"); + o2.addBook("Effective Java (3nd Edition)"); + + List list = new ArrayList<>(); + list.add(o1); + list.add(o2); + + // hmm....Set of Set...how to process? + /*Set> collect = list.stream() + .map(x -> x.getBook()) + .collect(Collectors.toSet());*/ + Set> collect01 = list.stream() + .map(x -> x.getBook()) + .collect(Collectors.toSet()); + collect01.forEach(System.out::println); + + Set collect = + list.stream() + .map(x -> x.getBook()) // Stream> + .flatMap(x -> x.stream()) // Stream + .filter(x -> !x.toLowerCase().contains("python")) // filter python book + .collect(Collectors.toSet()); // remove duplicated + + collect.forEach(System.out::println); + + } + +} diff --git a/src/main/java/lambdasinaction/chap6/Grouping.java b/src/main/java/lambdasinaction/chap6/Grouping.java index 9105cc80..605eb05c 100644 --- a/src/main/java/lambdasinaction/chap6/Grouping.java +++ b/src/main/java/lambdasinaction/chap6/Grouping.java @@ -1,7 +1,9 @@ package lambdasinaction.chap6; import java.util.*; +import java.util.stream.Collectors; +import static java.util.Comparator.comparingInt; import static java.util.stream.Collectors.*; import static lambdasinaction.chap6.Dish.dishTags; import static lambdasinaction.chap6.Dish.menu; @@ -19,9 +21,11 @@ public static void main(String ... args) { System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel()); System.out.println("Count dishes in groups: " + countDishesInGroups()); System.out.println("Most caloric dishes by type: " + mostCaloricDishesByType()); - System.out.println("Most caloric dishes by type: " + mostCaloricDishesByTypeWithoutOprionals()); + System.out.println("Most caloric dishes by type: " + mostCaloricDishesByTypeWithoutOptionals()); System.out.println("Sum calories by type: " + sumCaloriesByType()); System.out.println("Caloric levels by type: " + caloricLevelsByType()); + System.out.println("Caloric levels by type: " + caloricLevelByDishType()); + System.out.println("Most caloric dishes by type without optional: " + mostCaloricDishesByTypeWithoutOptionals()); } private static Map> groupDishesByType() { @@ -72,7 +76,7 @@ private static Map> mostCaloricDishesByType() { reducing((Dish d1, Dish d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2))); } - private static Map mostCaloricDishesByTypeWithoutOprionals() { + private static Map mostCaloricDishesByTypeWithoutOptionals() { return menu.stream().collect( groupingBy(Dish::getType, collectingAndThen( @@ -93,4 +97,25 @@ private static Map> caloricLevelsByType() { else return CaloricLevel.FAT; }, toSet() ))); } + + private static Map> caloricLevelByDishType() { + return menu.stream().collect(groupingBy(Dish::getType, mapping(dish -> { + if (dish.getCalories() <=400) { + return CaloricLevel.DIET; + } else if (dish.getCalories() <= 700) { + return CaloricLevel.NORMAL; + } else { + return CaloricLevel.FAT; + } + }, Collectors.toCollection(HashSet::new)))); + } + + Map> mostCaloricByType = + menu.stream() + .collect(groupingBy(Dish::getType, + maxBy(comparingInt(Dish::getCalories)))); + + Map mostCaloriesByTypeOptional = + menu.stream().collect(groupingBy(Dish::getType, + Collectors.collectingAndThen(maxBy(comparingInt(Dish::getCalories)), Optional::get))); } diff --git a/src/main/java/lambdasinaction/chap6/Summarizing.java b/src/main/java/lambdasinaction/chap6/Summarizing.java index 06f9af6d..ac1555b5 100644 --- a/src/main/java/lambdasinaction/chap6/Summarizing.java +++ b/src/main/java/lambdasinaction/chap6/Summarizing.java @@ -17,6 +17,12 @@ public static void main(String ... args) { System.out.println("Menu statistics: " + calculateMenuStatistics()); System.out.println("Short menu: " + getShortMenu()); System.out.println("Short menu comma separated: " + getShortMenuCommaSeparated()); + + System.out.println("Scott max: + " + getMaxCalories()); + + System.out.println("Customized Collector" + menu.stream().collect(new ToListCollector())); + + System.out.println("Customized Collector" + menu.stream().collect(ArrayList::new, List::add, List::addAll)); } @@ -53,4 +59,12 @@ private static String getShortMenu() { private static String getShortMenuCommaSeparated() { return menu.stream().map(Dish::getName).collect(joining(", ")); } + + private static int getMaxCalories() { + Comparator dishCaloriesComparator = Comparator.comparingInt(Dish::getCalories); + Optional mostCalorisDish = menu.stream().collect(maxBy(dishCaloriesComparator)); + return mostCalorisDish.get().getCalories(); + + } + } diff --git a/src/main/java/lambdasinaction/chap6/ToListCollector.java b/src/main/java/lambdasinaction/chap6/ToListCollector.java index 0621d96a..442d929e 100644 --- a/src/main/java/lambdasinaction/chap6/ToListCollector.java +++ b/src/main/java/lambdasinaction/chap6/ToListCollector.java @@ -14,12 +14,14 @@ public Supplier> supplier() { @Override public BiConsumer, T> accumulator() { - return (list, item) -> list.add(item); + return (list, item) -> { + list.add(item); + }; } @Override public Function, List> finisher() { - return i -> i; + return Function.identity(); } @Override