首页IT科技function as serve as(Function源码解析与实践)

function as serve as(Function源码解析与实践)

时间2025-07-29 08:59:30分类IT科技浏览4392
导读:作者:陈昌浩 1 导读...

作者:陈昌浩

1 导读

if…else…在代码中经常使用             ,听说可以通过Java 8的Function接口来消灭if…else…!Function接口是什么?如果通过Function接口接口消灭if…else…呢?让我们一起来探索一下吧             。

2 Function接口

Function接口就是一个有且仅有一个抽象方法                    ,但是可以有多个非抽象方法的接口,Function接口可以被隐式转换为 lambda 表达式                    。可以通过FunctionalInterface注解来校验Function接口的正确性      。Java 8允许在接口中加入具体方法       。接口中的具体方法有两种      ,default方法和static方法                    。

@FunctionalInterface interface TestFunctionService { void addHttp(String url); }

那么就可以使用Lambda表达式来表示该接口的一个实现             。

TestFunctionService testFunctionService = url -> System.out.println("http:" + url); 2.1 FunctionalInterface 2.1.1 源码 @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface FunctionalInterface {} 2.1.2 说明

上图是FunctionalInterface的注解说明       。通过上面的注解说明       ,可以知道FunctionalInterface是一个注解                    ,用来说明一个接口是函数式接口                    。 函数式接口只有一个抽象方法             。 可以有默认方法             ,因为默认方法有一个实现       ,所以不是抽象的。函数接口的实例可以用lambda表达式             、方法引用或构造函数引用创建                    。

FunctionalInterface会校验接口是否满足函数式接口:

类型必须是接口类型                    ,不能是注释类型                    、枚举或类                    。 只能有一个抽象方法。 可以有多个默认方法和静态方法             。 可以显示覆盖java.lang.Object中的抽象方法                    。

编译器会将满足函数式接口定义的任何接口视为函数式接口             ,而不管该接口声明中是否使用FunctionalInterface注解      。

3 Function接口主要分类

Function接口主要分类:

Function:Function函数的表现形式为接收一个参数,并返回一个值             。 Supplier:Supplier的表现形式为不接受参数      、只返回数据                    。 Consumer:Consumer接收一个参数                    ,没有返回值      。 Runnable:Runnable的表现形式为即没有参数也没有返回值       。 3.1 Function

Function函数的表现形式为接收一个参数                    ,并返回一个值                    。

3.1.1 源码 @FunctionalInterface public interface Function<T, R> { R apply(T t); default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } static <T> Function<T, T> identity() { return t -> t; } } 3.1.2 方法说明 apply:抽象方法             。将此函数应用于给定的参数       。参数t通过具体的实现返回R                    。 compose:default方法             。返回一个复合函数,首先执行fefore函数应用于输入             ,然后将该函数应用于结果。如果任意一个函数的求值引发异常                    ,则将其传递给组合函数的调用者                    。 andThen:default方法                    。返回一个复合函数      ,该复合函数首先对其应用此函数它的输入             ,然后对结果应用after函数。如果任意一个函数的求值引发异常                    ,则将其传递给组合函数的调用者             。 identity:static方法                    。返回一个始终返回其输入参数的函数      。 3.1.3 方法举例

1)apply

测试代码:

public String upString(String str){ Function<String, String> function1 = s -> s.toUpperCase(); return function1.apply(str); } public static void main(String[] args) { System.out.println(upString("hello!")); }

通过apply调用具体的实现             。执行结果:

2)compose

测试代码:

public static void main(String[] args) { Function<String, String> function1 = s -> s.toUpperCase(); Function<String, String> function2 = s -> "my name is "+s; String result = function1.compose(function2).apply("zhangSan"); System.out.println(result); }

执行结果

如结果所示:compose 先执行function2 后执行function1                    。

3)andThen

测试代码:

public static void main(String[] args) { Function<String, String> function1 = s -> s.toUpperCase(); Function<String, String> function2 = s -> "my name is "+s; String result = function1.andThen(function2).apply("zhangSan"); System.out.println(result); }

执行结果:

如结果所示:

andThen先执行function1 后执行function2      。

identity

测试代码:

public static void main(String[] args) { Stream<String> stream = Stream.of("order", "good", "lab", "warehouse"); Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length)); System.out.println(map); }

执行结果:

3.2 Supplier

Supplier的表现形式为不接受参数       、只返回数据       。

3.2.1 源码 @FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); } 3.2.2 方法说明

get:抽象方法                    。通过实现返回T             。

3.2.3 方法举例 public class SupplierTest { SupplierTest(){ System.out.println(Math.random()); System.out.println(this.toString()); } } public static void main(String[] args) { Supplier<SupplierTest> sup = SupplierTest::new; System.out.println("调用一次"); sup.get(); System.out.println("调用二次"); sup.get(); }

执行结果:

如结果所示:Supplier建立时并没有创建新类      ,每次调用get返回的值不是同一个       。

3.3 Consumer

Consumer接收一个参数       ,没有返回值                    。

3.3.1 源码 @FunctionalInterface public interface Consumer<T> { void accept(T t); default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } } 3.3.2 方法说明 accept:对给定参数T执行一些操作             。 andThen:按顺序执行Consumer -> after ,如果执行操作引发异常                    ,该异常被传递给调用者。 3.3.3 方法举例 public static void main(String[] args) { Consumer<String> consumer = s -> System.out.println("consumer_"+s); Consumer<String> after = s -> System.out.println("after_"+s); consumer.accept("isReady"); System.out.println("========================"); consumer.andThen(after).accept("is coming"); }

执行结果:

如结果所示:对同一个参数T             ,通过andThen 方法       ,先执行consumer                    ,再执行fater                    。

3.4 Runnable

Runnable:Runnable的表现形式为即没有参数也没有返回值                    。

3.4.1 源码 @FunctionalInterface public interface Runnable { public abstract void run(); } 3.4.2 方法说明

run:抽象方法。run方法实现具体的内容             ,需要将Runnale放入到Thread中,通过Thread类中的start()方法启动线程                    ,执行run中的内容             。

3.4.3 方法举例 public class TestRun implements Runnable { @Override public void run() { System.out.println("TestRun is running!"); } } public static void main(String[] args) { Thread thread = new Thread(new TestRun()); thread.start(); }

执行结果:

如结果所示:当线程实行start方法时                    ,执行Runnable 的run方法中的内容                    。

4 Function接口用法

Function的主要用途是可以通过lambda 表达式实现方法的内容      。

4.1 差异处理

原代码:

@Data public class User { /** * 姓名 */ private String name; /** * 年龄 */ private int age; /** * 组员 */ private List<User> parters; } public static void main(String[] args) { User user =new User(); if(user ==null ||user.getAge() <18 ){ throw new RuntimeException("未成年!"); } }

执行结果:

使用Function接口后的代码:

@FunctionalInterface public interface testFunctionInfe { /** * 输入异常信息 * @param message */ void showExceptionMessage(String message); } public static testFunctionInfe doException(boolean flag){ return (message -> { if (flag){ throw new RuntimeException(message); } }); } public static void main(String[] args) { User user =new User(); doException(user ==null ||user.getAge() <18).showExceptionMessage("未成年!"); }

执行结果:

使用function接口前后都抛出了指定的异常信息             。

4.2 处理if…else…

原代码:

public static void main(String[] args) { User user =new User(); if(user==null){ System.out.println("新增用户"); }else { System.out.println("更新用户"); } }

使用Function接口后的代码:

public static void main(String[] args) { User user =new User(); Consumer trueConsumer = o -> { System.out.println("新增用户"); }; Consumer falseConsumer= o -> { System.out.println("更新用户"); }; trueOrFalseMethdo(user).showExceptionMessage(trueConsumer,falseConsumer); } public static testFunctionInfe trueOrFalseMethdo(User user){ return ((trueConsumer, falseConsumer) -> { if(user==null){ trueConsumer.accept(user); }else { falseConsumer.accept(user); } }); } @FunctionalInterface public interface testFunctionInfe { /** * 不同分处理不同的事情 * @param trueConsumer * @param falseConsumer */ void showExceptionMessage(Consumer trueConsumer,Consumer falseConsumer); }

执行结果:

4.3 处理多个if

原代码:

public static void main(String[] args) { String flag=""; if("A".equals(flag)){ System.out.println("我是A"); }else if ("B".equals(flag)) { System.out.println("我是B"); }else if ("C".equals(flag)) { System.out.println("我是C"); }else { System.out.println("没有对应的指令"); } }

使用Function接口后的代码:

public static void main(String[] args) { String flag="B"; Map<String, Runnable> map =initFunctionMap(); trueOrFalseMethdo(map.get(flag)==null).showExceptionMessage(()->{ System.out.println("没有相应指令"); },map.get(flag)); } public static Map<String, Runnable> initFunctionMap(){ Map<String,Runnable> result = Maps.newHashMap(); result.put("A",()->{System.out.println("我是A");}); result.put("B",()->{System.out.println("我是B");}); result.put("C",()->{System.out.println("我是C");}); return result; } public static testFunctionInfe trueOrFalseMethdo(boolean flag){ return ((runnable, falseConsumer) -> { if(flag){ runnable.run(); }else { falseConsumer.run(); } }); }

执行结果:

5 总结

Function函数式接口是java 8新加入的特性,可以和lambda表达式完美结合             ,是非常重要的特性,可以极大的简化代码                    。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
phpcms上传视频失败500(phpcms怎么备份数据库) phpcms程序(phpcms怎么新建栏目)