Lamda 表达式非常方便,在项目中一般在 stream 编程中用的比较多。
List<Student> studentList = gen();
Map<String, Student> map = studentList .stream()
.collect(Collectors.toMap(Student::getId, a -> a, (a, b) -> a));
1. 确认 Lamda 表达式的类型
2. 找到要实现的方法
3. 实现这个方法
确认 Lamda 表达式的类型
@FunctionalInterface
public interface Runnable {
public abstract void run();
}这就是一个标准的函数式接口。 因为只有一个抽象方法。而且这个接口上有个注解
// 没有实现任何抽象方法的接口
@FunctionalInterface
public interface MyRunnable {}
// 编译后控制台显示如下信息
Error:(3, 1) java:
意外的 @FunctionalInterface 注释
MyRunnable 不是函数接口
在 接口 MyRunnable 中找不到抽象方法
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {...}
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {...}
default Predicate<T> negate() {...}
default Predicate<T> or(Predicate<? super T> other) {...}
static <T> Predicate<T> isEqual(Object targetRef) {...}
static <T> Predicate<T> not(Predicate<? super T> target) {...}
}
找到要实现的方法
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {...}
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {...}
default Predicate<T> negate() {...}
default Predicate<T> or(Predicate<? super T> other) {...}
static <T> Predicate<T> isEqual(Object targetRef) {...}
static <T> Predicate<T> not(Predicate<? super T> target) {...}
}
实现这个方法
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length() != 0;
}
};
Predicate<String> predicate =
(String s) -> {
return s.length() != 0;
};看出来了么?这个 Lamda 语法由三部分组成:
参数块:就是前面的 (String s),就是简单地把要实现的抽象方法的参数原封不动写在这。
小箭头:就是 -> 这个符号。
代码块:就是要实现的方法原封不动写在这。
Predicate<String> predicate =
(s) -> {
return s.length() != 0;
};
Predicate<String> predicate =
s -> {
return s.length() != 0;
};
Predicate<String> p = s -> s.length() != 0;
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Runnable r = () -> System.out.println("I am running");
new Thread(() -> System.out.println("I am running")).start();
多个入参
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
// default methods removed
}BiConsumer<Random, Integer> randomNumberPrinter =
(random, number) -> {
for (int i = 0; i < number; i++) {
System.out.println("next random = " + random.nextInt());
}
};
randomNumberPrinter.accept(new Random(314L), 5));@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
// default methods removed
}
// 看个例子
BiFunction<String, String, Integer> findWordInSentence =
(word, sentence) -> sentence.indexOf(word);
发现规律了没
@FunctionalInterface
public interface DoubleFunction<R> {
R apply(double value);
}
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
用我们常见的 Stream 编程熟悉一下
List<Student> studentList = gen();
Map<String, Student> map = studentList .stream()
.collect(Collectors.toMap(Student::getId, a -> a, (a, b) -> a));Collectors.toMap(Student::getId, a -> a, (a, b) -> a)Collectors.toMap(a -> a.getId(), a -> a, (a, b) -> a)
public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction)
{
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
Collectors.toMap(a -> a.getId(), Function.identity(), (a, b) -> a)
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
...
static <T> Function<T, T> identity() {
return t -> t;
}
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
}
Predicate<String> p =
s -> (s != null) &&
!s.isEmpty() &&
s.length() < 5;
Predicate<String> nonNull = s -> s != null;
Predicate<String> nonEmpty = s -> s.isEmpty();
Predicate<String> shorterThan5 = s -> s.length() < 5;
Predicate<String> p = nonNull.and(nonEmpty).and(shorterThan5);方法引用
Function<String, Integer> toLength = s -> s.length();
Function<String, Integer> toLength = String::length;
Function<User, String> getName = user -> user.getName();
Function<String, Integer> toLength = User::getName;
Consumer<String> printer = s -> System.out.println(s);
Consumer<String> printer = System.out::println;
Supplier<List<String>> newListOfStrings = () -> new ArrayList<>();
Supplier<List<String>> newListOfStrings = ArrayList::new;
总结
1. 确认 Lamda 表达式的类型
2. 找到要实现的方法
3. 实现这个方法