Guest User

Untitled

a guest
Oct 22nd, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.53 KB | None | 0 0
  1. import java.util.Arrays;
  2. import java.util.List;
  3. import java.util.Random;
  4. import java.util.concurrent.CompletableFuture;
  5. import java.util.concurrent.Future;
  6. import java.util.stream.Collectors;
  7.  
  8.  
  9. public class CompletableFutureTest {
  10.  
  11. public static void main(String[] args) {
  12. List<Shop> shops = Arrays.asList(
  13. new Shop("New Save"),
  14. new Shop("Pak n Save"),
  15. new Shop("New World"),
  16. new Shop("PB"),
  17. new Shop("Norman"),
  18. new Shop("Countdown")
  19. );
  20.  
  21. long start = System.nanoTime();
  22. System.out.println(findPricesAsyn("IPhone7", shops));
  23. long duration = (System.nanoTime() - start) / 1_000_000;
  24. System.out.println("Done in completable future " + duration + " msecs");
  25.  
  26.  
  27. start = System.nanoTime();
  28. System.out.println(findPricesSync("IPhone6", shops));
  29. duration = (System.nanoTime() - start) / 1_000_000;
  30. System.out.println("Done in parallel stream " + duration + " msecs");
  31.  
  32. }
  33.  
  34.  
  35. /**
  36. * Note that you use two separate stream pipelines,
  37. * instead of putting the two map operations one after the other in the same stream-processing pipeline—and for a very good reason.
  38. * Given the lazy nature of intermediate stream operations,
  39. * if you had processed the stream in a single pipeline, you would have succeeded only in executing all the requests to different shops synchronously and sequentially.
  40. * This is because the creation of each CompletableFuture to interrogate a given shop would start only when the computation of the previous one had completed,
  41. * letting the join method return the result of that computation.
  42. *
  43. * @param product
  44. * @param shops
  45. * @return
  46. */
  47. public static List<String> findPricesAsyn(String product, List<Shop> shops) {
  48.  
  49. // more flexible than parallel as it allows you to specify a different Executor to submit their tasks to
  50. List<CompletableFuture<String>> priceFutures = shops.stream()
  51. .map(shop -> CompletableFuture.supplyAsync(
  52. () -> shop.getPrice(product)))
  53. .map(future -> future.thenApply(Quote::parse))
  54. .map(future -> future.thenCompose(quote ->
  55. CompletableFuture.supplyAsync(() -> //create another future to be composed...
  56. Discount.applyDiscount(quote))))
  57. .collect(Collectors.toList());
  58.  
  59. return priceFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
  60. }
  61.  
  62.  
  63. public static List<String> findPricesSync(String product, List<Shop> shops) {
  64. return shops.stream()
  65. .map(shop -> shop.getPrice(product))
  66. .map(Quote::parse)
  67. .map(Discount::applyDiscount)
  68. .collect(Collectors.toList());
  69. }
  70.  
  71.  
  72. // public static List<String> findPricesParall(String product, List<Shop> shops) {
  73. // return shops.parallelStream()
  74. // .map(shop -> shop.getPrice(product))
  75. // .collect(Collectors.toList());
  76. // }
  77.  
  78. }
  79.  
  80.  
  81. class Shop {
  82.  
  83. private String name;
  84.  
  85. Random random = new Random();
  86.  
  87. public Shop(String name) {
  88. this.name = name;
  89. }
  90.  
  91. public String getName() {
  92. return name;
  93. }
  94.  
  95. public static void delay() {
  96. try {
  97. Thread.sleep(1000);
  98. } catch (InterruptedException e) {
  99. e.printStackTrace();
  100. }
  101. }
  102.  
  103. private double calculatePrice(String product) {
  104. delay();
  105. return random.nextDouble() * product.charAt(0) + product.charAt(1);
  106. }
  107.  
  108. public String getPrice(String product) {
  109. double price = calculatePrice(product);
  110. Discount.Code code = Discount.Code.values()[random.nextInt(Discount.Code.values().length)];
  111. return String.format("%s:%.2f:%s", name, price, code);
  112. }
  113.  
  114. public Future<Double> getPriceAsync(String product) {
  115. return CompletableFuture.supplyAsync(() -> calculatePrice(product));
  116. }
  117. }
  118.  
  119. class Quote {
  120. private final String shopName;
  121. private double price;
  122. private final Discount.Code discountCode;
  123.  
  124.  
  125. public Quote(String shopName, double price, Discount.Code discountCode) {
  126. this.shopName = shopName;
  127. this.price = price;
  128. this.discountCode = discountCode;
  129. }
  130.  
  131. public static Quote parse(String s) {
  132. String[] split = s.split(":");
  133. String shopName = split[0];
  134. double price = Double.parseDouble(split[1]);
  135. Discount.Code discountCode = Discount.Code.valueOf(split[2]);
  136. return new Quote(shopName, price, discountCode);
  137. }
  138.  
  139. public String getShopName() {
  140. return shopName;
  141. }
  142.  
  143. public double getPrice() {
  144. return price;
  145. }
  146.  
  147. public Discount.Code getDiscountCode() {
  148. return discountCode;
  149. }
  150. }
  151.  
  152. class Discount {
  153. public enum Code {
  154. A(10), B(20), C(30);
  155. int percentage;
  156.  
  157. Code(int percentage) {
  158. this.percentage = percentage;
  159. }
  160.  
  161. int getPercentage() {
  162. return percentage;
  163. }
  164.  
  165. }
  166.  
  167. public static String applyDiscount(Quote quote) {
  168. return quote.getShopName() + " price is " + Discount.apply(quote.getPrice(), quote.getDiscountCode());
  169. }
  170.  
  171. public static void delay() {
  172. try {
  173. Thread.sleep(1000);
  174. } catch (InterruptedException e) {
  175. e.printStackTrace();
  176. }
  177. }
  178.  
  179. private static double apply(double price, Code discountCode) {
  180. delay();
  181. return price * (100 - discountCode.getPercentage() / 100);
  182. }
  183. }
Add Comment
Please, Sign In to add comment