diff --git a/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java index d2940969..84d253b6 100644 --- a/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java +++ b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java @@ -1,9 +1,16 @@ package lambdasinaction.chap10; -import java.util.*; +import org.junit.Test; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.stream.Collectors; -import static java.util.Optional.of; import static java.util.Optional.empty; +import static java.util.Optional.of; +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertEquals; public class OperationsWithOptional { @@ -22,4 +29,175 @@ public static void main(String... args) { public static final Optional max(Optional i, Optional j) { return i.flatMap(a -> j.map(b -> Math.max(a, b))); } + + /** + * 这个类型的对象可能包含值,也可能为空。你可以使用同名方法创建一个空的 Optional。 + */ + @Test(expected = NoSuchElementException.class) + public void whenCreateEmptyOptional_thenNull() { + Optional emptyOpt = Optional.empty(); + emptyOpt.get(); + } + + @Test(expected = NullPointerException.class) + public void whenCreateOfEmptyOptional_thenNullPointerException() { + User user = null; + Optional opt = Optional.of(user); + } + + @Test + public void whenCreateOfNullableOptional_thenOk() { + String name = "John"; + Optional opt = Optional.ofNullable(name); + + assertEquals("John", opt.get()); + } + + @Test + public void whenCheckIfPresent_thenOk() { + User user = new User("john@gmail.com", "1234"); + Optional opt = Optional.ofNullable(user); + assertTrue(opt.isPresent()); + + opt.ifPresent( u -> assertEquals(user.getEmail(), u.getEmail())); + + assertEquals(user.getEmail(), opt.get().getEmail()); + } + + + @Test + public void whenEmptyValue_thenReturnDefault() { + User user = null; + User user2 = new User("anna@gmail.com", "1234"); + User result = Optional.ofNullable(user).orElse(user2); + + assertEquals(user2.getEmail(), result.getEmail()); + } + + @Test + public void whenValueNotNull_thenIgnoreDefault() { + User user = new User("john@gmail.com","1234"); + User user2 = new User("anna@gmail.com", "1234"); + User result = Optional.ofNullable(user).orElse(user2); + + User result2 = Optional.ofNullable(user).orElseGet( () -> user2); + + assertEquals("john@gmail.com", result.getEmail()); + assertEquals("john@gmail.com", result2.getEmail()); + } + + + @Test + public void givenEmptyValue_whenCompare_thenOk() { + User user = null; + System.out.println( "Using orElse"); + User result = Optional.ofNullable(user).orElse(createNewUser()); + System.out.println("Using orElseGet"); + User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser()); + } + + private User createNewUser() { + System.out.println("Creating New User"); + return new User("extra@gmail.com", "1234"); + } + + /** + * 这个大坑啊,用orElse ,是必定执行后面orElse的表达式的, + * + * 建议用orElseGet 或者 orElse不用表达式 + * + */ + @Test + public void givenPresentValue_whenCompare_thenOk() { + User user = new User("john@gmail.com", "1234"); + System.out.println("Using orElse"); + User result = Optional.ofNullable(user).orElse(createNewUser()); + System.out.println("Using orElseGet"); + User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser()); + } + + /** + * 返回异常 + */ + @Test(expected = IllegalArgumentException.class) + public void whenThrowException_thenOk() { + User user = null; + User result = Optional.ofNullable(user) + .orElseThrow( () -> new IllegalArgumentException()); + } + + /** + * 转换值 + */ + + @Test + public void whenMap_thenOk() { + User user = new User("anna@gmail.com", "1234"); + String email = Optional.ofNullable(user) + //orElse 后面不要带表达式,无论null 或者非null 都会执行的 + .map(u -> u.getEmail()).orElse(print()); + + assertEquals(email, user.getEmail()); + } + + private String print(){ + System.out.println("test"); + return "xxx"; + + } + + @Test + public void whenFlatMap_thenOk() { + User user = new User("anna@gmail.com", "1234"); + user.setPosition("Developer"); + String position = Optional.ofNullable(user) + .map(u -> u.getPosition()).orElse("default"); + + assertEquals(position, user.getPosition()); + } + + /** + * 过滤值 + */ + @Test + public void whenFilter_thenOk() { + User user = new User("anna@gmail.com", "1234"); + Optional result = Optional.ofNullable(user) + .filter(u -> u.getEmail() != null && u.getEmail().contains("@")); + + assertTrue(result.isPresent()); + } + + /** + * Java 9 增强,如果对象包含值,则 Lambda 表达式不会执行: + */ + + @Test + public void whenEmptyOptional_thenGetValueFromOr() { + User user = new User("anna@gmail.com", "1234"); + User result = Optional.ofNullable(user) + .or( () -> Optional.of(new User("default","1234"))).get(); + + assertEquals(result.getEmail(), "default"); + + + Optional.ofNullable(user).ifPresentOrElse( u -> System.out.println("User is:" + u.getEmail()), + () -> System.out.println("User not found")); + } + + @Test + public void whenGetStream_thenOk() { + User user = new User("john@gmail.com", "1234"); + List emails = Optional.ofNullable(user) + .stream() + .filter(u -> u.getEmail() != null && u.getEmail().contains("@")) + .map( u -> u.getEmail()) + .collect(Collectors.toList()); + + assertTrue(emails.size() == 1); + assertEquals(emails.get(0), user.getEmail()); + } + + + } diff --git a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java index 5a74161a..99c7d99a 100644 --- a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java +++ b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java @@ -16,6 +16,11 @@ public static void main(String[] args) { execute("combined USD CompletableFuture v3", () -> bestPriceFinder.findPricesInUSD3("myPhone27S")); } + /** + * todo :这个几乎是最低成本获取并行的方式了,要好好注意学习并运用 + * @param msg + * @param s + */ private static void execute(String msg, Supplier> s) { long start = System.nanoTime(); System.out.println(s.get()); diff --git a/src/main/java/lambdasinaction/chap14/Currying.java b/src/main/java/lambdasinaction/chap14/Currying.java index f17ac928..6a250a07 100644 --- a/src/main/java/lambdasinaction/chap14/Currying.java +++ b/src/main/java/lambdasinaction/chap14/Currying.java @@ -2,7 +2,11 @@ import java.util.function.DoubleUnaryOperator; - +/** + * 科里化 + * 科里化1是一种将具备2个参数(比如,x和y)的函数f转化为使用一个参数的函数g,并 且这个函数的返回值也是一个函数,它会作为新函数的一个参数。 + * 后者的返回值和初始函数的 返回值相同,即f(x,y) = (g(x))(y)。 + */ public class Currying { public static void main(String[] args) { diff --git a/src/main/java/lambdasinaction/chap3/Sorting.java b/src/main/java/lambdasinaction/chap3/Sorting.java index 41acbe25..7119f209 100644 --- a/src/main/java/lambdasinaction/chap3/Sorting.java +++ b/src/main/java/lambdasinaction/chap3/Sorting.java @@ -40,7 +40,8 @@ public int compare(Apple a1, Apple a2){ // 4 // [Apple{color='red', weight=10}, Apple{color='red', weight=20}, Apple{color='green', weight=155}] inventory.sort(comparing(Apple::getWeight)); - System.out.println(inventory); + + System.out.println(inventory); } public static class Apple { diff --git a/src/main/java/lambdasinaction/chap4/ParallelStream.java b/src/main/java/lambdasinaction/chap4/ParallelStream.java new file mode 100644 index 00000000..3c14b007 --- /dev/null +++ b/src/main/java/lambdasinaction/chap4/ParallelStream.java @@ -0,0 +1,18 @@ +package lambdasinaction.chap4; + +import java.util.Arrays; +import java.util.List; + +/** + * @author chenhaipeng + * @version 1.0 + * @date 2018/08/02 上午10:35 + */ +public class ParallelStream { + public static void main(String[] args) { + + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); + numbers.parallelStream() + .forEach(System.out::println); + } +} diff --git a/src/main/java/lambdasinaction/chap4/StreamBasic.java b/src/main/java/lambdasinaction/chap4/StreamBasic.java index 19a8c176..6a2f048c 100644 --- a/src/main/java/lambdasinaction/chap4/StreamBasic.java +++ b/src/main/java/lambdasinaction/chap4/StreamBasic.java @@ -1,13 +1,10 @@ package lambdasinaction.chap4; import java.util.*; -import java.util.stream.*; import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toList; -import static lambdasinaction.chap4.Dish.menu; - public class StreamBasic { public static void main(String...args){ @@ -41,10 +38,15 @@ public int compare(Dish d1, Dish d2){ } public static List getLowCaloricDishesNamesInJava8(List dishes){ - return dishes.stream() + return dishes.parallelStream() .filter(d -> d.getCalories() < 400) .sorted(comparing(Dish::getCalories)) .map(Dish::getName) .collect(toList()); } + + //todo + public static Map> getKeyMapInJava8(List dishes){ + return null; + } } diff --git a/src/main/java/lambdasinaction/chap4/StreamVsCollection.java b/src/main/java/lambdasinaction/chap4/StreamVsCollection.java index a72a0730..f4720d49 100644 --- a/src/main/java/lambdasinaction/chap4/StreamVsCollection.java +++ b/src/main/java/lambdasinaction/chap4/StreamVsCollection.java @@ -1,8 +1,8 @@ package lambdasinaction.chap4; -import java.util.*; -import java.util.stream.*; -import static java.util.stream.Collectors.toList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; public class StreamVsCollection { @@ -14,5 +14,9 @@ public static void main(String...args){ // uncommenting this line will result in an IllegalStateException // because streams can be consumed only once //s.forEach(System.out::println); + + s.forEach(s1 -> { + System.out.println(s1); + }); } } \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap5/BuildingStreams.java b/src/main/java/lambdasinaction/chap5/BuildingStreams.java index 15280a39..6259110b 100644 --- a/src/main/java/lambdasinaction/chap5/BuildingStreams.java +++ b/src/main/java/lambdasinaction/chap5/BuildingStreams.java @@ -26,11 +26,14 @@ public static void main(String...args) throws Exception{ .limit(10) .forEach(System.out::println); + System.out.println("======================="); + // fibonnaci with 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] + ")")); - + + System.out.println("======================="); Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1],t[0] + t[1]}) .limit(10) . map(t -> t[0]) @@ -52,7 +55,8 @@ public int getAsInt(){ } }).limit(5) .forEach(System.out::println); - + + System.out.println("----------------------"); IntSupplier fib = new IntSupplier(){ private int previous = 0; @@ -66,7 +70,7 @@ public int getAsInt(){ }; IntStream.generate(fib).limit(10).forEach(System.out::println); - long uniqueWords = Files.lines(Paths.get("lambdasinaction/chap5/data.txt"), Charset.defaultCharset()) + long uniqueWords = Files.lines(Paths.get("/Users/uc/IdeaProjects/Java8InAction/src/main/resources/lambdasinaction/chap5/data.txt"), Charset.defaultCharset()) .flatMap(line -> Arrays.stream(line.split(" "))) .distinct() .count(); diff --git a/src/main/java/lambdasinaction/chap5/Finding.java b/src/main/java/lambdasinaction/chap5/Finding.java index acccc543..cbe37aec 100644 --- a/src/main/java/lambdasinaction/chap5/Finding.java +++ b/src/main/java/lambdasinaction/chap5/Finding.java @@ -1,8 +1,7 @@ package lambdasinaction.chap5; -import lambdasinaction.chap4.*; +import lambdasinaction.chap4.Dish; -import java.util.stream.*; -import java.util.*; +import java.util.Optional; import static lambdasinaction.chap4.Dish.menu; diff --git a/src/main/java/lambdasinaction/chap6/Summarizing.java b/src/main/java/lambdasinaction/chap6/Summarizing.java index 06f9af6d..903d916d 100644 --- a/src/main/java/lambdasinaction/chap6/Summarizing.java +++ b/src/main/java/lambdasinaction/chap6/Summarizing.java @@ -25,6 +25,9 @@ private static long howManyDishes() { } private static Dish findMostCaloricDish() { + + //menu.stream().mapToInt(Dish::getCalories).max(); + return menu.stream().collect(reducing((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2)).get(); } @@ -50,6 +53,9 @@ private static String getShortMenu() { return menu.stream().map(Dish::getName).collect(joining()); } + /** + * good job 这个是我们平时用得比较多的 + */ private static String getShortMenuCommaSeparated() { return menu.stream().map(Dish::getName).collect(joining(", ")); } diff --git a/src/main/java/lambdasinaction/dsl/Consumer.java b/src/main/java/lambdasinaction/dsl/Consumer.java new file mode 100644 index 00000000..956cd1b2 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/Consumer.java @@ -0,0 +1,33 @@ +package lambdasinaction.dsl; + +import java.util.Arrays; + +/** + * @author chenhaipeng + * @version 1.0 + * @date 2018/08/02 下午5:55 + */ +public class Consumer { + public static void main(String[] args) { + Arrays.asList("Justin", "Monica", "Irene").forEach(System.out::println); + + } + + +} + +class User{ + String username; + + public User(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/src/main/java/lambdasinaction/dsl/Main.java b/src/main/java/lambdasinaction/dsl/Main.java index b50683e5..2419f28d 100644 --- a/src/main/java/lambdasinaction/dsl/Main.java +++ b/src/main/java/lambdasinaction/dsl/Main.java @@ -73,6 +73,11 @@ public void nestedFunction() { ); } + /** + * Consumer 代表可以接受xx类,如果xx类是一个builder ,那么你就可以链式构造 + * 如:Consumer consumer,注意consumer.accept( builder ) + * 代表执行builder方式 ,如果不写代表没有用到 + */ public void lambda() { Order order = LambdaOrderBuilder.order( o -> { o.forCustomer( "BigBank" ); diff --git a/src/main/java/lambdasinaction/dsl/Mixed.java b/src/main/java/lambdasinaction/dsl/Mixed.java index 132dd998..99eafc7e 100644 --- a/src/main/java/lambdasinaction/dsl/Mixed.java +++ b/src/main/java/lambdasinaction/dsl/Mixed.java @@ -23,7 +23,15 @@ import static lambdasinaction.dsl.MixedBuilder.forCustomer; public class Mixed { - public void mixed() { + public static void main(String[] args) { + mixed(); + } + + /** + * Consumer consumer 接受一个TradeBuilder,TradeBuilder构建一个表达式 + * Consumer.accept 相当 于执行表达式链 + */ + public static void mixed() { Order order = forCustomer( "BigBank", buy( t -> t.quantity( 80 ) @@ -34,6 +42,7 @@ public void mixed() { .stock( "GOOGLE" ) .on( "NASDAQ" ) .at( 125.00 )) ); + System.out.println(order); } } diff --git a/src/main/java/lambdasinaction/dsl/NestedFunctionOrderBuilder.java b/src/main/java/lambdasinaction/dsl/NestedFunctionOrderBuilder.java index b9daaac9..efc322e1 100644 --- a/src/main/java/lambdasinaction/dsl/NestedFunctionOrderBuilder.java +++ b/src/main/java/lambdasinaction/dsl/NestedFunctionOrderBuilder.java @@ -22,6 +22,9 @@ import java.util.stream.Stream; +/** + * 这个类跟lambda好象没有什么关系啊,只有一个Stream.of(trades).forEach(order::addTrade) + */ public class NestedFunctionOrderBuilder { public static Order order(String customer, Trade... trades) { diff --git a/src/main/java/lambdasinaction/dsl/TaxCalculator.java b/src/main/java/lambdasinaction/dsl/TaxCalculator.java index 9ef38cef..27969dfc 100644 --- a/src/main/java/lambdasinaction/dsl/TaxCalculator.java +++ b/src/main/java/lambdasinaction/dsl/TaxCalculator.java @@ -21,6 +21,9 @@ import java.util.function.Function; +/** + * 利用函数式 + */ public class TaxCalculator { public static double calculate( Order order, boolean useRegional, boolean useGeneral, boolean useSurcharge ) { @@ -56,6 +59,11 @@ public double calculate(Order order) { public Function taxFuncion = Function.identity(); + /** + * 我们是否会写这个参数形式的接口, + * @param f + * @return + */ public TaxCalculator with(Function f) { taxFuncion.andThen( f ); return this; @@ -68,14 +76,21 @@ public double calculateF(Order order) { public static void main(String[] args) { Order order = new Order(); - double value = TaxCalculator.calculate( order, true, false, true ); + double value = TaxCalculator.calculate(order, true, false, true); + System.out.println(value); + //类似builder 模式 value = new TaxCalculator().withTaxRegional() - .withTaxSurcharge() - .calculate( order ); + .withTaxSurcharge() + .calculate(order); + //用函数式编程的想法实现 value = new TaxCalculator().with(Tax::regional) - .with(Tax::surcharge) - .calculate( order ); + .with(Tax::surcharge) + .calculate(order); + + //函数式编程,核心是函数,有时候计算往往是后置的,把计算公式传递, + //不过我们平时用的Builder 一般针对bean来说,一个比较简单的实现例如lambok + System.out.println("======="+new TaxCalculator().with(Tax::test).calculate(order)); } } diff --git a/src/main/java/lambdasinaction/dsl/model/Order.java b/src/main/java/lambdasinaction/dsl/model/Order.java index 21c06747..866d5d1d 100644 --- a/src/main/java/lambdasinaction/dsl/model/Order.java +++ b/src/main/java/lambdasinaction/dsl/model/Order.java @@ -40,4 +40,12 @@ public void setCustomer( String customer ) { public double getValue() { return trades.stream().mapToDouble( Trade::getValue ).sum(); } + + @Override + public String toString() { + return "Order{" + + "customer='" + customer + '\'' + + ", trades=" + trades + + '}'; + } } \ No newline at end of file diff --git a/src/main/java/lambdasinaction/dsl/model/Stock.java b/src/main/java/lambdasinaction/dsl/model/Stock.java index 1e0302e2..864eb916 100644 --- a/src/main/java/lambdasinaction/dsl/model/Stock.java +++ b/src/main/java/lambdasinaction/dsl/model/Stock.java @@ -37,4 +37,12 @@ public String getMarket() { public void setMarket( String market ) { this.market = market; } + + @Override + public String toString() { + return "Stock{" + + "symbol='" + symbol + '\'' + + ", market='" + market + '\'' + + '}'; + } } diff --git a/src/main/java/lambdasinaction/dsl/model/Tax.java b/src/main/java/lambdasinaction/dsl/model/Tax.java index d2d6bf22..c17dcc70 100644 --- a/src/main/java/lambdasinaction/dsl/model/Tax.java +++ b/src/main/java/lambdasinaction/dsl/model/Tax.java @@ -28,4 +28,8 @@ public static double general(double value) { public static double surcharge(double value) { return value * 1.05; } + + public static double test(double value) { + return value + 100; + } } diff --git a/src/main/java/lambdasinaction/dsl/model/Trade.java b/src/main/java/lambdasinaction/dsl/model/Trade.java index c8f35813..0b27549d 100644 --- a/src/main/java/lambdasinaction/dsl/model/Trade.java +++ b/src/main/java/lambdasinaction/dsl/model/Trade.java @@ -63,4 +63,14 @@ public void setStock( Stock stock ) { public double getValue() { return quantity * price; } + + @Override + public String toString() { + return "Trade{" + + "type=" + type + + ", stock=" + stock + + ", quantity=" + quantity + + ", price=" + price + + '}'; + } } diff --git a/src/main/java/lambdasinaction/dsl/test/PredicateConsumerDemo.java b/src/main/java/lambdasinaction/dsl/test/PredicateConsumerDemo.java new file mode 100644 index 00000000..8d44cbd3 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/test/PredicateConsumerDemo.java @@ -0,0 +1,15 @@ +package lambdasinaction.dsl.test; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class PredicateConsumerDemo { + + public static Student updateStudentFee(Student student, Predicate predicate, Consumer consumer){ + if (predicate.test(student)){ + consumer.accept(student); + } + return student; + } + +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/dsl/test/Student.java b/src/main/java/lambdasinaction/dsl/test/Student.java new file mode 100644 index 00000000..06a8a4a2 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/test/Student.java @@ -0,0 +1,22 @@ +package lambdasinaction.dsl.test; + +public class Student { + + String firstName; + String lastName; + Double grade; + Double feeDiscount = 0.0; + Double baseFee = 2000.0; + + public Student(String firstName, String lastName, Double grade) { + this.firstName = firstName; + this.lastName = lastName; + this.grade = grade; + } + + public void printFee(){ + System.out.println(baseFee+"------"+feeDiscount); + Double newFee = baseFee - ((baseFee * feeDiscount)/100); + System.out.println("The fee after discount: " + newFee); + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/dsl/test/Test.java b/src/main/java/lambdasinaction/dsl/test/Test.java new file mode 100644 index 00000000..ee779c93 --- /dev/null +++ b/src/main/java/lambdasinaction/dsl/test/Test.java @@ -0,0 +1,30 @@ +package lambdasinaction.dsl.test; + +import static lambdasinaction.dsl.test.PredicateConsumerDemo.updateStudentFee; + +public class Test { + public static void main(String[] args) { + Student student1 = new Student("Ashok","Kumar", 9.5); + + student1 = updateStudentFee(student1, + //Lambda expression for Predicate interface + student -> student.grade > 8.5, + //Lambda expression for Consumer inerface + student -> student.feeDiscount = 30.0); + student1.printFee(); //The fee after discount: 1400.0 + + Student student2 = new Student("Rajat","Verma", 8.0); + student2 = updateStudentFee(student2, + //Lambda expression for Predicate interface + student -> student.grade >= 8, + + //Lambda expression for Consumer inerface + //student -> student.feeDiscount = 30.0); + System.out::println); + student2.printFee();//The fee after discount: 1600.0 + + + + + } +} \ No newline at end of file