Lambda表达式
1、Lambda语法
2、Lambda使用
使用前:
Comparator < Apple > byWeight = new Comparator < Apple > ( ) {
public int compare ( Apple a1, Apple a2) {
return a1. getWeight ( ) . compareTo ( a2. getWeight ( ) ) ;
}
}
使用后:
Comparator < Apple > byWeight =
( Apple a1, Apple a2) -> a1. getWeight ( ) . compareTo ( a2. getWeight ( ) ) ;
3、函数式接口
只定义一个抽象方法的接口,函数式接口带有@FunctionalInterface标注
函数式接口 函数描述符 Predicate T->boolean Consumer T->void Function<T,R> T->R Supplier ()->T UnaryOperator T->T BinaryOperator (T,T)->T BiPredicate<L,R> (L,R)->boolean BiConsumer<T,U> (T,U)->void BiFunction<T,U,R> (T,U)->R
4、函数式接口例子
使用案例 lambda表达式 函数式接口 布尔表达式 (List list) -> list.isEmpty() Predicate<List> 创建对象 () -> new Apple(10) Supplier 消费一个对象 (Apple a) -> System.out.println(a.getWeight()) Consumer 从一个对象中选择/提取 (String s) -> s.length() Function<String, Integer>或ToIntFunction 合并两个值 (int a, int b) -> a*b IntBinaryOperator 比较两个对象 (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()) Comparator或BiFunction<Apple, Apple,Integer>或 ToIntBiFunction<Apple,Apple>
方法引用
1、指向静态方法的方法引用
Integer :: parseInt
2、指向任意类型实例方法的方法引用
String :: length
3、指向现有对象的实例方法的方法引用
expensiveTransaction:: getValue
构造函数引用
1、不带参数构造函数
Supplier < Apple > c1 = Apple :: new ;
Apple a1 = c1. get ( ) ;
Supplier < Apple > c1 = ( ) -> new Apple ( ) ;
Apple a1 = c1. get ( ) ;
2、带参数构造函数
Function < Integer , Apple > c2 = Apple :: new ;
Apple a2 = c2. get ( 110 ) ;
Function < Integer , Apple > c2 = ( weight) -> new Apple ( weight) ;
Apple a2 = c2. get ( 110 ) ;
复合Lambda表达式
1、比较器复合
1.1 逆序
inventory. sort ( Comparator . comparing ( Apple :: getWeight ) . reversed ( ) ) ;
1.2 比较器链
inventory. sort ( comparing ( Apple :: getWeight )
. reversed ( )
. thenComparing ( Apple :: getCountry ) ) ;
2、谓词复合
2.1 非
Predicate < Apple > notRedApple = redApple. negate ( ) ;
2.2 与
Predicate < Apple > redAndHeavyApple =
redApple. and ( a -> a. getWeight ( ) > 150 ) ;
2.3 或
Predicate < Apple > redAndHeavyAppleOrGreen =
redApple. and ( a -> a. getWeight ( ) > 150 )
. or ( a -> "green" . equals ( a. getColor ( ) ) ) ;
3、函数复合
3.1 andThen
Function < Integer , Integer > f = x -> x + 1 ;
Function < Integer , Integer > g = x -> x * 2 ;
Function < Integer , Integer > h = f. andThen ( g) ;
int result = h. apply ( 1 ) ;
3.2 compose
Function < Integer , Integer > f = x -> x + 1 ;
Function < Integer , Integer > g = x -> x * 2 ;
Function < Integer , Integer > h = f. compose ( g) ;
int result = h. apply ( 1 ) ;
流操作
1、中间操作
操作 类型 返回类型 操作参数 filter 中间 Stream Predicate map 中间 Stream Function<T,R> limit 中间 Stream sorted 中间 Stream Comparator distinct 中间 Stream
2、终端操作
操作 类型 目的 forEach 终端 消费流中的每个元素并对其应用Lambda。这一操作返回void count 终端 返回流中元素的个数。这一操作返回long collect 终端 把流归约成一个集合,比如List、Map甚至是Integer
使用流
1、筛选
List < Dish > vegetarianMenu = menu. stream ( )
. filter ( Dish :: isVegetarian )
. collect ( toList ( ) ) ;
List < Integer > numbers = Arrays . asList ( 1 , 2 , 1 , 3 , 3 , 2 , 4 ) ;
numbers. stream ( )
. filter ( i -> i % 2 == 0 )
. distinct ( )
. forEach ( System . out:: println ) ;
2、截断
List < Dish > dishes = menu. stream ( )
. filter ( d -> d. getCalories ( ) > 300 )
. limit ( 3 )
. collect ( toList ( ) ) ;
3、跳过
List < Dish > dishes = menu. stream ( )
. filter ( d -> d. getCalories ( ) > 300 )
. skip ( 2 )
. collect ( toList ( ) ) ;
4、映射
List < String > dishNames = menu. stream ( )
. map ( Dish :: getName )
. collect ( toList ( ) ) ;
List < String > words = Arrays . asList ( "Java 8" , "Lambdas" , "In" , "Action" ) ;
List < Integer > wordLengths = words. stream ( )
. map ( String :: length )
. collect ( toList ( ) ) ;
5、流扁平化
List < String > uniqueCharacters =
words. stream ( )
. map ( w -> w. split ( "" ) )
. flatMap ( Arrays :: stream )
. distinct ( )
. collect ( Collectors . toList ( ) ) ;
6、匹配
boolean isHealthy = menu. stream ( )
. allMatch ( d -> d. getCalories ( ) < 1000 ) ;
boolean isHealthy = menu. stream ( )
. noneMatch ( d -> d. getCalories ( ) >= 1000 ) ;
7、查找
Optional < Dish > dish =
menu. stream ( )
. filter ( Dish :: isVegetarian )
. findAny ( ) ;
8、归约
int sum = numbers. stream ( ) . reduce ( 0 , ( a, b) -> a + b) ;
int sum = numbers. stream ( ) . reduce ( 0 , Integer :: sum ) ;
Optional < Integer > sum = numbers. stream ( ) . reduce ( ( a, b) -> ( a + b) ) ;
Optional < Integer > max = numbers. stream ( ) . reduce ( Integer :: max ) ;
Optional < Integer > min = numbers. stream ( ) . reduce ( Integer :: min ) ;
9、汇总
int totalCalories = menu. stream ( ) . collect ( summingInt ( Dish :: getCalories ) ) ;
double avgCalories =
menu. stream ( ) . collect ( averagingInt ( Dish :: getCalories ) ) ;
IntSummaryStatistics menuStatistics =
menu. stream ( ) . collect ( summarizingInt ( Dish :: getCalories ) ) ;
10、分组
Map < Dish. Type , List < Dish > > dishesByType =
menu. stream ( ) . collect ( groupingBy ( Dish :: getType ) ) ;
11、多级分组
Map < Dish. Type , Map < CaloricLevel , List < Dish > > > dishesByTypeCaloricLevel =
menu. stream ( ) . collect (
groupingBy ( Dish :: getType ,
groupingBy ( dish -> {
if ( dish. getCalories ( ) <= 400 ) return CaloricLevel . DIET ;
else if ( dish. getCalories ( ) <= 700 ) return CaloricLevel . NORMAL ;
else return CaloricLevel . FAT ;
} )
)
) ;
12、分区
Map < Boolean , List < Dish > > partitionedMenu =
menu. stream ( ) . collect ( partitioningBy ( Dish :: isVegetarian ) ) ;
创建流
1、数值流
int calories = menu. stream ( )
. mapToInt ( Dish :: getCalories )
. sum ( ) ;
IntStream intStream = menu. stream ( ) . mapToInt ( Dish :: getCalories ) ;
Stream < Integer > stream = intStream. boxed ( ) ;
IntStream evenNumbers = IntStream . rangeClosed ( 1 , 100 )
. filter ( n -> n % 2 == 0 ) ;
IntStream evenNumbers = IntStream . range ( 1 , 100 )
. filter ( n -> n % 2 == 0 ) ;
2、创建流
Stream < String > stream = Stream . of ( "Java 8 " , "Lambdas " , "In " , "Action" ) ;
int [ ] numbers = { 2 , 3 , 5 , 7 , 11 , 13 } ;
int sum = Arrays . stream ( numbers) . sum ( ) ;
Stream . iterate ( 0 , n -> n + 2 )
. limit ( 10 )
. forEach ( System . out:: println ) ;
Stream . generate ( Math :: random )
. limit ( 5 )
. forEach ( System . out:: println ) ;
try ( Stream < String > lines =
Files . lines ( Paths . get ( "data.txt" ) , Charset . defaultCharset ( ) ) ) {
uniqueWords = lines. flatMap ( line -> Arrays . stream ( line. split ( " " ) ) )
. distinct ( )
. count ( ) ;
}
catch ( IOException e) {
}
并行流
Stream . iterate ( 1L , i -> i + 1 )
. limit ( n)
. parallel ( )
. reduce ( 0L , Long :: sum ) ;
Fork-Join并行任务
public class ForkJoinSumCalculator extends RecursiveTask < Long > {
private final long [ ] numbers;
private final int start;
private final int end;
public ForkJoinSumCalculator ( long [ ] numbers) {
this ( numbers, 0 , numbers. length) ;
}
public ForkJoinSumCalculator ( long [ ] numbers, int start, int end) {
this . numbers = numbers;
this . start = start;
this . end = end;
}
public static final long THRESHOLD = 10_000 ;
@Override
protected Long compute ( ) {
int length = end - start;
if ( length <= THRESHOLD ) {
return computeSequentially ( ) ;
}
ForkJoinSumCalculator leftTask =
new ForkJoinSumCalculator ( numbers, start, start+ length/ 2 ) ;
leftTask. fork ( ) ;
ForkJoinSumCalculator rightTask =
new ForkJoinSumCalculator ( numbers, start+ length/ 2 , end) ;
long rightResult = rightTask. compute ( ) ;
long leftResult = leftTask. join ( ) ;
return leftResult + rightResult;
}
private Long computeSequentially ( ) {
long sum = 0 ;
for ( int i= start; i< end; i++ ) {
sum += numbers[ i] ;
}
return sum;
}
public static long forkJoinSum ( long n) {
long [ ] numbers = LongStream . rangeClosed ( 1 , n) . toArray ( ) ;
ForkJoinTask < Long > task = new ForkJoinSumCalculator ( numbers) ;
return new ForkJoinPool ( ) . invoke ( task) ;
}
}
Optional使用
创建Optional对象
1、声明一个空的optional
Optional < Car > optCar = Optional . empty ( ) ;
2、依据一个非空值创建Optional
Optional < Car > optCar = Optional . of ( car) ;
3、可接受null的Optional
Optional < Car > optCar = Optional . ofNullable ( car) ;
map从Optional对象中提取和转换值
Optional < Insurance > optInsurance = Optional . ofNullable ( insurance) ;
Optional < String > name = optInsurance. map ( Insurance :: getName ) ;
floatMap链接Optional对象
public String getCarInsuranceName ( Optional < Person > person) {
return person. flatMap ( Person :: getCar )
. flatMap ( Car :: getInsurance )
. map ( Insurance :: getName )
. orElse ( "Unknown" ) ;
}
public Optional < Insurance > nullSafeFindCheapestInsurance (
Optional < Person > person, Optional < Car > car) {
return person. flatMap ( p -> car. map ( c -> findCheapestInsurance ( p, c) ) ) ;
}
对Optional对象过滤
public String getCarInsuranceName ( Optional < Person > person, int minAge) {
return person. filter ( p -> p. getAge ( ) >= minAge)
. flatMap ( Person :: getCar )
. flatMap ( Car :: getInsurance )
. map ( Insurance :: getName )
. orElse ( "Unknown" ) ;
}
CompletableFuture异步编程
使用异步api
public Future < Double > getPriceAsync ( String product) {
CompletableFuture < Double > futurePrice = new CompletableFuture < > ( ) ;
new Thread ( ( ) -> {
double price = calculatePrice ( product) ;
futurePrice. complete ( price) ;
} ) . start ( ) ;
return futurePrice;
}
使用工厂方法创建
public Future < Double > getPriceAsync ( String product) {
return CompletableFuture . supplyAsync ( ( ) -> calculatePrice ( product) ) ;
}
使用定制执行器
private final Executor executor =
Executors . newFixedThreadPool ( Math . min ( shops. size ( ) , 100 ) ,
new ThreadFactory ( ) {
public Thread newThread ( Runnable r) {
Thread t = new Thread ( r) ;
t. setDaemon ( true ) ;
return t;
}
} ) ;
CompletableFuture . supplyAsync ( ( ) -> shop. getName ( ) + " price is " +
shop. getPrice ( product) , executor) ;
构造异步操作
public List < String > findPrices ( String product) {
List < CompletableFuture < String > > priceFutures =
shops. stream ( ) . map ( shop -> CompletableFuture . supplyAsync (
( ) -> shop. getPrice ( product) , executor) )
. map ( future -> future. thenApply ( Quote :: parse ) )
. map ( future -> future. thenCompose ( quote ->
CompletableFuture . supplyAsync ( ( ) -> Discount . applyDiscount ( quote) , executor) ) ) . collect ( toList ( ) ) ;
return priceFutures. stream ( ) . map ( CompletableFuture :: join ) . collect ( toList ( ) ) ;
}
异步优化
public Stream < CompletableFuture < String > > findPricesStream ( String product) {
return shops. stream ( )
. map ( shop -> CompletableFuture . supplyAsync ( ( ) -> shop. getPrice ( product) , executor) )
. map ( future -> future. thenApply ( Quote :: parse ) )
. map ( future -> future. thenCompose (
quote -> CompletableFuture . supplyAsync ( ( ) -> Discount . applyDiscount ( quote) , executor) ) ) ;
}
CompletableFuture [ ] futures = findPricesStream ( "myPhone" )
. map ( f -> f. thenAccept ( System . out:: println ) )
. toArray ( size -> new CompletableFuture [ size] ) ;
CompletableFuture . allOf ( futures) . join ( ) ;
日期时间API
LocalDate使用
LocalDate date = LocalDate . of ( 2014 , 3 , 18 ) ;
int year = date. getYear ( ) ;
Month month = date. getMonth ( ) ;
int day = date. getDayOfMonth ( ) ;
DayOfWeek dow = date. getDayOfWeek ( ) ;
int len = date. lengthOfMonth ( ) ;
boolean leap = date. isLeapYear ( ) ;
LocalDate today = LocalDate . now ( ) ;
int year = date. get ( ChronoField . YEAR ) ;
int month = date. get ( ChronoField . MONTH_OF_YEAR ) ;
int day = date. get ( ChronoField . DAY_OF_MONTH ) ;
LocalDate date = LocalDate . parse ( "2014-03-18" ) ;
LocalTime使用
LocalTime time = LocalTime . of ( 13 , 45 , 20 ) ;
int hour = time. getHour ( ) ;
int minute = time. getMinute ( ) ;
int second = time. getSecond ( ) ;
LocalTime time = LocalTime . parse ( "13:45:20" ) ;
LocalDateTime使用
LocalDate date = LocalDate . of ( 2014 , Month . SEPTEMBER , 21 ) ;
LocalTime time = LocalTime . of ( 10 , 1 , 0 ) ;
LocalDateTime dt1 = LocalDateTime . of ( 2014 , Month . SEPTEMBER , 21 , 10 , 0 , 0 ) ;
LocalDateTime dt2 = LocalDateTime . of ( date, time) ;
LocalDateTime dt3 = date. atTime ( time) ;
LocalDateTime dt4 = date. atTime ( 10 , 1 , 0 ) ;
LocalDateTime dt5 = time. atDate ( date) ;
LocalDate date1 = dt1. toLocalDate ( ) ;
LocalTime time1 = dt1. toLocalTime ( ) ;
日期解析、格式化
LocalDate date1 = LocalDate . of ( 2022 , 11 , 21 ) ;
LocalDate date2 = date1. withYear ( 2011 ) ;
LocalDate date3 = date2. withDayOfMonth ( 25 ) ;
LocalDate date4 = date3. with ( ChronoField . MONTH_OF_YEAR , 9 ) ;
LocalDate date5 = LocalDate . of ( 2022 , 11 , 21 ) ;
LocalDate date6 = date5. plusWeeks ( 1 ) ;
LocalDate date7 = date6. minusYears ( 3 ) ;
LocalDate date8 = date7. plus ( 6 , ChronoUnit . MINUTES ) ;
TemporalAdjuster使用
import static java. time. temporal. TemporalAdjusters . * ;
LocalDate date1 = LocalDate . of ( 2014 , 3 , 18 ) ;
LocalDate date2 = date1. with ( nextOrSame ( DayOfWeek . SUNDAY ) ) ;
LocalDate date3 = date2. with ( lastDayOfMonth ( ) ) ;
方法名 描述 firstDayOfMonth 创建一个新的日期,它的值为当月的第一天 firstDayOfNextMonth 创建一个新的日期,它的值为下月的第一天 dayOfWeekInMonth 创建一个新的日期,它的值为同一个月中每一周的第几天 firstDayOfNextYear 创建一个新的日期,它的值为明年的第一天 firstDayOfYear 创建一个新的日期,它的值为当年的第一天 firstInMonth 创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值 lastDayOfMonth 创建一个新的日期,它的值为当月的最后一天 lastDayOfNextMonth 创建一个新的日期,它的值为下月的最后一天 lastDayOfNextYear 创建一个新的日期,它的值为明年的最后一天 lastDayOfYear 创建一个新的日期,它的值为今年的最后一天 lastInMonth 创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值 next/previous 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星 nextOrSame/previousOrSame 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星
日期打印输出
LocalDate date = LocalDate . of ( 2014 , 3 , 18 ) ;
String s1 = date. format ( DateTimeFormatter . BASIC_ISO_DATE ) ;
String s2 = date. format ( DateTimeFormatter . ISO_LOCAL_DATE ) ;
LocalDate date1 = LocalDate . parse ( "20140318" , DateTimeFormatter . BASIC_ISO_DATE ) ;
LocalDate date2 = LocalDate . parse ( "2014-03-18" , DateTimeFormatter . ISO_LOCAL_DATE ) ;
DateTimeFormatter formatter = DateTimeFormatter . ofPattern ( "dd/MM/yyyy" ) ;
LocalDate date1 = LocalDate . of ( 2014 , 3 , 18 ) ;
String formattedDate = date1. format ( formatter) ;
LocalDate date2 = LocalDate . parse ( formattedDate, formatter) ;
DateTimeFormatter italianFormatter =
DateTimeFormatter . ofPattern ( "d. MMMM yyyy" , Locale . ITALIAN ) ;
LocalDate date1 = LocalDate . of ( 2014 , 3 , 18 ) ;
String formattedDate = date. format ( italianFormatter) ;
LocalDate date2 = LocalDate . parse ( formattedDate, italianFormatter) ;