栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 函数式编程的妙用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 函数式编程的妙用

Jdk8之后新增的一个重要的包 : java.util.function

该包下所有的接口都是函数式接口, 按分类主要分为四大接口类型: Function、Consumer、Predicate、Supplier

接口

参数

返回值

说明

Supplier

T

供给型:无参,返回一个执行泛型对象

Consumer

T

无参

消费型:传入一个指定参数,无返回值

Function

T.R

R

方法型:输入一个参数得到一个结果

可以看下Java在function包下的代码:

Consumer

源码如下(包含一个接口和默认实现)

@FunctionalInterface
public interface Consumer {

    
    void accept(T t);

    
    default Consumer andThen(Consumer after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

 使用案例

public static void main(String[] args) {
        testConsumer();
        testAndThen();
    }
    
    public static void testConsumer() {
        //设置好Consumer实现方法
        Consumer square = x -> System.out.println("平方计算 : " + x * x);
        //传入值
        square.accept(2);
    }
    
    public static void testAndThen() {
        //当前值
        Consumer consumer1 = x -> System.out.println("当前值 : " + x);
        //相加
        Consumer consumer2 = x -> { System.out.println("相加 : " + (x + x)); };
        //相乘
        Consumer consumer3 = x -> System.out.println("相乘 : " + x * x);
        //andThen拼接
        consumer1.andThen(consumer2).andThen(consumer3).accept(1);
    }

 

这个是一个没有使用意义的DEMO,其实我们在使用consumer的时候,一般会用来操作集合,JDK的iterator接口就是使用consumer来操作的

另一种使用案例

public static void main(String[] args) {
        //假设这里有个集合,集合里的对象有个status属性,现在我想对这个属性赋值一个固定值
        List pensionList = new ArrayList<>();
        //1、传统的通过for循环添加
        for (Pension pension : pensionList) {
            pension.setStatus(1);
        }
        //2、通过forEach的Consumer添加
        pensionList.forEach(x -> x.setStatus(1));
    }

这样一比较是不是代码简洁了点,这就是Consumer是我们代码带来简洁的地方。

Supplier

提前定义可能返回的一个指定类型结果,等需要调用的时候再获取结果

我们看下源码

 public  T orElseThrow(Supplier exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }

使用案例

 public static void main(String[] args) {
        Person son = null;
        //先判断son是否为null,如果为不为null则返回当前对象,如果为null则返回新创建的对象
        BrandDTO optional = Optional.ofNullable(son).orElseGet(() -> new Person());

    }

Function

实现一个”一元函数“,即传入一个值经过函数的计算返回另一个值

源码

@FunctionalInterface
    public interface Function {
        
        
        R apply(T t);

        
        default  java.util.function.Function compose(java.util.function.Function before) {
            Objects.requireNonNull(before);
            return (V v) -> apply(before.apply(v));
        }

        
        default  java.util.function.Function andThen(java.util.function.Function after) {
            Objects.requireNonNull(after);
            return (T t) -> after.apply(apply(t));
        }

        
        static  java.util.function.Function identity() {
            return t -> t;
        }
    }

使用案例

public static void main(String[] args) {
        applyTest();
        andThenTest();
        composeTest();
        test();
    }

    
    private static void applyTest() {
        //示例1:定义一个funciton,实现将String转换为Integer
        Function function = x -> Integer.parseInt(x);
        Integer a = function.apply("100");
        System.out.println(a.getClass());
        // 结果:class java.lang.Integer
    }

    
    private static void andThenTest() {
        //示例2:使用andThen() 实现一个函数 y=10x + 10;
        //先执行 10 * x
        Function function2 = x -> 10 * x;
        //通过andThen在执行 这里的x就等于上面的10 * x的值
        function2 = function2.andThen(x -> x + 10);
        System.out.println(function2.apply(2));
        //结果:30

    }

    
    private static void composeTest() {
        //示例3:使用compose() 实现一个函数 y=(10+x)2;
        Function function3 = x -> x * 2;
        //先执行 x+10 在执行(x+10)*2顺序与上面相反
        function3 = function3.compose(x -> x + 10);
        System.out.println(function3.apply(3));
        //结果:26
    }

    
    private static void test() {

//示例4:使用使用compose()、andThen()实现一个函数 y=(10+x)*2+10;
        //执行第二步
        Function function4 = x -> x * 2;
        //执行第一步
        function4 = function4.compose(x -> x + 10);
        //执行第三步
        function4 = function4.andThen(x -> x + 10);
        System.out.println(function4.apply(3));
       //结果:36

    }

在JDK中内部的使用案例

Map> map = new HashMap<>();
List list;

// java8之前写法
list = map.get("key");
if (list == null) {
    list = new linkedList<>();
    map.put("key", list);
}
list.add("11");

// 使用 computeIfAbsent 可以这样写 如果key返回部位空则返回该集合 ,为空则创建集合后返回
list = map.computeIfAbsent("key", k -> new ArrayList<>());
list.add("11");
  public static void main(String[] args) {
        List persionList = new ArrayList();
        persionList.add(new Person(1,"张三","男",38));
        persionList.add(new Person(2,"小小","女",2));
        persionList.add(new Person(3,"李四","男",65));

        //1、只取出该集合中所有姓名组成一个新集合(将Person对象转为String对象)
        List nameList=persionList.stream().map(Person::getName).collect(Collectors.toList());
        System.out.println(nameList.toString());
        }

一般我们也会很少去定义一个方法,方法参数包含函数接口。我们更重要的是学会使用JDk8中带有函数式接口参数的方法,来简化我们的代码

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/284967.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号