Lamda表达式学习笔记一,
Lamda表达式学习笔记一
一、Lamda语法诠释
三傻大闹宝莱坞的主人公兰彻说的一句话让我映像深刻:用简单的语言来表达同样的意
我并不是说书上的定义怎么怎么不对,而是应该理解书本上的定义,并用简单的话语描述!
那么正题来了,lamda表达式是什么?
定义:lamda表达式是一个可传递的代码块,可以在以后执行一次或多次(将代码像数据一样进行传输)。
可传递的代码块?匿名内部类就是一种代码块!
1 /**
2 * 普通匿名函数
3 */
4 @Test
5 public void test() {
6 Comparator<Integer> comparator = new Comparator<Integer>() {
7 @Override
8 public int compare(Integer x, Integer y) {
9 return Integer.compare(x, y);
10 }
11 };
12 TreeSet<Integer> ts = new TreeSet<>(comparator);
13 }
14
15 /**
16 * lamda表达式
17 */
18 @Test
19 public void test1() {
20 Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
21 TreeSet<Integer> ts = new TreeSet<>(comparator);
22 }
证明了lamda语法确实能代替匿名函数,也就意味着lamda表达式需要接口的支持。
需要怎么样的接口来支持lamda表达式呢?这个问题我们后面再说。
二、Lamda语法

分别是
此处的参数列表是接口中抽象方法的形参,lamda体则是对于接口抽象方法的实现,那我们写lamda表达式用接口中哪一个方法?这个问题,jvm是不知道的,所以我们需要的接口就是只有一个抽象方法的接口
函数式接口:只有一个抽象方法的函数,通常函数式接口用@FunctionInterface来声明
三、lamda表达式的表现形式
lamda表达式的4种形式

/**
* 无参->无返回值
*/
@Test
public void test2() {
Runnable runnable = () -> System.out.println("hahahah"
);
runnable.run();
}
View Code
2.无参->有返回值

/**
* 无参->有返回值
*/
@Test
public void test3() {
Supplier<Integer> consumer = () -> 10
;
Integer o =
consumer.get();
System.out.println(o);
}
View Code
3.有参->无返回值

/**
* 有参->无返回值
*/
@Test
public void test4() {
Consumer consumer = (x) ->
System.out.println();
consumer.accept("hahahah"
);
}
View Code
4.有参-有返回值

/**
* 有参->有返回值
*/
@Test
public void test5() {
Function<Integer, Integer> function = (x) -> x *
x;
System.out.println(function.apply(1000
));
}
View Code
四、四大内置函数式接口
这四个接口分别是:Consumer<T>,Supplier<T>,Function<T, R>,Predicate<T>
1.Consumer<T> 消费型接口

@FunctionalInterface
public interface Consumer<T>
{
void accept(T var1);
default Consumer<T> andThen(Consumer<?
super T>
after) {
Objects.requireNonNull(after);
return (t) ->
{
this.accept(t);
after.accept(t);
};
}
}
View Code
2.Supplier<T> 供给型接口

package java.util.function;
@FunctionalInterface
public interface Supplier<T>
{
T get();
}
View Code
3.Function<T, R> 功能型接口

import java.util.Objects;
@FunctionalInterface
public interface Function<T, R>
{
R apply(T var1);
default <V> Function<V, R> compose(Function<?
super V, ?
extends T>
before) {
Objects.requireNonNull(before);
return (v) ->
{
return this.apply(before.apply(v));
};
}
default <V> Function<T, V> andThen(Function<?
super R, ?
extends V>
after) {
Objects.requireNonNull(after);
return (t) ->
{
return after.apply(
this.apply(t));
};
}
static <T> Function<T, T>
identity() {
return (t) ->
{
return t;
};
}
}
View Code
4.Predicate<T> 断言型接口(函数返回值是boolean值)

package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Predicate<T>
{
boolean test(T var1);
default Predicate<T> and(Predicate<?
super T>
other) {
Objects.requireNonNull(other);
return (t) ->
{
return this.test(t) &&
other.test(t);
};
}
default Predicate<T>
negate() {
return (t) ->
{
return !
this.test(t);
};
}
default Predicate<T> or(Predicate<?
super T>
other) {
Objects.requireNonNull(other);
return (t) ->
{
return this.test(t) ||
other.test(t);
};
}
static <T> Predicate<T>
isEqual(Object targetRef) {
return null == targetRef ? Objects::isNull : (object) ->
{
return targetRef.equals(object);
};
}
static <T> Predicate<T> not(Predicate<?
super T>
target) {
Objects.requireNonNull(target);
return target.negate();
}
}
View Code
不仅仅有这4个函数型接口,java8还为我们提供了

最后针对lamda表达式含有3个地方可以优化
1.当只有一个参数时可以不写小括号
2.当lamda体中只有一条语句时可以不用加大括号
3.参数列表可以不用声明参数类型,jvm会根据上下文来分析数据类型(不需要考虑性能问题,因为不论如何我们的.java代码都会进行编译)
侵删,文章仅供大家交流学习,第一次写文章,有不足之处希望大家多多包涵
参考: https://www.bilibili.com/video/av62117143
用户点评