详解如何熟练使用java函数式接口

网友投稿 256 2023-01-09

详解如何熟练使用java函数式接口

一、函数式接口的由来

我们知道使用Lambda表达式的前提是需要有函数式接口,而Lambda表达式使用时不关心接口名,抽象方法名。只关心抽象方法的参数列表和返回值类型。因此为了让我们使用Lambda表达式更加的方法,在JDK中提供了大量常用的函数式接口

package com.bobo.jdk.fun;

public class Demo01Fun {

public static void main(String[] args) {

fun1((arr)->{

int sum = 0 ;

for (int i : arr) {

sum += i;

}

return sum;

});

}

public static void fun1(Operator operator){

int[] arr = {1,2,3,4};

int sum = operator.getSum(arr);

System.out.println("sum = " + sum);

}

}

/**

* 函数式接口

*/

@FunctionalInterface

interface Operator{

int getSum(int[] arr);

}

二、函数式接口介绍

在JDK中帮我们提供的有函数式接口,主要是在 java.util.function 包中。

2.1 Supplier

无参有返回值的接口,对于的Lambda表达式需要提供一个返回数据的类型。

@FunctionalInterface

public interface Supplier {

/**

* Gets a result.

*

* @return a result

*/

T get();

}

使用:

/**

* Supplier 函数式接口的使用

*/

public class SupplierTest {

public static void main(String[] args) {

fun1(()->{

int arr[] = {22,33,55,66,44,99,10};

// 计算出数组中的最大值

Arrays.sort(arr);

return arr[arr.length-1];

});

}

private static void fun1(Supplier supplier){

// get() 是一个无参的有返回值的 抽象方法

Integer max = supplier.get();

System.out.println("max = " + max);

}

}

2.2 Consumer

有参无返回值得接口,前面介绍的Supplier接口是用来生产数据的,而Consumer接口是用来消费数据的,使用的时候需要指定一个泛型来定义参数类型

@FunctionalInterface

public interface Consumer {

/**

* Performs this operation on the given argument.

*

* @param t the input argument

*/

void accept(T t);

}

使用:将输入的数据统一转换为小写输出

public class ConsumerTest {

public static void main(String[] args) {

test(msg -> {

System.out.println(msg + "-> 转换为小写:" + msg.toLowerCase());

});

}

public static void test(Consumer consumer){

consumer.accept("Hello World");

}

}

默认方法:andThen

如果一个方法的参数和返回值全部是Consumer类型,那么就可以实现效果,消费一个数据的时候,首先做一个操作,然后再做一个操作,实现组合,而这个方法就是Consumer接口中的default方法 andThen方法

default Consumer andThen(Consumer super T> after) {

Objects.requireNonNull(after);

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

}

具体的操作

public class ConsumerAndThenTest {

public static void main(String[] args) {

test2(msg1->{

System.out.println(msg1 + "-> 转换为小写:" + msg1.toLowerCase());

},msg2->{

System.out.println(msg2 + "-> 转换为大写:" + msg2.toUpperCase());

});

}

public static void test2(Consumer c1,Consumer c2){

String str = "Hello World";

//c1.accept(str); // 转小写

//c2.accept(str); // 转大写

//c1.andThen(c2).accept(str);

c2.andThen(c1).accept(str);

}

}

2.3 Function

有参有返回值的接口,Function接口是根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。有参数有返回值。

@FunctionalInterface

public interface Function {

/**

* Applies this function to the given argument.

*

* @param t the function argument

* @return the function result

*/

R apply(T t);

}

使用:传递进入一个字符串返回一个数字

public class FunctionTest {

public static void main(String[] args) {

test(msg ->{

return Integer.parseInt(msg);

});

}

public static void test(Function function){

Integer apply = function.apply("666");

System.out.println("apply = " + apply);

}

}

默认方法:andThen,也是用来进行组合操作,

default Function andThen(Function super R, ? extends V> after) {

Objects.requireNonNull(after);

return (T t) -> after.apply(apply(t));

}

public class FunctionAndThenTest {

public static void main(String[] args) {

test(msg ->{

return Integer.parseInt(msg);

},msg2->{

return msg2 * 10;

});

}

public static void test(Function f1,Function f2){

/*Integer i1 = f1.apply("666");

Integer i2 = f2.apply(i1);*/

Integer i2 = f1.andThen(f2).apply("666");

System.out.println("i2:" + i2);

}

}

默认的compose方法的作用顺序和andThen方法刚好相反

而静态方法identity则是,输入什么参数就返回什么参数

2.4 Predicate

有参且返回值为Boolean的接口

@FunctionalInterface

public interface Predicate {

/**

* 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);

}

使用:

public class PredicateTest {

public static void main(String[] args) {

test(msg -> {

return msg.length() > 3;

},"HelloWorld");

}

private static void test(Predicate predicate,String msg){

boolean b = predicate.test(msg);

SysYyGZCyJpatem.out.println("b:" + b);

}

}

在Predicate中的默认方法提供了逻辑关系操作 and or negate isEquals方法

package com.bobo.jdk.fun;

import java.util.function.Predicate;

public class PredicateDefaultTest {

public static void main(String[] args) {

test(msg1 -> {

return msg1.contains("H");

},msg2 -> {

return msg2.contains("W");

});

}

private static void test(Predicate p1,Predicate p2){

/*boolean b1 = predicate.test(msg);

boolean b2 = predicate.test("Hello");*/

// b1 包含H b2 包含W

// p1 包含H 同时 p2 包含W

boolean bb1 = p1.and(p2).test("Hello");

// p1 包含H 或者 p2 包含W

boolean bb2 = p1.or(p2).test("Hello");

// p1 不包含H

boolean bb3 = p1.negate().test("Hello");

System.out.println(bb1); // FALSE

System.out.println(bb2); // TRUE

System.out.println(bb3); // FALSE

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java调用process线程阻塞问题的解决
下一篇:api接口的管理网站(API管理)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~