├── src └── main │ ├── resources │ └── data.txt │ └── java │ └── mf │ └── java8ws │ ├── talk │ ├── example14 │ │ ├── Monoid.java │ │ ├── EndoMonoid.java │ │ ├── SalaryCalculator.java │ │ └── FluentEndoMonoid.java │ ├── example09 │ │ ├── ParallelStreamsWithSideEffect.java │ │ └── ParallelStreamsHarness.java │ ├── example02 │ │ └── Behavior.java │ ├── example01 │ │ └── InternalIteration.java │ ├── example07 │ │ ├── ParallelStreams.java │ │ └── ParallelStreamsHarness.java │ ├── example12 │ │ ├── Main.java │ │ └── Logger.java │ ├── example04 │ │ └── PrimeNumbers.java │ ├── example05 │ │ └── ReadFile.java │ ├── example06 │ │ ├── CollectorFeatures.java │ │ └── Dish.java │ ├── example11 │ │ └── LoanPattern.java │ ├── example08 │ │ └── Modularity.java │ ├── example10 │ │ └── OptionalTest.java │ ├── example13 │ │ ├── Discount.java │ │ ├── AsyncShopClient.java │ │ ├── BestPriceFinderMain.java │ │ ├── Shop.java │ │ ├── Quote.java │ │ ├── AsyncShop.java │ │ ├── Util.java │ │ └── BestPriceFinder.java │ └── example03 │ │ └── Lazy.java │ └── examples │ ├── example14 │ ├── Monoid.java │ ├── EndoMonoid.java │ ├── FluentEndoMonoid.java │ └── SalaryCalculator.java │ ├── example01 │ └── InternalIteration.java │ ├── example12 │ ├── Main.java │ └── Logger.java │ ├── example09 │ ├── ParallelStreamsHarness.java │ └── ParallelStreamsWithSideEffect.java │ ├── example02 │ └── Behavior.java │ ├── example07 │ ├── ParallelStreams.java │ └── ParallelStreamsHarness.java │ ├── example13 │ ├── Discount.java │ ├── AsyncShopClient.java │ ├── BestPriceFinderMain.java │ ├── Shop.java │ ├── Quote.java │ ├── Util.java │ ├── AsyncShop.java │ └── BestPriceFinder.java │ ├── example05 │ └── ReadFile.java │ ├── example11 │ └── LoanPattern.java │ ├── example06 │ ├── CollectorFeatures.java │ └── Dish.java │ ├── example04 │ └── PrimeNumbers.java │ ├── example10 │ └── OptionalTest.java │ ├── example08 │ └── Modularity.java │ └── example03 │ └── Lazy.java ├── .gitignore └── pom.xml /src/main/resources/data.txt: -------------------------------------------------------------------------------- 1 | The next sentence is true 2 | The former sentence is false -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example14/Monoid.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example14; 2 | 3 | import java.util.function.*; 4 | 5 | public interface Monoid extends BinaryOperator { 6 | 7 | A zero(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example14/Monoid.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example14; 2 | 3 | import java.util.function.*; 4 | 5 | public interface Monoid extends BinaryOperator { 6 | 7 | A zero(); 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /local 3 | 4 | # Eclipse, Netbeans and IntelliJ files 5 | /.* 6 | !.gitignore 7 | /nbproject 8 | /*.ipr 9 | /*.iws 10 | /*.iml 11 | 12 | # Repository wide ignore mac DS_Store files 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example09/ParallelStreamsWithSideEffect.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example09; 2 | 3 | public class ParallelStreamsWithSideEffect { 4 | 5 | public static String sideEffectConcat(int n) { 6 | return ""; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example02/Behavior.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example02; 2 | 3 | import java.util.*; 4 | 5 | public class Behavior { 6 | 7 | public static void main(String... args) { 8 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example01/InternalIteration.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example01; 2 | 3 | import java.util.*; 4 | 5 | public class InternalIteration { 6 | 7 | public static void main(String... args) { 8 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example07/ParallelStreams.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example07; 2 | 3 | public class ParallelStreams { 4 | 5 | public static long sequentialSum(long n) { 6 | return 0L; 7 | } 8 | 9 | public static long parallelSum(long n) { 10 | return 0L; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example01/InternalIteration.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example01; 2 | 3 | import java.util.*; 4 | 5 | public class InternalIteration { 6 | 7 | public static void main(String... args) { 8 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 9 | 10 | numbers.forEach(System.out::println); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example12/Main.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example12; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | Logger logger = new Logger(Logger.Level.WARN); 7 | logger.log(Logger.Level.ERROR, "this is a critical error"); 8 | logger.log(Logger.Level.INFO, "this is just a info"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example12/Main.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example12; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | Logger logger = new Logger(Logger.Level.WARN); 7 | logger.log(Logger.Level.ERROR, () -> "this is a critical error"); 8 | logger.log(Logger.Level.INFO, () -> "this is just a info"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example09/ParallelStreamsHarness.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example09; 2 | 3 | import java.util.concurrent.ForkJoinPool; 4 | 5 | public class ParallelStreamsHarness { 6 | 7 | public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool(); 8 | 9 | public static void main(String[] args) { 10 | System.out.println(ParallelStreamsWithSideEffect.sideEffectConcat(100)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example04/PrimeNumbers.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example04; 2 | 3 | /** 4 | * Find all pair i, j such as: 5 | * - 0 < i <= j <= 20 6 | * - i + j is prime 7 | */ 8 | public class PrimeNumbers { 9 | 10 | public static final int LIMIT = 20; 11 | 12 | public static void main(String[] args) { 13 | } 14 | 15 | public static boolean isPrime(int n) { 16 | return false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example05/ReadFile.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example05; 2 | 3 | public class ReadFile { 4 | 5 | public static void main(String[] args) { 6 | long uniqueWords = calculateUniqueWords("src/main/resources/data.txt"); 7 | System.out.println("Unique words in file: " + uniqueWords); 8 | } 9 | 10 | private static long calculateUniqueWords(String fileName) { 11 | return 0; 12 | } 13 | } -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example14/EndoMonoid.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example14; 2 | 3 | import java.util.function.*; 4 | 5 | public interface EndoMonoid extends Monoid> { 6 | 7 | @Override 8 | default UnaryOperator apply(UnaryOperator a1, UnaryOperator a2) { 9 | return (A a) -> a2.apply(a1.apply(a)); 10 | } 11 | 12 | @Override 13 | default UnaryOperator zero() { 14 | return a -> a; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example14/EndoMonoid.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example14; 2 | 3 | import java.util.function.*; 4 | 5 | public interface EndoMonoid extends Monoid> { 6 | 7 | @Override 8 | default UnaryOperator apply(UnaryOperator a1, UnaryOperator a2) { 9 | return (A a) -> a2.apply(a1.apply(a)); 10 | } 11 | 12 | @Override 13 | default UnaryOperator zero() { 14 | return a -> a; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example09/ParallelStreamsHarness.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example09; 2 | 3 | public class ParallelStreamsHarness { 4 | 5 | public static void main(String[] args) { 6 | System.out.println(ParallelStreamsWithSideEffect.sideEffectConcat(100)); 7 | System.out.println(ParallelStreamsWithSideEffect.sideEffectParallelConcat(100)); 8 | System.out.println(ParallelStreamsWithSideEffect.parallelConcat(100)); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example12/Logger.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example12; 2 | 3 | public class Logger { 4 | public enum Level { 5 | ERROR, WARN, INFO, DEBUG 6 | } 7 | 8 | private final Level level; 9 | 10 | public Logger(Level level) { 11 | this.level = level; 12 | } 13 | 14 | public void log(Level level, String message) { 15 | if (isLoggable(level)) { 16 | System.out.println(message); 17 | } 18 | } 19 | 20 | public boolean isLoggable(Level level) { 21 | return this.level.compareTo(level) >= 0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example06/CollectorFeatures.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example06; 2 | 3 | import java.util.*; 4 | 5 | public class CollectorFeatures { 6 | 7 | public static void main(String... args) { 8 | System.out.println("Dishes grouped by type: " + groupDishesByType()); 9 | System.out.println("Most caloric Dish by type: " + mostCaloricDishByType()); 10 | } 11 | 12 | private static Map> groupDishesByType() { 13 | return null; 14 | } 15 | 16 | private static Map> mostCaloricDishByType() { 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example11/LoanPattern.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example11; 2 | 3 | public class LoanPattern { 4 | 5 | public static class Resource { 6 | 7 | private Resource() { 8 | System.out.println("Opening resource"); 9 | } 10 | 11 | public void operate() { 12 | System.out.println("Operating on resource"); 13 | throw new RuntimeException(); 14 | } 15 | 16 | public void dispose() { 17 | System.out.println("Disposing resource"); 18 | } 19 | 20 | } 21 | 22 | public static void main(String... args) { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example02/Behavior.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example02; 2 | 3 | import java.util.*; 4 | import java.util.function.*; 5 | 6 | public class Behavior { 7 | 8 | public static int sum(List numbers, Predicate p) { 9 | int total = 0; 10 | for (int n : numbers) { 11 | if (p.test(n)) { 12 | total += n; 13 | } 14 | } 15 | return total; 16 | } 17 | 18 | public static void main(String... args) { 19 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 20 | 21 | System.out.println(sum(numbers, n -> true)); 22 | System.out.println(sum(numbers, n -> n % 2 == 0)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example08/Modularity.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example08; 2 | 3 | import mf.java8ws.talk.example06.*; 4 | 5 | public class Modularity { 6 | 7 | public static void main(String[] args) { 8 | Dish d1 = new Dish("chicken", false, 400, Dish.Type.MEAT); 9 | Dish d2 = new Dish("beef", false, 700, Dish.Type.MEAT); 10 | lightest(d1, d2); 11 | 12 | } 13 | 14 | public static Dish declareLightest(Dish d) { 15 | System.out.println(d + " is the lightest dish"); 16 | return d; 17 | } 18 | 19 | public static Dish lightest(Dish d1, Dish d2) { 20 | if (d1.getCalories() < d2.getCalories()) return declareLightest(d1); 21 | else return declareLightest(d2); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example07/ParallelStreams.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example07; 2 | 3 | import java.util.stream.*; 4 | 5 | public class ParallelStreams { 6 | 7 | public static long sequentialSum(long n) { 8 | return Stream.iterate(1L, i -> i + 1).limit(n).reduce(Long::sum).get(); 9 | } 10 | 11 | public static long parallelSum(long n) { 12 | return Stream.iterate(1L, i -> i + 1).limit(n).parallel().reduce(Long::sum).get(); 13 | } 14 | 15 | public static long rangedSum(long n) { 16 | return LongStream.rangeClosed(1, n).reduce(Long::sum).getAsLong(); 17 | } 18 | 19 | public static long parallelRangedSum(long n) { 20 | return LongStream.rangeClosed(1, n).parallel().reduce(Long::sum).getAsLong(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example10/OptionalTest.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example10; 2 | 3 | import org.junit.*; 4 | 5 | import java.util.*; 6 | 7 | import static org.junit.Assert.*; 8 | 9 | public class OptionalTest { 10 | 11 | @Test 12 | public void testMap() { 13 | Map param = new HashMap(); 14 | param.put("a", "5"); 15 | param.put("b", "true"); 16 | param.put("c", "-3"); 17 | 18 | assertEquals(5, readDuration(param, "a")); 19 | assertEquals(0, readDuration(param, "b")); 20 | assertEquals(0, readDuration(param, "c")); 21 | assertEquals(0, readDuration(param, "d")); 22 | } 23 | 24 | public int readDuration(Map params, String name) { 25 | return 0; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example12/Logger.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example12; 2 | 3 | import java.util.function.Supplier; 4 | 5 | public class Logger { 6 | public enum Level { 7 | ERROR, WARN, INFO, DEBUG 8 | } 9 | 10 | private final Level level; 11 | 12 | public Logger(Level level) { 13 | this.level = level; 14 | } 15 | 16 | public void log(Level level, String message) { 17 | if (isLoggable(level)) { 18 | System.out.println(message); 19 | } 20 | } 21 | 22 | public boolean isLoggable(Level level) { 23 | return this.level.compareTo(level) >= 0; 24 | } 25 | 26 | public void log(Level level, Supplier message) { 27 | if (isLoggable(level)) { 28 | System.out.println(message.get()); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example13/Discount.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example13; 2 | 3 | import static mf.java8ws.examples.example13.Util.delay; 4 | import static mf.java8ws.examples.example13.Util.format; 5 | 6 | public class Discount { 7 | 8 | public enum Code { 9 | NONE(0), SILVER(5), GOLD(10), PLATINUM(15), DIAMOND(20); 10 | 11 | private final int percentage; 12 | 13 | Code(int percentage) { 14 | this.percentage = percentage; 15 | } 16 | } 17 | 18 | public static String applyDiscount(Quote quote) { 19 | return quote.getShopName() + " price is " + Discount.apply(quote.getPrice(), quote.getDiscountCode()); 20 | } 21 | private static double apply(double price, Code code) { 22 | delay(); 23 | return format(price * (100 - code.percentage) / 100); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example13/Discount.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example13; 2 | 3 | import static mf.java8ws.examples.example13.Util.delay; 4 | import static mf.java8ws.examples.example13.Util.format; 5 | 6 | public class Discount { 7 | 8 | public enum Code { 9 | NONE(0), SILVER(5), GOLD(10), PLATINUM(15), DIAMOND(20); 10 | 11 | private final int percentage; 12 | 13 | Code(int percentage) { 14 | this.percentage = percentage; 15 | } 16 | } 17 | 18 | public static String applyDiscount(Quote quote) { 19 | return quote.getShopName() + " price is " + Discount.apply(quote.getPrice(), quote.getDiscountCode()); 20 | } 21 | 22 | private static double apply(double price, Code code) { 23 | delay(); 24 | return format(price * (100 - code.percentage) / 100); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example05/ReadFile.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example05; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Paths; 6 | import java.util.stream.Stream; 7 | 8 | public class ReadFile { 9 | 10 | public static void main(String[] args) { 11 | long uniqueWords = calculateUniqueWords("src/main/resources/data.txt"); 12 | System.out.println("Unique words in file: " + uniqueWords); 13 | } 14 | 15 | private static long calculateUniqueWords(String fileName) { 16 | try (Stream stream = Files.lines(Paths.get(fileName))) { 17 | return stream.flatMap(line -> Stream.of(line.split(" "))) 18 | .distinct() 19 | .count(); 20 | } catch (IOException e) { 21 | throw new RuntimeException(e); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example13/AsyncShopClient.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example13; 2 | 3 | import java.util.concurrent.Future; 4 | 5 | public class AsyncShopClient { 6 | 7 | public static void main(String[] args) { 8 | AsyncShop shop = new AsyncShop("BestShop"); 9 | long start = System.nanoTime(); 10 | Future futurePrice = shop.getPriceFor("myPhone"); 11 | long incocationTime = ((System.nanoTime() - start) / 1_000_000); 12 | System.out.println("Invocation returned after " + incocationTime + " msecs"); 13 | try { 14 | System.out.println("Price is " + futurePrice.get()); 15 | } catch (Exception e) { 16 | throw new RuntimeException(e); 17 | } 18 | long retrivalTime = ((System.nanoTime() - start) / 1_000_000); 19 | System.out.println("Price returned after " + retrivalTime + " msecs"); 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example09/ParallelStreamsWithSideEffect.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example09; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | public class ParallelStreamsWithSideEffect { 6 | 7 | public static String sideEffectConcat(int n) { 8 | StringBuilder sb = new StringBuilder(); 9 | IntStream.rangeClosed(1, n).mapToObj(i -> i + " ").forEach(sb::append); 10 | return sb.toString(); 11 | } 12 | 13 | public static String sideEffectParallelConcat(int n) { 14 | StringBuilder sb = new StringBuilder(); 15 | IntStream.rangeClosed(1, n).parallel().mapToObj(i -> i + " ").forEach(sb::append); 16 | return sb.toString(); 17 | } 18 | 19 | public static String parallelConcat(int n) { 20 | return IntStream.rangeClosed(1, n).parallel() 21 | .mapToObj(i -> i + " ").reduce("", (a, b) -> a+b); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example13/AsyncShopClient.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example13; 2 | 3 | import java.util.concurrent.Future; 4 | 5 | public class AsyncShopClient { 6 | 7 | public static void main(String[] args) { 8 | AsyncShop shop = new AsyncShop("BestShop"); 9 | long start = System.nanoTime(); 10 | Future futurePrice = shop.getPriceFor("myPhone27"); 11 | long incocationTime = ((System.nanoTime() - start) / 1_000_000); 12 | System.out.println("Invocation returned after " + incocationTime + " msecs"); 13 | try { 14 | System.out.println("Price is " + futurePrice.get()); 15 | } catch (Exception e) { 16 | throw new RuntimeException(e); 17 | } 18 | long retrivalTime = ((System.nanoTime() - start) / 1_000_000); 19 | System.out.println("Price returned after " + retrivalTime + " msecs"); 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example14/SalaryCalculator.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example14; 2 | 3 | public class SalaryCalculator { 4 | 5 | // B = basic + 20% 6 | public double plusAllowance(double d) { 7 | return d * 1.2; 8 | } 9 | 10 | // C = B + 10% 11 | public double plusBonus(double d) { 12 | return d * 1.1; 13 | } 14 | 15 | // D = C - 30% 16 | public double plusTax(double d) { 17 | return d * 0.7; 18 | } 19 | 20 | // E = D - 10% 21 | public double plusSurcharge(double d) { 22 | return d * 0.9; 23 | } 24 | 25 | public double calculateImperative(double basic, boolean... bs) { 26 | double salary = basic; 27 | if (bs[0]) salary = plusAllowance(salary); 28 | if (bs[1]) salary = plusBonus(salary); 29 | if (bs[2]) salary = plusTax(salary); 30 | if (bs[3]) salary = plusSurcharge(salary); 31 | return salary; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example13/BestPriceFinderMain.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example13; 2 | 3 | import java.util.List; 4 | import java.util.function.Supplier; 5 | 6 | public class BestPriceFinderMain { 7 | 8 | private static BestPriceFinder bestPriceFinder = new BestPriceFinder(); 9 | 10 | public static void main(String[] args) { 11 | execute("sequential", () -> bestPriceFinder.findPriceSequential("myPhone")); 12 | execute("parallel", () -> bestPriceFinder.findPriceParallel("myPhone")); 13 | execute("composed CompletableFuture", () -> bestPriceFinder.findPrice("myPhone")); 14 | //bestPriceFinder.printPricesStream(); 15 | } 16 | 17 | private static void execute(String msg, Supplier> s) { 18 | long start = System.nanoTime(); 19 | System.out.println(s.get()); 20 | long duration = (System.nanoTime() - start) / 1_000_000; 21 | System.out.println(msg + " done in " + duration + " msecs"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example03/Lazy.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example03; 2 | 3 | import java.util.*; 4 | 5 | public class Lazy { 6 | 7 | public static void main(String... args) { 8 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 9 | 10 | // Take only the even numbers, double them and print 11 | // the first one bigger than 5 12 | 13 | } 14 | } 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | /* 35 | List l1 = new ArrayList(); 36 | for (int n : numbers) { 37 | if (isEven(n)) l1.add(n); 38 | } 39 | 40 | List l2 = new ArrayList(); 41 | for (int n : l1) { 42 | l2.add(doubleIt(n)); 43 | } 44 | 45 | List l3 = new ArrayList(); 46 | for (int n : l2) { 47 | if (isGT5(n)) l3.add(n); 48 | } 49 | 50 | System.out.println(l3.get(0)); 51 | */ -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example11/LoanPattern.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example11; 2 | 3 | import java.util.function.*; 4 | 5 | public class LoanPattern { 6 | 7 | public static class Resource { 8 | 9 | private Resource() { 10 | System.out.println("Opening resource"); 11 | } 12 | 13 | public void operate() { 14 | System.out.println("Operating on resource"); 15 | throw new RuntimeException(); 16 | } 17 | 18 | public void dispose() { 19 | System.out.println("Disposing resource"); 20 | } 21 | 22 | public static void withResource(Consumer consumer) { 23 | Resource r = new Resource(); 24 | try { 25 | consumer.accept(r); 26 | } finally { 27 | r.dispose(); 28 | } 29 | } 30 | } 31 | 32 | public static void main(String... args) { 33 | Resource.withResource(r -> r.operate()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example13/BestPriceFinderMain.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example13; 2 | 3 | import java.util.List; 4 | import java.util.function.Supplier; 5 | 6 | public class BestPriceFinderMain { 7 | 8 | private static BestPriceFinder bestPriceFinder = new BestPriceFinder(); 9 | 10 | public static void main(String[] args) { 11 | 12 | execute("sequential", () -> bestPriceFinder.findPriceSequential("myPhone27")); 13 | execute("parallel", () -> bestPriceFinder.findPriceParallel("myPhone27")); 14 | execute("composed CompletableFuture", () -> bestPriceFinder.findPrice("myPhone27")); 15 | 16 | // bestPriceFinder.printPricesStream("myPhone27"); 17 | } 18 | 19 | private static void execute(String msg, Supplier> s) { 20 | long start = System.nanoTime(); 21 | System.out.println(s.get()); 22 | long duration = (System.nanoTime() - start) / 1_000_000; 23 | System.out.println(msg + " done in " + duration + " msecs"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example13/Shop.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example13; 2 | 3 | import java.util.Random; 4 | 5 | import static mf.java8ws.talk.example13.Util.delay; 6 | import static mf.java8ws.talk.example13.Util.format; 7 | 8 | public class Shop { 9 | 10 | private final String name; 11 | private final Random random; 12 | 13 | public Shop(String name) { 14 | this.name = name; 15 | random = new Random(name.charAt(0) * name.charAt(1) * name.charAt(2)); 16 | } 17 | 18 | public double getPriceFor(String product) { 19 | delay(); 20 | return format(random.nextDouble() * product.charAt(0) + product.charAt(1)); 21 | } 22 | 23 | public String getDiscountedPriceFor(String product) { 24 | double price = getPriceFor(product); 25 | Discount.Code code = Discount.Code.values()[random.nextInt(Discount.Code.values().length)]; 26 | return name + ":" + price + ":" + code; 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example06/CollectorFeatures.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example06; 2 | 3 | import java.util.*; 4 | import java.util.function.*; 5 | 6 | import static java.util.Comparator.*; 7 | import static java.util.stream.Collectors.*; 8 | import static mf.java8ws.examples.example06.Dish.menu; 9 | 10 | public class CollectorFeatures { 11 | 12 | public static void main(String... args) { 13 | System.out.println("Dishes grouped by type: " + groupDishesByType()); 14 | System.out.println("Most caloric Dish by type: " + mostCaloricDishByType()); 15 | } 16 | 17 | private static Map> groupDishesByType() { 18 | return menu.stream().collect(groupingBy(Dish::getType)); 19 | } 20 | 21 | private static Map mostCaloricDishByType() { 22 | return menu.stream().collect(groupingBy(Dish::getType, 23 | collectingAndThen( 24 | reducing(BinaryOperator.maxBy(comparingInt(Dish::getCalories))), Optional::get))); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example13/Shop.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example13; 2 | 3 | import java.util.Random; 4 | 5 | import static mf.java8ws.examples.example13.Util.delay; 6 | import static mf.java8ws.examples.example13.Util.format; 7 | 8 | public class Shop { 9 | 10 | private final String name; 11 | private final Random random; 12 | 13 | public Shop(String name) { 14 | this.name = name; 15 | random = new Random(name.charAt(0) * name.charAt(1) * name.charAt(2)); 16 | } 17 | 18 | public String getDiscountedPriceFor(String product) { 19 | double price = getPriceFor(product); 20 | Discount.Code code = Discount.Code.values()[random.nextInt(Discount.Code.values().length)]; 21 | return name + ":" + price + ":" + code; 22 | } 23 | 24 | public double getPriceFor(String product) { 25 | delay(); 26 | return format(random.nextDouble() * product.charAt(0) + product.charAt(1)); 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example13/Quote.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example13; 2 | 3 | public class Quote { 4 | 5 | private final String shopName; 6 | private final double price; 7 | private final Discount.Code discountCode; 8 | 9 | public Quote(String shopName, double price, Discount.Code discountCode) { 10 | this.shopName = shopName; 11 | this.price = price; 12 | this.discountCode = discountCode; 13 | } 14 | 15 | public static Quote parse(String s) { 16 | String[] split = s.split(":"); 17 | String shopName = split[0]; 18 | double price = Double.parseDouble(split[1]); 19 | Discount.Code discountCode = Discount.Code.valueOf(split[2]); 20 | return new Quote(shopName, price, discountCode); 21 | } 22 | 23 | public String getShopName() { 24 | return shopName; 25 | } 26 | 27 | public double getPrice() { 28 | return price; 29 | } 30 | 31 | public Discount.Code getDiscountCode() { 32 | return discountCode; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example13/Quote.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example13; 2 | 3 | public class Quote { 4 | 5 | private final String shopName; 6 | private final double price; 7 | private final Discount.Code discountCode; 8 | 9 | public Quote(String shopName, double price, Discount.Code discountCode) { 10 | this.shopName = shopName; 11 | this.price = price; 12 | this.discountCode = discountCode; 13 | } 14 | 15 | public static Quote parse(String s) { 16 | String[] split = s.split(":"); 17 | String shopName = split[0]; 18 | double price = Double.parseDouble(split[1]); 19 | Discount.Code discountCode = Discount.Code.valueOf(split[2]); 20 | return new Quote(shopName, price, discountCode); 21 | } 22 | 23 | public String getShopName() { 24 | return shopName; 25 | } 26 | 27 | public double getPrice() { 28 | return price; 29 | } 30 | 31 | public Discount.Code getDiscountCode() { 32 | return discountCode; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example14/FluentEndoMonoid.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example14; 2 | 3 | import java.util.function.*; 4 | 5 | public class FluentEndoMonoid implements EndoMonoid { 6 | private final UnaryOperator endo; 7 | 8 | 9 | public FluentEndoMonoid(UnaryOperator endo) { 10 | this.endo = endo; 11 | } 12 | 13 | public FluentEndoMonoid(UnaryOperator endo, boolean b) { 14 | this.endo = b ? endo : zero(); 15 | } 16 | 17 | public FluentEndoMonoid add(UnaryOperator other) { 18 | return new FluentEndoMonoid(apply(endo, other)); 19 | } 20 | 21 | public FluentEndoMonoid add(UnaryOperator other, boolean b) { 22 | return add(b ? other : zero()); 23 | } 24 | 25 | public UnaryOperator get() { 26 | return endo; 27 | } 28 | 29 | public static FluentEndoMonoid endo(UnaryOperator f) { 30 | return new FluentEndoMonoid(f); 31 | } 32 | 33 | public static FluentEndoMonoid endo(UnaryOperator f, boolean b) { 34 | return new FluentEndoMonoid(f, b); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example14/FluentEndoMonoid.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example14; 2 | 3 | import java.util.function.*; 4 | 5 | public class FluentEndoMonoid implements EndoMonoid { 6 | private final UnaryOperator endo; 7 | 8 | 9 | public FluentEndoMonoid(UnaryOperator endo) { 10 | this.endo = endo; 11 | } 12 | 13 | public FluentEndoMonoid(UnaryOperator endo, boolean b) { 14 | this.endo = b ? endo : zero(); 15 | } 16 | 17 | public FluentEndoMonoid add(UnaryOperator other) { 18 | return new FluentEndoMonoid(apply(endo, other)); 19 | } 20 | 21 | public FluentEndoMonoid add(UnaryOperator other, boolean b) { 22 | return add(b ? other : zero()); 23 | } 24 | 25 | public UnaryOperator get() { 26 | return endo; 27 | } 28 | 29 | public static FluentEndoMonoid endo(UnaryOperator f) { 30 | return new FluentEndoMonoid(f); 31 | } 32 | 33 | public static FluentEndoMonoid endo(UnaryOperator f, boolean b) { 34 | return new FluentEndoMonoid(f, b); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example04/PrimeNumbers.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example04; 2 | 3 | import java.util.*; 4 | import java.util.stream.*; 5 | 6 | import static java.util.stream.Collectors.toList; 7 | 8 | /** 9 | * Find all pair i, j such as: 10 | * - 0 < i <= j <= 20 11 | * - i + j is prime 12 | */ 13 | public class PrimeNumbers { 14 | 15 | public static final int LIMIT = 20; 16 | 17 | public static void main(String[] args) { 18 | System.out.println( 19 | IntStream.rangeClosed(1, LIMIT) 20 | .boxed() 21 | .flatMap(i -> IntStream.rangeClosed(1, i) 22 | .mapToObj(j -> new int[]{i, j})) 23 | .peek(a -> System.out.println(Arrays.toString(a))) 24 | .filter(a -> isPrime(a[0] + a[1])) 25 | .map(Arrays::toString) 26 | .collect(toList()) 27 | ); 28 | } 29 | 30 | public static boolean isPrime(int n) { 31 | return IntStream.rangeClosed(2, (int)Math.sqrt(n)).noneMatch(i -> n % i == 0); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.mf 8 | Java8WS 9 | 1.0-SNAPSHOT 10 | 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.11 20 | 21 | 22 | 23 | 24 | 25 | 26 | org.apache.maven.plugins 27 | maven-compiler-plugin 28 | 3.1 29 | 30 | 1.8 31 | 1.8 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example10/OptionalTest.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example10; 2 | 3 | import org.junit.*; 4 | 5 | import java.util.*; 6 | 7 | import static java.util.Optional.*; 8 | import static org.junit.Assert.*; 9 | 10 | public class OptionalTest { 11 | 12 | @Test 13 | public void testMap() { 14 | Map param = new HashMap(); 15 | param.put("a", "5"); 16 | param.put("b", "true"); 17 | param.put("c", "-3"); 18 | 19 | assertEquals(5, readDuration(param, "a")); 20 | assertEquals(0, readDuration(param, "b")); 21 | assertEquals(0, readDuration(param, "c")); 22 | assertEquals(0, readDuration(param, "d")); 23 | } 24 | 25 | public int readDuration(Map params, String name) { 26 | return ofNullable(params.get(name)) 27 | .flatMap(OptionalTest::s2i) 28 | .filter(i -> i > 0).orElse(0); 29 | } 30 | 31 | public static Optional s2i(String s) { 32 | try { 33 | return of(Integer.parseInt(s)); 34 | } catch (NumberFormatException e) { 35 | return empty(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example08/Modularity.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example08; 2 | 3 | import mf.java8ws.examples.example06.*; 4 | 5 | import static mf.java8ws.examples.example06.Dish.menu; 6 | 7 | public class Modularity { 8 | 9 | public static void main(java.lang.String[] args) { 10 | Dish d1 = new Dish("chicken", false, 400, Dish.Type.MEAT); 11 | Dish d2 = new Dish("beef", false, 700, Dish.Type.MEAT); 12 | lightest(d1, d2); 13 | 14 | System.out.println("Lighetst dish in menu is: " + 15 | menu.stream().reduce(Modularity::lightest).get() 16 | ); 17 | 18 | declareLightest(minCalories(d1, d2)); 19 | System.out.println("Lighetst dish in menu is: " + 20 | menu.stream().reduce(Modularity::minCalories).get() 21 | ); 22 | } 23 | 24 | public static Dish declareLightest(Dish d) { 25 | System.out.println(d + " is the lightest dish"); 26 | return d; 27 | } 28 | 29 | public static Dish lightest(Dish d1, Dish d2) { 30 | if (d1.getCalories() < d2.getCalories()) return declareLightest(d1); 31 | else return declareLightest(d2); 32 | } 33 | 34 | public static Dish minCalories(Dish d1, Dish d2) { 35 | if (d1.getCalories() < d2.getCalories()) return d1; 36 | else return d2; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example14/SalaryCalculator.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example14; 2 | 3 | import static mf.java8ws.examples.example14.FluentEndoMonoid.endo; 4 | 5 | public class SalaryCalculator { 6 | 7 | // B = basic + 20% 8 | public double plusAllowance(double d) { 9 | return d * 1.2; 10 | } 11 | 12 | // C = B + 10% 13 | public double plusBonus(double d) { 14 | return d * 1.1; 15 | } 16 | 17 | // D = C - 30% 18 | public double plusTax(double d) { 19 | return d * 0.7; 20 | } 21 | 22 | // E = D - 10% 23 | public double plusSurcharge(double d) { 24 | return d * 0.9; 25 | } 26 | 27 | public double calculateImperative(double basic, boolean... bs) { 28 | double salary = basic; 29 | if (bs[0]) salary = plusAllowance(salary); 30 | if (bs[1]) salary = plusBonus(salary); 31 | if (bs[2]) salary = plusTax(salary); 32 | if (bs[3]) salary = plusSurcharge(salary); 33 | return salary; 34 | } 35 | 36 | public double calculate(double basic, boolean... bs) { 37 | return endo(this::plusAllowance, bs[0]) 38 | .add(this::plusBonus, bs[1]) 39 | .add(this::plusTax, bs[2]) 40 | .add(this::plusSurcharge, bs[3]) 41 | .get() 42 | .apply(basic); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example07/ParallelStreamsHarness.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example07; 2 | 3 | import java.util.concurrent.*; 4 | import java.util.function.*; 5 | 6 | public class ParallelStreamsHarness { 7 | 8 | public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool(); 9 | 10 | public static void main(String[] args) { 11 | System.out.println("Sequential Sum done in: " + measurePerf(ParallelStreams::sequentialSum, 10_000_000L) + " msecs"); 12 | System.out.println("Parallel Sum done in: " + measurePerf(ParallelStreams::parallelSum, 10_000_000L) + " msecs"); 13 | //System.out.println("Sequential ranged sum done in: " + measurePerf(ParallelStreams::rangedSum, 10_000_000L) + " msecs" ); 14 | //System.out.println("Parallel ranged sum done in: " + measurePerf(ParallelStreams::parallelRangedSum, 10_000_000L) + " msecs" ); 15 | } 16 | 17 | public static long measurePerf(Function f, T input) { 18 | long fastest = Long.MAX_VALUE; 19 | for (int i = 0; i < 10; i++) { 20 | long start = System.nanoTime(); 21 | R result = f.apply(input); 22 | long duration = (System.nanoTime() - start) / 1_000_000; 23 | System.out.println("Result: " + result); 24 | if (duration < fastest) fastest = duration; 25 | } 26 | return fastest; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example07/ParallelStreamsHarness.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example07; 2 | 3 | import java.util.concurrent.*; 4 | import java.util.function.*; 5 | 6 | public class ParallelStreamsHarness { 7 | 8 | public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool(); 9 | 10 | public static void main(String[] args) { 11 | System.out.println("Sequential Sum done in: " + measurePerf(ParallelStreams::sequentialSum, 10_000_000L) + " msecs"); 12 | System.out.println("Parallel Sum done in: " + measurePerf(ParallelStreams::parallelSum, 10_000_000L) + " msecs"); 13 | System.out.println("Sequential ranged sum done in: " + measurePerf(ParallelStreams::rangedSum, 10_000_000L) + " msecs" ); 14 | System.out.println("Parallel ranged sum done in: " + measurePerf(ParallelStreams::parallelRangedSum, 10_000_000L) + " msecs" ); 15 | } 16 | 17 | public static long measurePerf(Function f, T input) { 18 | long fastest = Long.MAX_VALUE; 19 | for (int i = 0; i < 10; i++) { 20 | long start = System.nanoTime(); 21 | R result = f.apply(input); 22 | long duration = (System.nanoTime() - start) / 1_000_000; 23 | System.out.println("Result: " + result); 24 | if (duration < fastest) fastest = duration; 25 | } 26 | return fastest; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example13/AsyncShop.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example13; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.CompletableFuture; 5 | import java.util.concurrent.Future; 6 | 7 | import static mf.java8ws.examples.example13.Util.delay; 8 | import static mf.java8ws.examples.example13.Util.format; 9 | 10 | public class AsyncShop { 11 | 12 | private final String name; 13 | private final Random random; 14 | 15 | public AsyncShop(String name) { 16 | this.name = name; 17 | random = new Random(name.charAt(0) * name.charAt(1) * name.charAt(2)); 18 | } 19 | 20 | public Future getPriceFor(String product) { 21 | CompletableFuture futurePrice = new CompletableFuture<>(); 22 | new Thread( () -> { 23 | try { 24 | double price = calculatePrice(product); 25 | futurePrice.complete(price); 26 | } catch (Exception ex) { 27 | futurePrice.completeExceptionally(ex); 28 | } 29 | }).start(); 30 | return futurePrice; 31 | } 32 | 33 | private double calculatePrice(String product) { 34 | delay(); 35 | // if (true) throw new RuntimeException("product not available"); 36 | return format(random.nextDouble() * product.charAt(0) + product.charAt(1)); 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example13/Util.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example13; 2 | 3 | import java.text.DecimalFormat; 4 | import java.text.DecimalFormatSymbols; 5 | import java.util.List; 6 | import java.util.Locale; 7 | import java.util.Random; 8 | import java.util.concurrent.CompletableFuture; 9 | import java.util.stream.Collectors; 10 | 11 | public class Util { 12 | 13 | private static final Random RANDOM = new Random(0); 14 | private static final DecimalFormat formatter = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US)); 15 | 16 | public static void delay() { 17 | int delay = 1000; 18 | //int delay = 500 + RANDOM.nextInt(2000); 19 | try { 20 | Thread.sleep(delay); 21 | } catch (InterruptedException e) { 22 | throw new RuntimeException(e); 23 | } 24 | } 25 | 26 | public static double format(double number) { 27 | synchronized (formatter) { 28 | return new Double(formatter.format(number)); 29 | } 30 | } 31 | 32 | public static CompletableFuture> sequence(List> futures) { 33 | return CompletableFuture.supplyAsync(() -> futures.stream() 34 | .map(CompletableFuture::join) 35 | .collect(Collectors.toList())); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example13/AsyncShop.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example13; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.CompletableFuture; 5 | import java.util.concurrent.Future; 6 | 7 | import static mf.java8ws.examples.example13.Util.delay; 8 | import static mf.java8ws.examples.example13.Util.format; 9 | 10 | public class AsyncShop { 11 | 12 | private final String name; 13 | private final Random random; 14 | 15 | public AsyncShop(String name) { 16 | this.name = name; 17 | random = new Random(name.charAt(0) * name.charAt(1) * name.charAt(2)); 18 | } 19 | 20 | public Future getPriceFor(String product) { 21 | /* 22 | CompletableFuture futurePrice = new CompletableFuture<>(); 23 | new Thread( () -> { 24 | try { 25 | double price = calculatePrice(product); 26 | futurePrice.complete(price); 27 | } catch (Exception ex) { 28 | futurePrice.completeExceptionally(ex); 29 | } 30 | }).start(); 31 | return futurePrice; 32 | */ 33 | return CompletableFuture.supplyAsync(() -> calculatePrice(product)); 34 | } 35 | 36 | private double calculatePrice(String product) { 37 | delay(); 38 | if (true) throw new RuntimeException("product not available"); 39 | return format(random.nextDouble() * product.charAt(0) + product.charAt(1)); 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example13/Util.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example13; 2 | 3 | import java.text.DecimalFormat; 4 | import java.text.DecimalFormatSymbols; 5 | import java.util.List; 6 | import java.util.Locale; 7 | import java.util.Random; 8 | import java.util.concurrent.CompletableFuture; 9 | import java.util.stream.Collectors; 10 | 11 | public class Util { 12 | 13 | private static final Random RANDOM = new Random(0); 14 | private static final DecimalFormat formatter = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US)); 15 | 16 | public static void delay() { 17 | int delay = 1000; 18 | //int delay = 500 + RANDOM.nextInt(2000); 19 | try { 20 | Thread.sleep(delay); 21 | } catch (InterruptedException e) { 22 | throw new RuntimeException(e); 23 | } 24 | } 25 | 26 | public static double format(double number) { 27 | synchronized (formatter) { 28 | return new Double(formatter.format(number)); 29 | } 30 | } 31 | 32 | public static CompletableFuture> sequence(List> futures) { 33 | return CompletableFuture.supplyAsync(() -> futures.stream() 34 | .map(future -> future.join()) 35 | .collect(Collectors.toList())); 36 | } 37 | 38 | public static long timeSince(long nanoStart) { 39 | return (System.nanoTime() - nanoStart) / 1_000_000; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example13/BestPriceFinder.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example13; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.concurrent.Executor; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.ThreadFactory; 8 | import java.util.stream.Collectors; 9 | 10 | public class BestPriceFinder { 11 | 12 | private final List shops = Arrays.asList(new Shop("BestPrice"), 13 | new Shop("LetsSaveBig"), 14 | new Shop("MyFavoriteShop"), 15 | new Shop("BuyItAll"), 16 | new Shop("ShopEasy")); 17 | 18 | private final Executor executor = Executors.newFixedThreadPool(shops.size(), new ThreadFactory() { 19 | @Override 20 | public Thread newThread(Runnable r) { 21 | Thread t = new Thread(r); 22 | t.setDaemon(true); 23 | return t; 24 | } 25 | }); 26 | 27 | public List findPriceSequential(String product) { 28 | return shops.stream() 29 | .map(shop -> shop.getName() + " price is " + shop.getPriceFor(product)) 30 | .collect(Collectors.toList()); 31 | } 32 | 33 | public List findPriceParallel(String product) { 34 | return null; 35 | } 36 | 37 | public List findPrice(String product) { 38 | return null; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/talk/example06/Dish.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.talk.example06; 2 | import java.util.*; 3 | 4 | public class Dish { 5 | 6 | private final String name; 7 | private final boolean vegetarian; 8 | private final int calories; 9 | private final Type type; 10 | 11 | public Dish(String name, boolean vegetarian, int calories, Type type) { 12 | this.name = name; 13 | this.vegetarian = vegetarian; 14 | this.calories = calories; 15 | this.type = type; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public boolean isVegetarian() { 23 | return vegetarian; 24 | } 25 | 26 | public int getCalories() { 27 | return calories; 28 | } 29 | 30 | public Type getType() { 31 | return type; 32 | } 33 | 34 | public enum Type { MEAT, FISH, OTHER } 35 | 36 | @Override 37 | public String toString() { 38 | return name; 39 | } 40 | 41 | public static final List menu = 42 | Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), 43 | new Dish("beef", false, 700, Dish.Type.MEAT), 44 | new Dish("chicken", false, 400, Dish.Type.MEAT), 45 | new Dish("french fries", true, 530, Dish.Type.OTHER), 46 | new Dish("rice", true, 350, Dish.Type.OTHER), 47 | new Dish("seasonal fruit", true, 120, Dish.Type.OTHER), 48 | new Dish("pizza", true, 550, Dish.Type.OTHER), 49 | new Dish("prawns", false, 400, Dish.Type.FISH), 50 | new Dish("salmon", false, 450, Dish.Type.FISH)); 51 | } -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example06/Dish.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example06; 2 | import java.util.*; 3 | 4 | public class Dish { 5 | 6 | private final String name; 7 | private final boolean vegetarian; 8 | private final int calories; 9 | private final Type type; 10 | 11 | public Dish(String name, boolean vegetarian, int calories, Type type) { 12 | this.name = name; 13 | this.vegetarian = vegetarian; 14 | this.calories = calories; 15 | this.type = type; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public boolean isVegetarian() { 23 | return vegetarian; 24 | } 25 | 26 | public int getCalories() { 27 | return calories; 28 | } 29 | 30 | public Type getType() { 31 | return type; 32 | } 33 | 34 | public enum Type { MEAT, FISH, OTHER } 35 | 36 | @Override 37 | public String toString() { 38 | return name; 39 | } 40 | 41 | public static final List menu = 42 | Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), 43 | new Dish("beef", false, 700, Dish.Type.MEAT), 44 | new Dish("chicken", false, 400, Dish.Type.MEAT), 45 | new Dish("french fries", true, 530, Dish.Type.OTHER), 46 | new Dish("rice", true, 350, Dish.Type.OTHER), 47 | new Dish("seasonal fruit", true, 120, Dish.Type.OTHER), 48 | new Dish("pizza", true, 550, Dish.Type.OTHER), 49 | new Dish("prawns", false, 400, Dish.Type.FISH), 50 | new Dish("salmon", false, 450, Dish.Type.FISH)); 51 | } -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example03/Lazy.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example03; 2 | 3 | import java.util.*; 4 | 5 | public class Lazy { 6 | 7 | public static boolean isEven(int n) { 8 | System.out.println("isEven: " + n); 9 | return n % 2 == 0; 10 | } 11 | 12 | public static int doubleIt(int n) { 13 | System.out.println("doubleIt: " + n); 14 | return n * 2; 15 | } 16 | 17 | public static boolean isGT5(int n) { 18 | System.out.println("isGT5: " + n); 19 | return n > 5; 20 | } 21 | 22 | public static void main(String... args) { 23 | List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 24 | 25 | // Take only the even numbers, double them and print 26 | // the first one bigger than 5 27 | 28 | for (int n : numbers) { 29 | if (n % 2 == 0) { 30 | int n2 = n * 2; 31 | if (n2 > 5) { 32 | System.out.println(n2); 33 | break; 34 | } 35 | } 36 | } 37 | 38 | List l1 = new ArrayList(); 39 | for (int n : numbers) { 40 | if (isEven(n)) l1.add(n); 41 | } 42 | 43 | List l2 = new ArrayList(); 44 | for (int n : l1) { 45 | l2.add(doubleIt(n)); 46 | } 47 | 48 | List l3 = new ArrayList(); 49 | for (int n : l2) { 50 | if (isGT5(n)) l3.add(n); 51 | } 52 | 53 | System.out.println(l3.get(0)); 54 | 55 | System.out.println( 56 | numbers.stream() 57 | .filter(Lazy::isEven) 58 | .map(Lazy::doubleIt) 59 | .filter(Lazy::isGT5) 60 | .findFirst().get()); 61 | } 62 | } 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | /* 83 | List l1 = new ArrayList(); 84 | for (int n : numbers) { 85 | if (isEven(n)) l1.add(n); 86 | } 87 | 88 | List l2 = new ArrayList(); 89 | for (int n : l1) { 90 | l2.add(doubleIt(n)); 91 | } 92 | 93 | List l3 = new ArrayList(); 94 | for (int n : l2) { 95 | if (isGT5(n)) l3.add(n); 96 | } 97 | 98 | System.out.println(l3.get(0)); 99 | */ -------------------------------------------------------------------------------- /src/main/java/mf/java8ws/examples/example13/BestPriceFinder.java: -------------------------------------------------------------------------------- 1 | package mf.java8ws.examples.example13; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.concurrent.CompletableFuture; 6 | import java.util.concurrent.Executor; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.ThreadFactory; 9 | import java.util.stream.Collectors; 10 | 11 | import static mf.java8ws.examples.example13.Util.sequence; 12 | 13 | public class BestPriceFinder { 14 | 15 | private final List shops = Arrays.asList(new Shop("BestPrice"), 16 | new Shop("LetsSaveBig"), 17 | new Shop("MyFavoriteShop"), 18 | /*new Shop("111"), 19 | new Shop("222"), 20 | new Shop("333"), 21 | new Shop("444"),*/ 22 | new Shop("BuyItAll"), 23 | new Shop("ShopEasy")); 24 | 25 | private final Executor executor = Executors.newFixedThreadPool(shops.size(), new ThreadFactory() { 26 | @Override 27 | public Thread newThread(Runnable r) { 28 | Thread t = new Thread(r); 29 | t.setDaemon(true); 30 | return t; 31 | } 32 | }); 33 | 34 | public List findPriceSequential(String product) { 35 | return shops.stream() 36 | .map(shop -> shop.getName() + " price is " + shop.getPriceFor(product)) 37 | .collect(Collectors.toList()); 38 | } 39 | 40 | public List findPriceParallel(String product) { 41 | return shops.parallelStream() 42 | .map(shop -> shop.getName() + " price is " + shop.getPriceFor(product)) 43 | .collect(Collectors.toList()); 44 | } 45 | 46 | public List findPrice(String product) { 47 | List> priceFutures = 48 | shops.stream() 49 | .map(shop -> CompletableFuture.supplyAsync(() -> shop.getName() + " price is " + shop.getPriceFor(product), executor)) 50 | .collect(Collectors.toList()); 51 | 52 | return sequence(priceFutures).join(); 53 | } 54 | /*/ 55 | public List findPriceSequential(String product) { 56 | return shops.stream() 57 | .map(shop -> shop.getDiscountedPriceFor(product)) 58 | .map(Quote::parse) 59 | .map(Discount::applyDiscount) 60 | .collect(Collectors.toList()); 61 | } 62 | 63 | public List findPriceParallel(String product) { 64 | return shops.parallelStream() 65 | .map(shop -> shop.getDiscountedPriceFor(product)) 66 | .map(Quote::parse) 67 | .map(Discount::applyDiscount) 68 | .collect(Collectors.toList()); 69 | } 70 | 71 | public List findPrice(String product) { 72 | List> priceFutures = findPriceStream(product) 73 | .collect(Collectors.>toList()); 74 | 75 | return sequence(priceFutures).join(); 76 | } 77 | 78 | public Stream> findPriceStream(String product) { 79 | return shops.stream() 80 | .map(shop -> CompletableFuture.supplyAsync(() -> shop.getDiscountedPriceFor(product), executor)) 81 | .map(future -> future.thenApply(Quote::parse)) 82 | .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote), executor))); 83 | } 84 | 85 | public void printPricesStream() { 86 | long start = System.nanoTime(); 87 | CompletableFuture[] futures = findPriceStream("myPhone") 88 | .map(f -> f.thenAccept(s -> System.out.println(s + " (done in " + ((System.nanoTime() - start) / 1_000_000) + " msecs)"))) 89 | .toArray(size -> new CompletableFuture[size]); 90 | CompletableFuture.allOf(futures).join(); 91 | } 92 | */ 93 | } 94 | --------------------------------------------------------------------------------