欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

java中functional interface的分类和使用

发布时间:2024/2/28 50 豆豆
生活随笔 收集整理的这篇文章主要介绍了 java中functional interface的分类和使用 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

文章目录

  • 简介
  • Functional Interface
  • Function:一个参数一个返回值
  • BiFunction:接收两个参数,一个返回值
  • Supplier:无参的Function
  • Consumer:接收一个参数,不返回值
  • Predicate:接收一个参数,返回boolean
  • Operator:接收和返回同样的类型
  • 总结

简介

java 8引入了lambda表达式,lambda表达式实际上表示的就是一个匿名的function。

在java 8之前,如果需要使用到匿名function需要new一个类的实现,但是有了lambda表达式之后,一切都变的非常简介。

我们看一个之前讲线程池的时候的一个例子:

//ExecutorService using classExecutorService executorService = Executors.newSingleThreadExecutor();executorService.submit(new Runnable() {@Overridepublic void run() {log.info("new runnable");}});

executorService.submit需要接收一个Runnable类,上面的例子中我们new了一个Runnable类,并实现了它的run()方法。

上面的例子如果用lambda表达式来重写,则如下所示:

//ExecutorService using lambdaexecutorService.submit(()->log.info("new runnable"));

看起是不是很简单,使用lambda表达式就可以省略匿名类的构造,并且可读性更强。

那么是不是所有的匿名类都可以用lambda表达式来重构呢?也不是。

我们看下Runnable类有什么特点:

@FunctionalInterface public interface Runnable

Runnable类上面有一个@FunctionalInterface注解。这个注解就是我们今天要讲到的Functional Interface。

Functional Interface

Functional Interface是指带有 @FunctionalInterface 注解的interface。它的特点是其中只有一个子类必须要实现的abstract方法。如果abstract方法前面带有default关键字,则不做计算。

其实这个也很好理解,因为Functional Interface改写成为lambda表达式之后,并没有指定实现的哪个方法,如果有多个方法需要实现的话,就会有问题。

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface FunctionalInterface {}

Functional Interface一般都在java.util.function包中。

根据要实现的方法参数和返回值的不同,Functional Interface可以分为很多种,下面我们分别来介绍。

Function:一个参数一个返回值

Function接口定义了一个方法,接收一个参数,返回一个参数。

@FunctionalInterface public interface Function<T, R> {/*** Applies this function to the given argument.** @param t the function argument* @return the function result*/R apply(T t)

一般我们在对集合类进行处理的时候,会用到Function。

Map<String, Integer> nameMap = new HashMap<>();Integer value = nameMap.computeIfAbsent("name", s -> s.length());

上面的例子中我们调用了map的computeIfAbsent方法,传入一个Function。

上面的例子还可以改写成更短的:

Integer value1 = nameMap.computeIfAbsent("name", String::length);

Function没有指明参数和返回值的类型,如果需要传入特定的参数,则可以使用IntFunction, LongFunction, DoubleFunction:

@FunctionalInterface public interface IntFunction<R> {/*** Applies this function to the given argument.** @param value the function argument* @return the function result*/R apply(int value); }

如果需要返回特定的参数,则可以使用ToIntFunction, ToLongFunction, ToDoubleFunction:

@FunctionalInterface public interface ToDoubleFunction<T> {/*** Applies this function to the given argument.** @param value the function argument* @return the function result*/double applyAsDouble(T value); }

如果要同时指定参数和返回值,则可以使用DoubleToIntFunction, DoubleToLongFunction, IntToDoubleFunction, IntToLongFunction, LongToIntFunction, LongToDoubleFunction:

@FunctionalInterface public interface LongToIntFunction {/*** Applies this function to the given argument.** @param value the function argument* @return the function result*/int applyAsInt(long value); }

BiFunction:接收两个参数,一个返回值

如果需要接受两个参数,一个返回值的话,可以使用BiFunction:BiFunction, ToDoubleBiFunction, ToIntBiFunction, ToLongBiFunction等。

@FunctionalInterface public interface BiFunction<T, U, R> {/*** Applies this function to the given arguments.** @param t the first function argument* @param u the second function argument* @return the function result*/R apply(T t, U u);

我们看一个BiFunction的例子:

//BiFunctionMap<String, Integer> salaries = new HashMap<>();salaries.put("alice", 100);salaries.put("jack", 200);salaries.put("mark", 300);salaries.replaceAll((name, oldValue) ->name.equals("alice") ? oldValue : oldValue + 200);

Supplier:无参的Function

如果什么参数都不需要,则可以使用Supplier:

@FunctionalInterface public interface Supplier<T> {/*** Gets a result.** @return a result*/T get(); }

Consumer:接收一个参数,不返回值

Consumer接收一个参数,但是不返回任何值,我们看下Consumer的定义:

@FunctionalInterface public interface Consumer<T> {/*** Performs this operation on the given argument.** @param t the input argument*/void accept(T t);

看一个Consumer的具体应用:

//ConsumernameMap.forEach((name, age) -> System.out.println(name + " is " + age + " years old"));

Predicate:接收一个参数,返回boolean

Predicate接收一个参数,返回boolean值:

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

如果用在集合类的过滤上面那是极好的:

//PredicateList<String> names = Arrays.asList("A", "B", "C", "D", "E");List<String> namesWithA = names.stream().filter(name -> name.startsWith("A")).collect(Collectors.toList());

Operator:接收和返回同样的类型

Operator接收和返回同样的类型,有很多种Operator:UnaryOperator BinaryOperator ,DoubleUnaryOperator, IntUnaryOperator, LongUnaryOperator, DoubleBinaryOperator, IntBinaryOperator, LongBinaryOperator等。

@FunctionalInterface public interface IntUnaryOperator {/*** Applies this operator to the given operand.** @param operand the operand* @return the operator result*/int applyAsInt(int operand);

我们看一个BinaryOperator的例子:

//OperatorList<Integer> values = Arrays.asList(1, 2, 3, 4, 5);int sum = values.stream().reduce(0, (i1, i2) -> i1 + i2);

总结

Functional Interface是一个非常有用的新特性,希望大家能够掌握。

本文的例子:https://github.com/ddean2009/learn-java-streams/tree/master/functional-interface

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

更多内容请访问 www.flydean.com

总结

以上是生活随笔为你收集整理的java中functional interface的分类和使用的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。