JUC(六) 四大函数式接口和ForkJoin

本文深入探讨了Java中的四大函数式接口——Function、Predicate、Supplier和Consumer的使用,以及Stream流式计算的实践。通过示例展示了如何利用lambda表达式和链式编程进行高效的数据处理。同时,文章还介绍了ForkJoin框架在并行计算中的应用,强调了其工作窃取的特点和提高效率的能力。
摘要由CSDN通过智能技术生成

目录

四大函数式接口

函数型接口

 Function 函数型接口

Predicate 断定型接口

Supplier 供给型接口

Consumer 消费型接口

Stream 流式计算

 ForkJoin


四大函数式接口

lambda表达式,链式编程,函数式接口,Steram流式计算

函数型接口

 Function 函数型接口

函数式接口:只有一个方法的接口

传入参数T,返回类型R

只要是函数式接口,就可以用lambda表达式简化

public class FunctionDemo {
    public static void main(String[] args) {
        /*Function<String,String> function = new Function<String,String>() {
            //工具类:输出输入的值
            @Override
            public String apply(String str) {
                return str;
            };
        };*/
        Function<String,String> function = (str)->{return str;};
        System.out.println(function.apply("aaa"));
    }
}

Predicate 断定型接口

 有一个输入参数,返回值只能是布尔值

public class PredicateDemo {
    public static void main(String[] args) {
        //判断字符串是否为空
        /*Predicate<String> predicate = new Predicate<String>() {
            @Override
            public boolean test(String str) {
                return str.isEmpty();
            }
        };*/
        Predicate<String> predicate = (str)->{return str.isEmpty();};
        System.out.println(predicate.test(""));
    }
}

Supplier 供给型接口

public class SuppierDemo {
    public static void main(String[] args) {
        //打印字符串
        /*Supplier<String> supplier = new Supplier<String>() {
            @Override
            public String get() {
                return "aaa";
            }
        };*/

        Supplier<String> supplier = ()->{return "aaa";};
        System.out.println(supplier.get());
    }
}

Consumer 消费型接口

public class ConsummerDemo {
    public static void main(String[] args) {
        //打印字符串
       /* Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };*/
        Consumer<String> consumer = (s)->{System.out.println(s);};
        consumer.accept("sss");
    }
}

Stream 流式计算

什么是Stream流式计算

  • 大数据:存储+计算
  • 集合、Mysql本来就是存储数据的,计算应该交给流来操作。

/**
 * 题目要求: 用一行代码实现
 * 1. Id 必须是偶数
 * 2.年龄必须大于23
 * 3. 用户名转为大写
 * 4. 用户名倒序
 * 5. 只能输出一个用户
 **/

public class StreamDemo {
    public static void main(String[] args) {
        User u1 = new User(1, "a", 23);
        User u2 = new User(2, "b", 23);
        User u3 = new User(3, "c", 23);
        User u4 = new User(6, "d", 24);
        User u5 = new User(4, "e", 25);

        List<User> list = Arrays.asList(u1, u2, u3, u4, u5);
        // lambda、链式编程、函数式接口、流式计算
        list.stream()
                .filter(user -> {return user.getId()%2 == 0;})//判断偶数
                .filter(user -> {return user.getAge() > 23;})//判断大于23
                .map(user -> {return user.getName().toUpperCase();})//转换大写
                .sorted((user1, user2) -> {return user2.compareTo(user1);})//排序(比较user1和user2)
                .limit(1)//打印一个
                .forEach(System.out::println);
    }
}

ForkJoin

ForkJoin 在JDK1.7,并行执行任务!提高效率~。在大数据量速率会更快!

一个线程并发成多个去操作

大数据中:Map Reduce 核心思想->把大任务拆分为小任务

 ForkJoin 特点: 工作窃取!(B执行完后会把A没执行的任务执行)
这里面维护的是双端队列(两端都可操作)
实现原理是:双端队列!从上面和下面都可以去拿到任务进行执行!

  • 如何使用ForkJoin?
    • 通过ForkJoinPool来执行
    • 计算任务 execute(ForkJoinTask<?> task)
    • 计算类要去继承ForkJoinTask;

public class ForkJoinDemo extends RecursiveTask<Long> {
    private long star;
    private long end;
    /** 临界值 */
    private long temp = 1000000L;

    public ForkJoinDemo(long star, long end) {
        this.star = star;
        this.end = end;
    }

    /**
     * 计算方法
     * @return
     */
    @Override
    protected Long compute() {
        if ((end - star) < temp) {
            Long sum = 0L;
            for (Long i = star; i < end; i++) {
                sum += i;
            }
            return sum;
        }else {
            // 使用ForkJoin 分而治之 计算
            //1 . 计算平均值
            long middle = (star + end) / 2;
            ForkJoinDemo forkJoinDemo1 = new ForkJoinDemo(star, middle);
            // 拆分任务,把线程压入线程队列
            forkJoinDemo1.fork();
            ForkJoinDemo forkJoinDemo2 = new ForkJoinDemo(middle, end);
            forkJoinDemo2.fork();

            long taskSum = forkJoinDemo1.join() + forkJoinDemo2.join();
            return taskSum;
        }
    }
}

测试

public class ForkJoinTest {
    private static final long SUM = 20_0000_0000;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        test1();
        test2();
        test3();
    }

    /**
     * 使用普通方法
     */
    public static void test1() {
        long star = System.currentTimeMillis();
        long sum = 0L;
        for (long i = 1; i < SUM ; i++) {
            sum += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(sum);
        System.out.println("时间:" + (end - star));
        System.out.println("----------------------");
    }
    
    /**
     * 使用ForkJoin 方法
     */
    public static void test2() throws ExecutionException, InterruptedException {
        long star = System.currentTimeMillis();

        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTask<Long> task = new ForkJoinDemo(0L, SUM);
        ForkJoinTask<Long> submit = forkJoinPool.submit(task); //提交任务
        Long along = submit.get();

        System.out.println(along);
        long end = System.currentTimeMillis();
        System.out.println("时间:" + (end - star));
        System.out.println("-----------");
    }
    
    /**
     * 使用 Stream并行流计算
     */
    public static void test3() {
        long star = System.currentTimeMillis();

        long sum = LongStream.rangeClosed(0L, SUM).parallel().reduce(0, Long::sum);
        System.out.println(sum);
        long end = System.currentTimeMillis();
        System.out.println("时间:" + (end - star));
        System.out.println("-----------");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值