1) 函数式接口:
如何一个接口只包含一个抽象方法那么这个接口就是函数式接口如:Callable Runnable Comparator .etc
可以通过@FunctionalInterface 注解标识函数式函数式接口(非必须--但是建议)
添加该注解后,如果在接口添加第二个方法编译器会报错。
但是函数式接口允许多个静态方法或者默认方法。
java.util.function包下的所有接口都是函数式接口。
引入函数式接口是为了lamdba设计的,lambda表达式的方法体就是函数式接口的实现。
2) Lambda表达式
>>使用Lambda的语法是匿名内部类的一种简写形式。
>>任何一个只包含抽象方法的接口,我们都可以用来做成Lambda表达式。
>>Lambda表达式的语法结构是: (参数) -> {函数体/方法体} 注:参数类型可以省略
1) 内置功能接口-谓词(predicate)
谓词是但参数的返回Boolean的函数式接口,输入一个参数,返回true or false。同时该接口也包含多个默认方法或静态方法使谓词转换成复杂的逻辑表达式(与、或、非等等)。
如何使用?
1、定义: Predicate<String> p = (String s)->s.length()>0;
2、使用: boolean result = p.test(str);
其他用法: Predicate<String> p2 = (String s)->s.length()<5;
boolean result = p.and(p2).test(str);
默认方法有: and() //与 or() //或 negate() //取反
静态方法: isEqual()
2) 内置功能接口- Function
Function接收一个参数,并产生一个结果,默认方法可以将多个函数串在一起
Function<String,Integer> f = (String s)->Integer.parseInt(s);
Integer i = f.apply(str);
Function<Integer,Integer> f1 = (Integer i1)->i1*3;
Function<Integer,Integer> f2 = (Integer i2)->i2*i2;
Integer result = f1.compose(f2).apply(2);//先算f2 再把结果带入f1
System.out.println(result); //12
Integer result1 = f1.andThen(f2).apply(2);//先算f1 再把结果带入f2
System.out.println(result1); //36
3) 内置功能接口- 生产者(Supplier)
Supplier产生一个给定的泛型类型的结果,与Function不同的是Supplier不接受输入参数。
eg: Supplier<User> s = () -> new User("zn", "123456");
User user = s.get();
4) 内置功能接口-
消费者(Consumer)
Consumer代表在一个单一的输入参数上执行操作,Consumer的操作可能会更改输入参数的内部状态。
eg: Consumer<User> consumer = (User u) -> {
u.setPassword("123");
u.setUsername("defaultname");
};
User user = new User();
consumer.accept(user);
3)方法引用
方法引用是用来直接访问类或者实例已经存在的方法和构造方法。是Lambda表达式的一种简写形式。
如果lambda表达式只是调用一个特定的已经存在的方法,那么可以使用方法引用。
如何lambda的方法体很长,影响代码阅读性,则可以用方法引用来解决。
>>方法引用有四种类型:
1、静态方法引用:ContainingClass::staticMethodName
2、实例方法引用:containingObject::instanceMethodName
3、任意类方法引用: ContainingType::methodName
Collections.sort(list,(o1,o2)->return o1.compareTo(o2);} ); 可以改写为:
Collections.sort(list,String::compareTo); //规则:String方法中的compareTo方法不是static,但是这里可以通过类名::方法名的方式来引用原因是 方法参数有String类型。
4、构造方法引用:ClassName::new
eg: Supplier<User> s = () -> new User();
User user = s.get();
可以简化为 Supplier<User> s = User::new
4)Stream
java.util.stream包下,是对Collection功能的增强,专注于集合对象进行非常便利高效的操作。底层使用的并行化操作,利用Java7中引用的
fork/join框架来拆分业务,加速处理过程,充分利用了多核处理器的优势。
Stream对集合操作可以分为中间操作和末端操作。
1、Filter--接受一个谓词来过滤流中所有的元素。
list.stream().filter((s)->s.length()>=3).forEach((s)->System.out.println(s));
其中filter需要传入一个谓词来过滤满足条件的元素,forEach则需要传入一个消费者来消费集合中的元素,按照需求操作。
2、Sorted--是一个返回流的自然排序的中间运算。除非你传递一个定制的Comparator,元素将被以自然顺序进行排序
list.stream().sorted().forEach((s)->System.out.println(s));
3、Map--中间操作,传入function, 可以将集合中的每个元素通过给定的函数转变为其它对象。
list.stream().map((s)->s.toUpperCase());
4、Match--是一个末端操作,可以用来检查某个Stream是否与一个特定的谓词匹配,返回一个boolean型结果。
>>boolean
result
=
list.stream().anyMatch((s)->s.startsWith("a"));
//是否含有a开头的元素
5、Count--末端操作,以long类型返回在stream中的元素的数目。
long
count
=
list.stream().count();
6、Parallel Stream
使用并行stream可以充分使用多核处理器的优势,提升速度和性能。
list.parallelStream().map((s)->s.toUpperCase());