Home Java8(一):Lambda表达式-函数式接口
Post
Cancel

Java8(一):Lambda表达式-函数式接口

Java supports anonymous functions, named Lambda Expressions, starting with JDK 8.

Lambda Expressions, a new language feature, has been introduced in this release. They enable you to treat functionality as a method argument, or code as data. Lambda expressions let you express instances of single-method interfaces (referred to as functional interfaces) more compactly.

Java8开始支持匿名函数,又叫Lambda表达式。

Lambda表达式允许函数作为方法参数,并且可以让单方法接口(也叫函数式接口)的表达更为紧凑。

Lambda表达式Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// with no parameter
() -> System.out.println("Hello, world.")

// with one parameter (this example is an identity function).
a -> a

// with one expression
(a, b) -> a + b

// with explicit type information
(long id, String name) -> "id: " + id + ", name:" + name

// with a code block
(a, b) -> { return a + b; }

// with multiple statements in the lambda body. It needs a code block.
// This example also includes two nested lambda expressions (the first one is also a closure).
(id, defaultPrice) -> {
  Optional<Product> product = productList.stream().filter(p -> p.getId() == id).findFirst();
  return product.map(p -> p.getPrice()).orElse(defaultPrice);
}

函数式接口

A functional interface is any interface that contains only one abstract method.

函数式接口:任何只有一个抽象方法的接口。

函数式接口可以被隐式转换为 lambda 表达式。

定义一个函数式接口如下:

1
2
3
interface GreetingService {
    void sayMessage(String message);
}

可以使用Lambda表达式来表示该接口的一个实现:

1
2
GreetingService greetService = message -> System.out.println("Hello " + message);
greetService.sayMessage("world!");

Java8使用Lambda时,需要声明函数式接口。因此,JDK设计人员内置了四大核心函数式接口。

1、消费型接口Consumer< T >

消费型接口:有参数,无返回值。

1
2
3
4
5
@Test
public void testConsumer() {
  Consumer<Double> consumer = m -> System.out.format("买苹果花费:%.1f元\n", m);
  consumer.accept(1.1);
}

2、供给型接口Supplier< T >

供给型接口:无参数,有返回值。

1
2
3
4
5
@Test
public void testSupplier() {
  Supplier<Double> supplier = () -> Math.random() * 10;
  System.out.format("卖苹果盈利:%.1f元\n", supplier.get());
}

3、函数型接口Function< T, R >

函数型接口:有参数,有返回值。

1
2
3
4
5
6
@Test
public void testFunction() {
  Function<String, String> function = (s1) -> StringUtils.upperCase(s1);
  String name = "Jeff";
  System.out.format("名字:%s,大写是:%s", name, function.apply(name));
}

4、断言型接口Predicate< T >

断言型接口:有参数,返回值为布尔值。

1
2
3
4
5
6
7
8
9
10
@Test
public void testPredicate() {
  Predicate<String> predicate = (s1) -> StringUtils.length(s1) >= 5;
  List<String> names = Arrays.asList(new String[]{"Army", "Luna", "Elle", "Katherine"});
  for (String name : names) {
    if (predicate.test(name)) {
      System.out.println(name);
    }
  }
}

5、四大核心函数式接口补充

四大核心函数式接口,除了核心的抽象方法外,还有几个有意思的默认、静态方法。

Predicate:增加了逻辑运算方法,这样就可以把很多断言型接口串起来。

1
2
3
4
5
6
7
8
9
10
# 
default Predicate<T> and(Predicate<? super T> other)
# 
default Predicate<T> negate()
# 
default Predicate<T> or(Predicate<? super T> other)
# 根据equal方法判断两个对象是否相等
static <T> Predicate<T> isEqual(Object targetRef)
# 
static <T> Predicate<T> not(Predicate<? super T> target)

Consumer:增加了andThen方法,可以把多个消费型接口串起来。

1
default Consumer<T> andThen(Consumer<? super T> after)

Function:增加了前序、后续函数。

1
2
3
4
# V -> T, T -> R
default <V> Function<V, R> compose(Function<? super V, ? extends T> before)
# T -> R, R -> V
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after)
This post is licensed under CC BY 4.0 by the author.