专业编程基础技术教程

网站首页 > 基础教程 正文

java8函数式接口

ccvgpt 2024-11-30 19:17:17 基础教程 1 ℃

Java 8在java.util.function包中引入了几个新的函数式接口:Predicate、Consumer和Function

一、Predicate 断言

java8函数式接口

java.util.function.Predicate<T>接口定义了一个名叫test的抽象方法,它接受泛型T对象,并返回一个boolean。在你需要表示一个涉及类型T的布尔表达式时,就可以使用这个接口。比如,你可以定义一个接String对象的Lambda表达式,如下所示。

package java.util.function;

import java.util.Objects;

@FunctionalInterface

public interface Predicate<T> {

/**

* Evaluates this predicate on the given argument.

*

* @param t the input argument

* @return {@code true} if the input argument matches the predicate,

* otherwise {@code false}

*/

boolean test(T t);

}

使用举例

List<String> listOfStrings = Arrays.asList("hello", "java", "", "apple");

List<String> nonEmpty = filter(listOfStrings, s -> !s.isEmpty());

System.out.println(nonEmpty); // [hello, java, apple]

二、.Consumer 消费者,没有返回值

java.util.function.Consumer<T>定义了一个名叫accept的抽象方法,它接受泛型T的对象,没有返回(void)。你如果需要访问类型T的对象,并对其执行某些操作,就可以使用这个接口。

package java.util.function;

import java.util.Objects;

@FunctionalInterface

public interface Consumer<T> {

/**

* Performs this operation on the given argument.

*

* @param t the input argument

*/

void accept(T t);

/**

* 接口中默认实现的方法

*/

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

Objects.requireNonNull(after);

return (T t) -> { accept(t); after.accept(t); };

}

}

使用举例

public static <T> void forEach(List<T> list, Consumer<T> c) {

for (T t : list) {

c.accept(t);

}

}

List<String> listOfStrings = Arrays.asList("hello", "java", "", "apple");

List<String> nonEmpty = filter(listOfStrings, s -> !s.isEmpty());

System.out.println(nonEmpty);

forEach(Arrays.asList(1, 2, 3, 4, 5), s -> System.out.println(s));

三、 Supplier 消费者,没有入参

@FunctionalInterface

public interface Supplier<T> {


/**

* Gets a result.

*

* @return a result

*/

T get();

}

四、Function 方法

java.util.function.Function<T, R>接口定义了一个叫作apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象。如果你需要定义一个Lambda,将输入对象的信息映射到输出,就可以使用这个接口。

@FunctionalInterface

public interface Function<T, R>{

R apply(T t);

}

使用举例

public static <T, R> List<R> map(List<T> list, Function<T, R> f) {

List<R> result = new ArrayList<>();

for (T t : list) {

result.add(f.apply(t));

}

return result;

}


List<Integer> list = map(Arrays.asList("hello", "java", "sun"), s -> s.length());

System.out.println(list); // [5, 4, 3]

测验3.4:函数式接口

对于下列函数描述符(即Lambda表达式的签名),你会使用哪些函数式接口?在表3-2中

可以找到大部分答案。作为进一步练习,请构造一个可以利用这些函数式接口的有效Lambda

表达式:

(1) T->R

(2) (int, int)->int

(3) T->void

(4) ()->T

(5) (T, U)->R

答案如下。

(1) Function<T,R>不错。它一般用于将类型T的对象转换为类型R的对象(比如Function<Apple, Integer>用来提取苹果的重量)。

(2) IntBinaryOperator具有唯一一个抽象方法,叫作applyAsInt,它代表的函数描述符是(int, int) -> int。

(3) Consumer<T>具有唯一一个抽象方法叫作accept,代表的函数描述符是T -> void。

(4) Supplier<T>具有唯一一个抽象方法叫作get,代表的函数描述符是()-> T。或者,Callable<T>具有唯一一个抽象方法叫作call,代表的函数描述符是() -> T。

(5) BiFunction<T, U, R>具有唯一一个抽象方法叫作apply,代表的函数描述符是(T,U) -> R。

最近发表
标签列表