zoukankan      html  css  js  c++  java
  • 第四节:函数式编程

    1. 内容简述

    Java版本,JDK 8

    1.1 内置函数式接口

    内置的函数式接口都在 java.util.function 包下

    Function

    表示一个函数(方法),接收一个单一的参数并返回一个单一的值

    Predicate

    表示一个简单的函数,接收一个值作为参数,返回真或假

    UnaryOperator

    代表一个操作,接收一个参数,并返回一个相同类型的参数

    BinaryOperator

    代表一个接收两个参数,并返回一个值的操作

    Supplier

    代表一个函数,提供某种类型的值

    Consumer

    代表一个函数,接收一个参数而不返回任何值

    1.2 函数的组合

    and/or

    拼接两个函数

    Predicate<String> startWithA = (text) -> text.startsWith("A");
    Predicate<String> endWithX = (text) -> text.endsWith("X");
    // 判断是否A开头并且X结尾
    Predicate<String> WithAandX = startWithA.and(endWithX);
    // 判断是否A开头或者X结尾
    Predicate<String> WithAandX = startWithA.or(endWithX);
    

    compose/andthen

    函数执行顺序

    Function<Integer, Integer> A = (value) -> value + 1;
    Function<Integer, Integer> B = (value) -> value * 2;
    // 先执行 B 在执行 A
    Function<Integer, Integer> then = A.compose(B);
    System.out.println(then.apply(2));
    // 先执行 A 在执行 B
    Function<Integer, Integer> then = A.andthen(B);
    System.out.println(then.apply(2));
    

    2. 基础阶段

    2.1 创建数据流

    数组创建

    public static void main(String[] args) {
        User[] array = new User[]{
                new User(1, "李白"),
                new User(2, "白起"),
                new User(3, "赵云"),
                new User(4, "韩信")
        };
        List<User> list = Arrays.stream(array)
            .filter(u -> u.getId() > 2)
            .limit(2)
            .collect(Collectors.toList());
        list.forEach(u-> System.out.println(u.getName()));
    }
    

    列表集合创建

    public static void main(String[] args) {
        List<User> list = new ArrayList<>();
        list.add(new User(1, "李白"));
        list.add(new User(2, "白起"));
        list.add(new User(3, "赵云"));
        list.add(new User(4, "韩信"));
        List<User> users = list.stream()
                .filter(u -> u.getId() > 2)
                .limit(2)
                .collect(Collectors.toList());
        users.forEach(u -> System.out.println(u.getName()));
    }
    

    2.2 流操作符

    连接类型操作符,可跟其它操作符,不会中断流

    筛选元素:

    List<User> list = new ArrayList<>();
    
    List<User> users = list.stream()
            .filter(u -> u.getId() > 2)
            .collect(Collectors.toList());
    
    users.forEach(u -> System.out.println(u.getName()));
    

    返回第一个元素:

    List<User> list = new ArrayList<>();
    
    Optional<User> first = users.stream().findFirst();
    User user = first.get();
    
    System.out.println(user.getName());
    

    映射指定类型元素:

    List<User> list = new ArrayList<>();
    
    Set<String> collect = list.stream().map(x -> x.getName()).collect(Collectors.toSet());
    
    System.out.println(collect.size());
    

    终止操作符,后面不可跟其它操作符,中断流

    是否有所有元素满足条件:

    List<User> list = new ArrayList<>();
    
    boolean match = list.stream().noneMatch(x -> x.getId() > 4);
    
    System.out.println(match);
    

    是否有一个满足条件:

    List<User> list = new ArrayList<>();
    
    boolean match = list.stream().anyMatch(x -> x.getId() > 2);
    
    System.out.println(match);
    

    是否全部不满足条件:有满足的为 false

    List<User> list = new ArrayList<>();
    
    boolean match = list.stream().noneMatch(x -> x.getId() > 4);
    
    System.out.println(match);
    

    数据总数:

    List<User> list = new ArrayList<>();
    
    long count = list.stream().count();
    
    System.out.println(count);
    

    最大,最小:

    List<User> list = new ArrayList<>();
    
    Optional<User> max = list.stream().max(Comparator.comparing(User::getId));
    System.out.println(max.get().getId());
    
    Optional<User> min = list.stream().min(Comparator.comparing(User::getId));
    System.out.println(min.get().getId());
    

    2.3 Optional

    判断操作符

    判断值是否存在,存在返回 true:

    Optional<User> first = list.stream().findFirst();
    first.isPresent();
    

    处理空值

    当值存在则返回值,不存在返回参数默认值:

    List<User> list = new ArrayList<>();
    
    Optional<User> first = list.stream().filter(x -> x.getId() > 1).findFirst();
    User def = new User(5, "王战军");
    
    User user = first.orElse(def);
    
    System.out.println(user.getName());
    

    当值存在则返回值,不存在返回方法的返回值:

    List<User> list = new ArrayList<>();
    
    Optional<User> first = list.stream().filter(x -> x.getId() > 1).findFirst();
    User def = new User(5, "王战军");
    
    User user = first.orElseGet(() -> def);
    
    System.out.println(user.getName());
    

    有值时处理

    返回值,不存在抛出异常:

    Optional<User> first = list.stream().filter(x->x.getId()>8).findFirst();
    System.out.println(first.get());
    

    当有值时,执行一个方法,方法参数为当前值:

    List<User> list = new ArrayList<>();
    
    Optional<User> first = list.stream().filter(x -> x.getId() > 1).findFirst();
    
    first.ifPresent(x -> System.out.println(x.getName()));
    

    2.4 Collectors收集器

    将流输出收集为一个集合对象

    示例一:toSet

    List<User> list = new ArrayList<>();
    
    Set<String> collect = list.stream().map(x -> x.getName()).collect(Collectors.toSet());
    
    System.out.println(collect.size());
    

    示例二:toMap

    使用一:输出KEY:VALUE形式

    List<User> list = new ArrayList<>();
    
    Map<Integer, User> map = list.stream().collect(Collectors.toMap(
        u -> u.getId(), 
        u -> u
    ));
    
    System.out.println(userMap.size());
    

    使用二:输出KEY:VALUE形式,重复key将会选中其中一个值

    List<User> list = new ArrayList<>();
    
    Map<Integer, String> map = list.stream().collect(Collectors.toMap(
            u -> u.getId(),
            u -> u.getName(),
            (oldvalue, newvalue) -> oldvalue
    ));
    
    System.out.println(map.size());
    

    使用三:输出KEY:VALUE形式,重复key将会选中其中一个值,并按 KEY 值排序

    List<User> list = new ArrayList<>();
    
    Map<Integer, String> map = list.stream().collect(Collectors.toMap(
            u -> u.getId(),
            u -> u.getName(),
            (oldvalue, newvalue) -> oldvalue,
            ()->new TreeMap<>()	// TreeMap::new
    ));
    
    System.out.println(map.size());
    

    示例三:toCollection 自定义规则

    使用一:使用自定义排序器

    List<User> list = new ArrayList<>();
    
    Comparator<User> byAge = Comparator.comparing(User::getId);
    TreeSet<User> collect = list.stream()
        .collect(Collectors.toCollection(() -> new TreeSet<>(byAge)));
    
    System.out.println(collect.size());
    

    聚合函数

    平均值:

    List<User> list = new ArrayList<>();
    
    Double aDouble = list.stream().collect(Collectors.averagingInt(u -> u.getId()));
    
    System.out.println(aDouble);
    

    总和:

    List<User> list = new ArrayList<>();
    
    Integer sum = list.stream().collect(Collectors.summingInt(u -> u.getId()));
    
    System.out.println(sum);
    

    多个聚合值:

    List<User> list = new ArrayList<>();
    
    DoubleSummaryStatistics collect = list.stream()
        .collect(Collectors.summarizingDouble(u -> u.getId()));
    
    System.out.println("和:" + collect.getSum());
    System.out.println("MAX:" + collect.getMax());
    System.out.println("MIN:" + collect.getMin());
    System.out.println("平均:" + collect.getAverage());
    System.out.println("行数:" + collect.getCount());
    

    分组统计

    使用一:简单分组,单个字段

    List<User> list = new ArrayList<>();
    
    Map<Integer, List<User>> map = list.stream()
        .collect(Collectors.groupingBy(u -> u.getId()));
    
    System.out.println(map.size());
    

    使用二:对分组后数据进行聚合

    List<User> list = new ArrayList<>();
    
    Map<Integer, DoubleSummaryStatistics> map = list.stream()
            .collect(Collectors.groupingBy(
                    u -> u.getId(),
                    Collectors.summarizingDouble(u -> u.getId())
                    )
            );
    
    到达胜利之前无法回头!
  • 相关阅读:
    Java Mockito 笔记
    J2EE 练习题
    CXF 教程 (二)
    CXF 教程(一)
    Java 动态代理
    常用 Git 命令汇总
    JXL 简单示例
    Visual Studio 技巧
    TreeView双击节点而不改变节点的折叠/展开状态
    称3次,找出坏鸡蛋
  • 原文地址:https://www.cnblogs.com/weiyongguang/p/14823596.html
Copyright © 2011-2022 走看看