JDK1.8新特性-函数式编程

我正在参与掘金创作者训练营第5期,点击了解活动详情

简介

面向对象其实是对数据的抽象

函数式编程则是对行为的抽象

核心思想:

使用不可变值和函数,函数对一个值进行处理,映射成另一个值

分类

函数式编程最理想的方式:

形成一个惰性求值的链,最后用一个及早求值的操作返回想要的结果。

类似建造者模式,先是使用一系列操作设置属性和配置,最后调用build方法,创建对象。

惰性求值方法

list.stream.filter(s -> s.equals("string"));
复制代码

就是描述的所需的数据,但是并没有产生结果。

及早求值方法

List<String> newList = list.stream.filter(s -> s.equals("string")).collect(Collectors.toList());
复制代码

最终产生了新的值,并且终止操作

Stream

顺序流

list.stream()
复制代码

并行流

list.stream().parallel()
    或
list.parallelStream()
复制代码

并行流的底层就是利用ForkJoinPool进行任务拆分交给不同的线程去执行最后在合并。也就是分治合并

常用函数方法

Filter

过滤函数中符合条件的数据

Map+Reduce

List<Integer> costBeforeTax = Arrays.asList(1, 2, 3);
double bill = costBeforeTax.stream()
    .map((cost) -> cost + 12*cost)
                .reduce((sum, cost) -> sum + cost).get();
复制代码

map将集合元素装换

reduce将集合数据合并成一个数据

Collectors

  • Collectors.joining(", ")
  • Collectors.toList()
  • Collectors.toSet() ,生成set集合
  • Collectors.toMap(MemberModel::getUid, Function.identity())
  • Collectors.toMap(ImageModel::getAid, o -> IMAGE_ADDRESS_PREFIX + o.getUrl())

FlatMap

List<Integer> result= Stream.of(Arrays.asList(1,3),Arrays.asList(5,6))
                .flatMap(a->a.stream()).collect(Collectors.toList());
复制代码

将多个stream连接成一个stream,flatMap操作的时候其实是先每个元素处理并返回一个新的Stream,然后将多个Stream展开合并为了一个完整的新的Stream

Distinct

去重

count

int countOfAdult=persons.stream()
    .filter(p -> p.getAge() > 18)
    .map(person -> new Adult(person))
                       .count();
复制代码

计总数

Match

anyMatch

集合中有一个符合条件就会返回true

allMatch

集合中所有元素都符合条件才会返回true

noneMatch

集合所有元素都不符合条件才会返回true;如果匹配一个元素或者多个元素都会返回false

min、max

使用方式一致,如下

Person a = lists.stream().max(Comparator.comparing(t -> t.getId())).get();

Person a = lists.stream().min(new Comparator<Person>() {
    @Override
    public int compare(Person o1, Person o2) {
        if (o1.getId() > o2.getId()) return -1;
        if (o1.getId() < o2.getId()) return 1;
        return 0;
    }
 }).get();
复制代码

summaryStatistics

统计数组的个数、最小值、最大值、总和以及平均值

List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest prime number in List : " + stats.getMax());
System.out.println("Lowest prime number in List : " + stats.getMin());
System.out.println("Sum of all prime numbers : " + stats.getSum());
System.out.println("Average of all prime numbers : " + stats.getAverage());
复制代码

四大函数接口

消费性接口

 Consumer< T> void accept(T t)有参数,无返回值的抽象方法;
复制代码

供给性接口

Supplier < T> T get() 无参有返回值的抽象方法;
复制代码

断定性接口

Predicate<T> boolean test(T t):有参,但是返回值类型是固定的boolean
复制代码

函数性接口

Function<T,R> R apply(T t)有参有返回值的抽象方法;
复制代码

注解 @FunctionInterface

符合哪些条件才能被这个注解修饰

  • 首先得是一个接口
  • 接口中只能有一个抽象方法,默认方法不算

自定义函数接口

@FunctionalInterface
interface MyFunction<T,R>{

    R become(T t);

    default void study(){
        System.out.println("努力学习!");
    }
}
复制代码

四大函数接口编码+自定义函数接口编码

/**
 * @author mumuwen
 * @className FunctionStudy
 * @description: 四大函数式接口,自定义函数式接口
 * @date 2022/5/8 16:44
 **/
public class FunctionStudy {

    private static Map<String,String> myLovePeopleMap = new HashMap<>();

    static {
        myLovePeopleMap.put("汪","girlfriend");
        myLovePeopleMap.put("刘","dad");
        myLovePeopleMap.put("张","mom");
    }

    public static void main(String[] args) {

        String name = "刘";

        Function<String,Object> function = nm -> new People(myLovePeopleMap.get(nm));

        System.out.println(name + function.apply(name));

        // 自定义函数式接口
        MyFunction<String,Object> myFunction = nm -> nm + "变成了" + new People(myLovePeopleMap.get(nm));

        name = "汪";

        myFunction.study();
        System.out.println(myFunction.become(name));

        // 断定性接口
        Predicate<String> predicate = nm -> myLovePeopleMap.get(nm) != null;

        name = "张";

        System.out.println(name + "是我爱的人吗? 请回答:" + predicate.test(name));

        // 消费函数
        Consumer<String> consumer = food -> System.out.println(food + "被吃掉了");

        consumer.accept("汉堡");

        // 生产函数
        Supplier<People> supplier = () -> {

            String relationship = "girlfriend";
            return new People(relationship);
        };

        System.out.println("获得了一个" + supplier.get());

    }
}

/**
 * 自定义函数式接口
 * @param <T> 参数
 * @param <R> 返回值
 */
@FunctionalInterface
interface MyFunction<T,R>{

    R become(T t);

    default void study(){
        System.out.println("努力学习!");
    }
}

class People{
    private String relationship;

    public People(String relationship) {
        this.relationship = relationship;
    }

    @Override
    public String toString() {
        return "我的" + relationship;
    }
}
复制代码

资料参考

www.pdai.tech/md/java/jav…

猜你喜欢

转载自juejin.im/post/7129499954745671688