内容简介:Java8回忆录 - Lambda
本文主要介绍 Java8
的 Lambda
表达式
基本语法
(parameters) -> expression
(parameters) -> {statements;}
Apple
相关代码托管在 java8_demo
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Apple{
public static enum COLOR { GREEN, RED }
public static final int HEAVY_WEIGHT = 200;
private COLOR color;
private Integer weight;
}
实例
(String s) -> s.length()
// 等价于
int f(String s){ return s.length(); }
(Apple a) -> a.getWeight() > Apple.HEAVY_WEIGHT
// 等价于
boolean f(Apple a){ return a.getWeight() > Apple.HEAVY_WEIGHT; }
(int x, int y) -> {
System.out.println("Result:");
Syetem.out.println(x+y;
}
// 等价于
void f(intx,inty){
System.out.println("Result:");
Syetem.out.println(x+y;
}
() -> 42
// 等价于
int f(){ return 42; }
(Apple a1 , Apple a2) -> a1.getWeight() > a2.getWeight
// 等价于
boolean f(Apple a1 , Apple a2){ return a1.getWeight() > a2.getWeight;}
函数式接口 + 函数描述符
函数式接口
-
定义:只定义了
一个抽象方法(排除default方法)的接口 -
用途:
Lambda表达式允许直接以内联的形式,为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例
函数描述符
-
定义:
函数式接口的抽象方法的签名 -
函数描述符=函数式接口的抽象方法的签名=Lambda表达式的签名
Lambda 出现的地方
-
赋值给一个变量(类型为
函数式接口) -
传递给一个接受
函数式接口为参数的方法
自定义函数式接口
函数式接口
@FunctionalInterface
public interface Change{ // 只有一个抽象方法
Integeraction(Integer param);
}
函数描述符: Integer -> Integer
单元测试
private int localChange(intparam, Change change){
return change.action(param);
}
@Test
public void multipyTest(){
// Lambda 能够赋值给一个函数式接口的变量(前提是函数式接口的抽象方法的签名 = Lambda 表达式的签名)
Change multiply = param -> param * 3;
assertEquals(15, localChange(5, multiply));
// Lambda 能够传递给一个接受函数式接口为参数的方法(前提是函数式接口的抽象方法的签名 = Lambda 表达式的签名)
assertEquals(4, localChange(3, param -> param + 1));
}
常用内置函数式接口
| 函数式接口 | 函数描述符 |
|---|---|
Predicate<T>
|
T -> boolean |
Consumer<T>
|
T -> void |
Supplier<T>
|
() -> T |
Function<T,R>
|
T -> R |
BiFunction<T,U,R>
|
(T,U) -> R |
BiPredicate<T,U>
|
(T,U) -> boolean |
BinaryOperator<T> extends BiFunction<T,T,T>
|
(T,T) -> T |
BiConsumer<T,U>
|
(T,U) -> void |
UnaryOperator<T> extends Function<T,T>
|
T -> T |
Predicate
定义
@FunctionalInterface
public interface Predicate<T>{
boolean test(T t);
}
函数描述符: T -> boolean
实例
private <T> List<T>predicate(List<T> list, Predicate<T> predicate){
List<T> result = new ArrayList<>();
for (T t : list) {
if (predicate.test(t)) {
result.add(t);
}
}
return result;
}
@Test
public void predicateTest(){
assertEquals(2, predicate(Arrays.asList("zhongmingmao", "", null),
s -> null == s || s.isEmpty()).size());
}
Consumer
定义
@FunctionalInterface
public interface Consumer<T>{
void accept(T t);
}
函数描述符: T -> void
实例
private <T> void consume(List<T> list, Consumer<T> consumer){
for (T t : list) {
consumer.accept(t);
}
}
@Test
public void consumerTest(){
consume(Arrays.asList(1, 2, 3), integer -> System.out.println(integer));
}
Supplier
定义
@FunctionalInterface
public interface Supplier<T>{
Tget();
}
函数描述符: () -> T
实例
private <T> Tsupply(Supplier<T> supplier){
return supplier.get();
}
@Test
public void supplierTest(){
assertEquals(LocalDate.now(), supply(() -> LocalDate.now()));
}
Function
定义
@FunctionalInterface
public interface Function<T,R>{
Rapply(T t);
}
函数描述符: T -> R
实例
private <T, R> Rfunction(T t, Function<T, R> func){
return func.apply(t);
}
@Test
public void functionTest(){
assertEquals(Integer.valueOf(12), function(Integer.valueOf(4), integer -> integer * 3));
}
BiFunction
定义
@FunctionalInterface
public interface BiFunction<T,U,R>{
Rapply(T t, U u);
}
函数描述符: (T,U) -> R
实例
private <T, U, R> RbiFunction(T t, U u, BiFunction<T, U, R> biFunc){
return biFunc.apply(t, u);
}
@Test
public void biFunctionTest(){
assertEquals("40", biFunction(4, "0", (integer, s) -> integer + s));
}
BiPredicate
定义
@FunctionalInterface
public interface BiPredicate<T,U>{
boolean test(T t, U u);
}
函数描述符: (T,U) -> boolean
实例
private <T, U> boolean biPredicate(T t, U u, BiPredicate<T, U> biPred){
return biPred.test(t, u);
}
@Test
public void biPredicateTest(){
assertTrue(biPredicate(4, "zhognmingmao", (integer, s) -> null != s && s.length() > integer));
}
BinaryOperator
定义
@FunctionalInterface
public interface BinaryOperator<T>extends BiFunction<T,T,T>{
}
函数描述符: (T,T) -> T
实例
private <T> TbinaryOperator(T t, BinaryOperator<T> bOp){
return bOp.apply(t, t);
}
@Test
public void binaryOperatorTest(){
assertEquals(Integer.valueOf(16), binaryOperator(4, (integer, integer2) -> integer * integer2));
}
BiConsumer
定义
@FunctionalInterface
public interface BiConsumer<T,U>{
void accept(T t, U u);
}
函数描述符: (T,U) -> void
实例
private <T, U> void biConsumer(T t, U u, BiConsumer<T, U> bCon){
bCon.accept(t, u);
}
@Test
public void biConsumerTest(){
biConsumer(4, "zhongmingmao", (integer, s) -> System.out.println(integer + s.length()));
}
UnaryOperator
定义
@FunctionalInterface
public interface UnaryOperator<T>extends Function<T,T>{
}
函数描述符: T -> T
实例
private <T> TunaryOperator(T t, UnaryOperator<T> uOp){
return uOp.apply(t);
}
@Test
public void unaryOperatorTest(){
assertEquals("zhongmingmao" , unaryOperator("zhongming" , s -> s + "mao"));
}
IntPredicate
-
IntPredicate是Predicate<Integer>的原始类型特化,节省了自动装箱和自动拆箱的开销 -
类似函数式接口的还有
LongPredicate、IntFunction<R>等
定义
@FunctionalInterface
public interface IntPredicate{
boolean test(intvalue);
}
实例
@Test
public void intPredicateTest(){
IntPredicate intPredicate = value -> value % 2 == 0;
Predicate<Integer> integerPredicate = integer -> integer % 2 == 0;
int max = 1 << 30;
long p1 = System.currentTimeMillis();
for (int i = 0; i < max; i++) {
intPredicate.test(i);
}
long p2 = System.currentTimeMillis();
for (int i = 0; i < max; i++) {
integerPredicate.test(i);
}
long p3 = System.currentTimeMillis();
System.out.println((p3 - p2) / (p2 - p1 + 0.0)); // 本地结果在100~220之间
assertTrue((p3 - p2) > (p2 - p1));
}
类型检查
引用上面的例子进行分析
// 函数定义
private <T> List<T>predicate(List<T> list, Predicate<T> predicate){...}
// 函数调用
predicate(Arrays.asList("zhongmingmao", "", null), s -> null == s || s.isEmpty()).size());
-
函数定义中形参为
Predicate<T> predicate -
Predicate<T>中的抽象函数的签名为boolean test(T t),因此Predicate<T>的函数描述符为T -> boolean -
函数调用中
Lambda的签名为String -> boolean与Predicate<T>的函数描述符匹配,类型检查通过
方法引用
方法引用
是 Lambda
的一种 快捷写法
(
语法糖
)
静态方法
-
Lambda:
(args) -> ClassName.staticMethod(args) -
方法引用:
ClassName::staticMethod
Function<String, Integer> str2Integer = s -> Integer.parseInt(s); str2Integer = Integer::parseInt;
任意类型的实例方法
-
Lambda:
(arg0,rest) -> arg0.instanceMethod(rest)(arg0是ClassName类型) -
方法引用:
ClassName::instanceMethod
BiPredicate<List<String>, String> contains = (strings, s) -> strings.contains(s); contains = List::contains;
现有对象的实例方法
-
Lambda:
(args) -> expr.instanceMethod(args) -
方法引用:
expr::instanceMethod
List<String> list = Arrays.asList("a", "b", "A", "B");
Predicate<String> contain = s -> list.contains(s);
contain = list::contains;
构造函数
Supplier<Apple> c1 = () -> new Apple(); c1 = Apple::new;// 默认构造函数 Apple apple = c1.get(); BiFunction<Apple.COLOR, Integer, Apple> c2 = (color, integer) -> new Apple(color, integer); c2 = Apple::new;// 2个参数构造函数 apple = c2.apply(Apple.COLOR.GREEN, Integer.valueOf(200));
复合Lambda
Comparator复合
@FunctionalInterface
public interface Comparator<T>{
int compare(T o1, T o2);
}
// <T, U extends Comparable<? super U>> Comparator<T> comparing(
// Function<? super T, ? extends U> keyExtractor)
Comparator<Apple> comparator = Comparator.comparing(Apple::getWeight); // Apple -> Integer
Comparator<Apple> reversedComparetor = comparator.reversed();
Comparator<Apple> linkedComparator = Comparator.comparing(Apple::getWeight).reversed()
.thenComparing(Apple::getColor).reversed();
Predicate复合
Predicate<Apple> greenApple = apple -> Apple.COLOR.GREEN.equals(apple.getColor()); Predicate<Apple> notGreenApple = greenApple.negate(); Predicate<Apple> heavyApple = apple -> apple.getWeight() > Apple.HEAVY_WEIGHT; Predicate<Apple> greenAndHeavyApple = greenApple.and(heavyApple); Predicate<Apple> redApple = apple -> Apple.COLOR.RED.equals(apple.getColor()); Predicate<Apple> greenAndHeavyOrRedApple = greenAndHeavyApple.or(redApple); // 优先级从左至右,(red or green) and heavy Predicate<Apple> redOrGreenAndHeavyApple = redApple.or(greenApple).and(heavyApple);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 低成本“全栈”回忆录
- 一个 Java 对象的回忆录:垃圾回收
- 我的本科回忆录:从迷茫自卑到保送华科
- CSS :visited伪类选择器隐秘往事回忆录
- HBase 抗战总结:阿里巴巴 HBase 高可用 8 年抗战回忆录
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java JDK6学习笔记
林信良 / 清华大学出版社 / 2007-4 / 59.90元
《Java JDK6学习笔记》是作者良葛格本人近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型、J2SE中标准的API等均进行了详细介绍。本书还安排了一个“文字编辑器”的专题制作。此外,Java SE6的新功能,对Java lang等套件的功能加强,以及JDBC4.0、......一起来看看 《Java JDK6学习笔记》 这本书的介绍吧!