java8的新特性
1.几个常用特性
1.Lambda表达式
2.方法引用
3.默认方法
4.新工具
5.StreamApi
6.Date Time Api
7.Optional 解决了空指针异常
8.Nashorn,javaScript引擎
2.Lambda表达式的基本用法
1.初识:使用Lambda表达式实现一个线程
public static void testRunnable ( ) {
Runnable runnable = new Runnable ( ) {
@Override
public void run ( ) {
log. info ( "aaaaa" ) ;
}
} ;
new Thread ( runnable) . start ( ) ;
Runnable runnable1 = ( ) -> log. info ( "bbbb" ) ;
new Thread ( runnable1) . start ( ) ;
}
2.Lambda表达式的基本用法
-- -- -- -- -- -- -- -- -- -- -- -- -- 原始写法,带一个参数-- -- -- -- -- -- -- -- -- -- -- -- -- --
Consumer < String > consumer1 = new Consumer < String > ( ) {
@Override
public void accept ( String s) {
System . out. println ( "消费数据:" + s) ;
}
} ;
consumer1. accept ( "consumer接口,没用使用lambda表达式" ) ;
-- -- -- -- -- -- -- -- -- Lambda 表达式写法,带一个参数,没有返回值-- -- -- -- -- -- -- -- -- --
Consumer < String > consumer2 = ( String s) -> {
System . out. println ( s) ;
} ;
consumer2. accept ( "consumer接口,使用lambda表达式" ) ;
Consumer < String > consumer3 = ( s) -> {
System . out. println ( s) ;
} ;
consumer3. accept ( "consumer接口,使用lambda表达式,省略参数类型" ) ;
Consumer < String > consumer4 = s -> {
System . out. println ( s) ;
} ;
consumer4. accept ( "consumer接口,使用lambda表达式,省略参数类型,一个参数省略小括号" ) ;
Consumer < String > consumer5 = s -> System . out. println ( s) ;
consumer5. accept ( "consumer接口,使用lambda表达式,省略参数类型,一个参数省略小括号,如果只有一条语句,省略大括号" ) ;
Consumer < String > consumer6 = System . out:: println ;
consumer6. accept ( "consumer接口,使用lambda表达式,省略参数类型,一个参数省略小括号,如果只有一条语句,省略大括号;使用方法引用,省略参数指定" ) ;
-- -- -- -- -- -- -- -- -- Lambda 表达式写法,带多个参数,有返回值-- -- -- -- -- -- -- -- -- --
Comparator < Integer > comparator1 = new Comparator < Integer > ( ) {
@Override
public int compare ( Integer o1, Integer o2) {
return o1. compareTo ( o2) ;
}
} ;
System . out. println ( comparator1. compare ( 12 , 13 ) ) ;
Comparator < Integer > comparator2 = ( o1, o2) -> o1. compareTo ( o2) ;
System . out. println ( comparator2. compare ( 15 , 13 ) ) ;
Comparator < Integer > comparator3 = Integer :: compareTo ;
System . out. println ( comparator3. compare ( 14 , 14 ) ) ;
Comparator < Integer > comparator4 = ( o1, o2) -> {
System . out. println ( "值1:" + o1) ;
System . out. println ( "值1:" + o2) ;
return o1. compareTo ( o2) ;
} ;
System . out. println ( comparator4. compare ( 16 , 18 ) ) ;
3.函数式接口使用
1.消费型函数式接口–Consumer
static void testLambdaConsumer ( ) {
consumData ( 1000 , money -> System . out. println ( "我有1000块,去买彩票" ) ) ;
consumData ( 2000 , money -> {
System . out. println ( "我有2000块,先去网吧打游戏" ) ;
System . out. println ( "我有2000块,打完游戏去超市买东西" ) ;
} ) ;
}
static void consumData ( double money, Consumer < Double > consumer) {
consumer. accept ( money) ;
}
2.供给型函数式接口–Supplier
static void testLambdaSupplier ( ) {
Supplier < String > supplier = ( ) -> "供给自定义数据返回" ;
System . out. println ( supplier. get ( ) ) ;
System . out. println ( getDataBySupplier ( ( ) -> "123" ) ) ;
System . out. println ( getDataBySupplier ( ( ) -> "bdc" ) ) ;
}
static String getDataBySupplier ( Supplier < String > supplier) {
return supplier. get ( ) ;
}
3. 断言型函数式接口 --Predicate
static void testLambdaPredicate ( ) {
List < String > names = Arrays . asList ( "Tom" , "Jack" , "Merry" , "mark" , "LiLei" , "XieQun" ) ;
List < String > namesList1 = collectNamesList ( names, name -> name. contains ( "a" ) ) ;
System . out. println ( namesList1) ;
List < String > namesList2 = collectNamesList ( names, name -> name. contains ( "a" ) || name. contains ( "e" ) ) ;
System . out. println ( namesList2) ;
}
static List < String > collectNamesList ( List < String > names, Predicate < String > predicate) {
List < String > namesList = new ArrayList < > ( ) ;
names. forEach ( name -> {
if ( predicate. test ( name) ) {
namesList. add ( name) ;
}
} ) ;
return namesList;
}
4.函数式接口 --Function
static void testLambdaFunction ( ) {
Function < Double , Long > function1 = d -> Math . round ( d) ;
Long num = function1. apply ( 2346.556 ) ;
System . out. println ( num) ;
}
4.StreamApi
什么是Stream
什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作
元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
1.基本用法
static void testStream1 ( ) {
Stream . of ( 1 , 2 , 3 , 4 , 5 ) . forEach ( i -> System . out. println ( i* i) ) ;
int [ ] nums = { 2 , 33 , 12 , 44 } ;
System . out. println ( Arrays . stream ( nums) . max ( ) . getAsInt ( ) ) ;
Stream . iterate ( 1 , num -> num+ 2 ) . limit ( 10 ) . forEach ( System . out:: println ) ;
Stream . generate ( Math :: random ) . limit ( 10 ) . forEach ( System . out:: println ) ;
}
2.操作集合,集合流遍历
static void testStream2 ( ) {
Stream < Employee > employeeStream = EmployeeUtil . employees. stream ( ) ;
employeeStream. forEach ( employee -> {
if ( employee. getEmpSalary ( ) >= 7000 ) {
System . out. println ( employee) ;
}
} ) ;
}
3.流对集合数据的操作
static void testStream3 ( ) {
Stream < Employee > employeeStream = EmployeeUtil . employees. stream ( ) ;
employeeStream. filter ( employee -> employee. getEmpSalary ( ) >= 6000 ) . filter ( employee -> employee. getEmpAge ( ) <= 30 ) . forEach ( System . out:: println ) ;
System . out. println ( "--------------------------------------" ) ;
Stream < Employee > employeeStream2 = EmployeeUtil . employees. stream ( ) ;
employeeStream2. limit ( 3 ) . forEach ( System . out:: println ) ;
System . out. println ( "--------------------------------------" ) ;
Stream < Employee > employeeStream3 = EmployeeUtil . employees. stream ( ) ;
employeeStream3. skip ( 2 ) . forEach ( System . out:: println ) ;
System . out. println ( "--------------------------------------" ) ;
Stream < Integer > integerStream = Stream . of ( 11 , 22 , 33 , 44 , 55 , 66 , 33 , 44 ) ;
integerStream. distinct ( ) . forEach ( System . out:: println ) ;
List < String > stringList = Arrays . asList ( "tom" , "jack" , "maek" ) ;
stringList. stream ( ) . map ( String :: toUpperCase ) . forEach ( System . out:: println ) ;
Stream < Employee > employeeStream = EmployeeUtil . employees. stream ( ) ;
employeeStream. map ( Employee :: getEmpName ) . filter ( string -> string. length ( ) > 5 ) . forEach ( System . out:: println ) ;
EmployeeUtil . employees. stream ( ) . mapToInt ( emp -> emp. getEmpName ( ) . length ( ) ) . forEach ( System . out:: println ) ;
List < String > stringList = Arrays . asList ( "tom" , "jack" , "maek" ) ;
stringList. stream ( ) . sorted ( ) . forEach ( System . out:: println ) ;
EmployeeUtil . employees. stream ( ) . sorted ( ( e1, e2) -> {
int cmpResult = Integer . compare ( e1. getEmpAge ( ) , e2. getEmpAge ( ) ) ;
if ( cmpResult == 0 ) {
return Double . compare ( e1. getEmpSalary ( ) , e2. getEmpSalary ( ) ) ;
}
return cmpResult;
} ) . forEach ( System . out:: println ) ;
boolean anyMatchFlag = EmployeeUtil . employees. stream ( ) . anyMatch ( emp -> emp. getEmpAge ( ) < 20 ) ;
System . out. println ( "有没有员工年龄小于20岁" + anyMatchFlag) ;
boolean allMatchFlag = EmployeeUtil . employees. stream ( ) . allMatch ( emp -> emp. getEmpSalary ( ) > 4000 ) ;
System . out. println ( "所有人的工资都大于4000》:" + allMatchFlag) ;
boolean noneMatchFlag = EmployeeUtil . employees. stream ( ) . noneMatch ( emp -> emp. getEmpName ( ) . endsWith ( "7" ) ) ;
System . out. println ( "没有人的姓名已7结尾:" + noneMatchFlag) ;
Long userCount = EmployeeUtil . employees. stream ( ) . filter ( emp -> emp. getEmpSalary ( ) > 6000 ) . count ( ) ;
System . out. println ( "员工工资大于6000的有多少人:" + userCount) ;
Optional < Employee > emp1 = EmployeeUtil . employees. stream ( ) . findFirst ( ) ;
System . out. println ( emp1) ;
Optional < Employee > emp2 = EmployeeUtil . employees. stream ( ) . findAny ( ) ;
System . out. println ( emp2) ;
Optional < Double > maxMoney = EmployeeUtil . employees. stream ( ) . map ( Employee :: getEmpSalary ) . max ( Double :: compareTo ) ;
System . out. println ( maxMoney) ;
Optional < Employee > emp3 = EmployeeUtil . employees. stream ( ) . min ( Comparator . comparingDouble ( Employee :: getEmpSalary ) ) ;
System . out. println ( emp3) ;
List < Employee > employees = EmployeeUtil . employees. stream ( ) . filter ( emp -> emp. getEmpAge ( ) > 30 ) . collect ( Collectors . toList ( ) ) ;
employees. forEach ( System . out:: println ) ;
}
集合规约
List < Integer > numList = Arrays . asList ( 1 , 3 , 5 , 7 , 9 ) ;
Optional < Integer > sum1 = numList. stream ( ) . reduce ( ( x, y) -> x+ y ) ;
System . out. println ( sum1) ;
Optional < Integer > sum2 = numList. stream ( ) . reduce ( Integer :: sum ) ;
System . out. println ( sum2) ;
Optional < Integer > sum3 = numList. stream ( ) . reduce ( ( a, b) -> {
System . out. println ( "a=" + b) ;
a += b;
System . out. println ( "b=" + b) ;
System . out. println ( "a_a=" + a) ;
return a;
} ) ;
System . out. println ( sum3) ;
Optional < Double > totalMoney = EmployeeUtil . employees. stream ( ) . map ( Employee :: getEmpSalary ) . reduce ( Double :: sum ) ;
System . out. println ( totalMoney) ;
List < Integer > numList2 = Arrays . asList ( 2 , 4 , 6 , 8 , 10 ) ;
Optional < Integer > sum4 = numList2. stream ( ) . map ( num -> num* num) . reduce ( Integer :: sum ) ;
System . out. println ( sum4) ;
4. streamApi 统计
5.Optional 解决空指针的问题
接受一个指定的元素
Optional<Employee> 解决空指针的问题
6.自定义函数式接口
@FunctionalInterface
public interface MyFunctionInterface {
void sayHi ( String str) ;
default void sayHello ( ) {
System . out. println ( "这个是默认方法,可以通过接口直接调用" ) ;
}
}
测试自定义函数式接口 ,该接口可以带一个参数
static void testFunctionInterface ( MyFunctionInterface myFunctionInterface, String msg) {
myFunctionInterface. sayHi ( msg) ;
myFunctionInterface. sayHello ( ) ;
}