函数式编程

1 概述

2 Lambda表达式

3 Stream流

       // 创建stream的方法

        //1  使用Collection下的 stream() 和 parallelStream() 方法
        List list = new ArrayList<>();
        Stream stream = list.stream();  // 顺序流
        Stream parallelStream = list.parallelStream(); // 并行流

        // 2 使用Arrays 中的stream()方法,将数组转成流
        Integer[] nums = new Integer[10];
        Stream stream1 = Arrays.stream(nums);

        //3 使用Stream中的静态方法:of()、iterate()、generate()
        Stream stream = Stream.of(1, 2, 3, 4, 5, 6);

        Stream stream2 = Stream.iterate(0, (x) -> x + 2).limit(6);
        stream2.forEach(System.out::println); // 0 2 4 6 8 10

        Stream stream3 = Stream.generate(Math::random).limit(2);
        stream3.forEach(System.out::println);

        //4 使用 BufferedReader.lines() 方法,将每行内容转成流
        BufferedReader reader = new BufferedReader(new FileReader("F:\\test_stream.txt"));
        Stream lineStream = reader.lines();
        lineStream.forEach(System.out::println);

        // 5 使用 Pattern.splitAsStream() 方法,将字符串分隔成流
        Pattern pattern = Pattern.compile(",");
        Stream stringStream = pattern.splitAsStream("a,b,c,d");
        stringStream.forEach(System.out::println);
 private static void test1(){
        List authors = getAuthors();
        // 年龄 author.getAge() < 18) // 过滤
                .forEach(author -> System.out.println(author.getAge())); // 迭代
    }

流中的元素进行计算或者转换

 private  static void test2(){
        List authors = getAuthors();
        authors.stream()
                .map(author -> author.getName())
                .forEach(name -> System.out.println(name));
         authors.stream()
                .map(author -> author.getAge())
                .map(age-> age+10)
                .forEach(age -> System.out.println(age));
    }
 private static void test3() {
        // 打印姓名 去重
        List authors = getAuthors();
        authors.stream()
                .distinct() //去重
                .forEach(author -> System.out.println(author.getName()));
    }
 private static void test4() {
        // 年龄降序排序 去重 自定义排序
        List authors = getAuthors();
        authors.stream()
                .distinct()
                .sorted(new Comparator() {
                    @Override
                    public int compare(Author o1, Author o2) {
                        //return o1.getAge().compareTo(o2.getAge()); //升序
                        return o2.getAge().compareTo(o1.getAge()); //降序
                    }
                }).forEach(author -> System.out.println(author.getAge()));

        authors.stream()
                .distinct()
                .sorted((o1,o2) -> o2.getAge().compareTo(o1.getAge())) //降序
                .forEach(author -> System.out.println(author.getAge()));
    }

 private static void test5() {
        // 按照年龄降序 去重 输出年龄最大的两个作家姓名
        List authors = getAuthors();

        authors.stream()
                .distinct() // 去重
                .sorted((a1,a2)-> a2.getAge().compareTo(a1.getAge())) // 按照年龄降序
                .limit(2) // 限制输出2个
                .forEach(author -> System.out.println(author.getAge() +"==="+author.getName()));
    }

跳过流中的前n个元素

 private static void test6() {
        // 按照年龄降序 去重 跳过年龄最大的作家
        List authors = getAuthors();

        authors.stream()
                .distinct() // 去重
                .sorted((a1, a2) -> a2.getAge().compareTo(a1.getAge())) // 按照年龄降序
                .skip(1)
                .forEach(author -> System.out.println(author.getAge() + "===" + author.getName()));
    }

接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

 private static void test8() {
        // 得到所有书籍的分类 去重
        List authors = getAuthors();
        List collect = authors.stream()
                .flatMap(author -> author.getBooks().stream()) // List
                .distinct()
                .flatMap(book -> Arrays.stream(book.getCategory().split(",")))
                .distinct()
                .collect(Collectors.toList());
        System.out.println(collect); //[分类1, 分类2, 分类3, 分类4, 分类5]

    }

    private static void test7() {
        // 打印所有书籍的名字 去重
        List authors = getAuthors();

        authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .forEach(book -> System.out.println(book.getName()));
    }

对流中数据进行遍历操作

private static void test9() {
        List authors = getAuthors();
        authors.stream()
                .map(Author::getName)
                .forEach(System.out::println);
    }

统计当前流中的元素的个数

 private static void test10() {
        // 统计书籍的数目 去重
        List authors = getAuthors();
        long count = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .count();
        System.out.println(count);
    }
 private static void test12() {
        // 获取所有书籍的评分最大值  最小值
        List authors = getAuthors();
       /* Integer max = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .max(new Comparator() {
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        return o1 - o2;
                    }
                }).get();*/
        Integer max = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .max((o1, o2) -> o1 - o2).get();
        Integer min = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .min((o1, o2) -> o1 - o2).get();
        System.out.println(max);
        System.out.println(min);
    }

接收一个Collector实例,将流中元素收集成另外一个数据结构

 private static void test13() {

        List authors = getAuthors();
        // 获取所有作者名 list集合
        List nameList = authors.stream()
                .map(Author::getName)
                .collect(Collectors.toList());
        System.out.println(nameList);
        // 获取所有书籍名set集合
        Set bookNameSet = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(Book::getName)
                .collect(Collectors.toSet());
        System.out.println(bookNameSet);
        // 获取map
        Map> map = authors.stream()
                .distinct() // 去重 key 不能重复
                .collect(Collectors.toMap(Author::getName, Author::getBooks));
        System.out.println(map);
    }

接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false

 private static void test14() {
        List authors = getAuthors();
        /*boolean b = authors.stream()
                .map(author -> author.getAge())
                .anyMatch(new Predicate() {
                    @Override
                    public boolean test(Integer integer) {
                        return integer > 30;
                    }
                });*/
        boolean b = authors.stream()
                .map(author -> author.getAge())
                .anyMatch(age -> age > 30); // 存在年龄大于30的 返回true
        System.out.println(b);
    }

接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false

    private static void test15() {
        List authors = getAuthors();
        boolean b = authors.stream()
                .map(author -> author.getAge()) // 33 15 13 13
                .distinct() // 33 15 13
                .noneMatch(age -> age > 40); // true
        System.out.println(b);
    }

接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false。

    private static void test16() {
        List authors = getAuthors();
        boolean b = authors.stream()
                .map(author -> author.getAge()) // 33 15 13 13
                .distinct() // 33 15 13
                .allMatch(age -> age > 30); // false
        System.out.println(b);
    }

返回流中第一个元素

    private static void test18() {
        List authors = getAuthors();
        Optional optionalAuthor = authors.stream()
                .filter(author -> author.getAge() > 13)
                .findFirst();
        if (optionalAuthor.isPresent()){
            System.out.println(optionalAuthor.get());
        }else {
            System.out.println("不存在满足条件的数据");
        }
    }

返回流中的任意元素

    private static void test17() {
        List authors = getAuthors();
        Optional optionalAuthor = authors.stream()
                .filter(author -> author.getAge() > 45)
                .findAny();
        if (optionalAuthor.isPresent()){
            System.out.println(optionalAuthor.get());
        }else {
            System.out.println("不存在满足条件的数据");
        }
    }

对流中的数据依照你制定的规格计算出一个结果

 T result = identity;
     for (T element : this stream)
         result = accumulator.apply(result, element)
     return result;
    private static void test19() {
        // 年龄求和
        List authors = getAuthors();
        Integer reduce = authors.stream()
                .distinct()
                .map(author -> author.getAge())
                .reduce(0, (result, element) -> result + element);
        System.out.println(reduce);
    }
    private static void test20() {
        // 作者的年龄最大 最下值
        List authors = getAuthors();
        Integer max = authors.stream()
                .distinct()
                .map(author -> author.getAge())
                .reduce(Integer.MIN_VALUE, (result, element) -> (result < element ? element : result));
        Integer min = authors.stream()
                .distinct()
                .map(author -> author.getAge())
                .reduce(Integer.MAX_VALUE, new BinaryOperator() {
                    @Override
                    public Integer apply(Integer result, Integer element) {
                        return element < result ? element : result;
                    }
                });
        System.out.println(max);
        System.out.println(min);
    }
 boolean foundAny = false;
     T result = null;
     for (T element : this stream) {
         if (!foundAny) {
             foundAny = true;
             result = element; // 第一个参数作为result初始化值
         }
         else
             result = accumulator.apply(result, element);
     }
     return foundAny ? Optional.of(result) : Optional.empty();
    private static void test21() {
        List authors = getAuthors();
        Optional optional = authors.stream()
                .distinct()
                .map(author -> author.getAge())
                .reduce(new BinaryOperator() {
                    @Override
                    public Integer apply(Integer result, Integer element) {
                        return result < element ? element:result;
                    }
                });
        optional.ifPresent(i -> System.out.println(i));
    }
 Optional.ofNullable(T value)

 Optional.of(T value) // value == null  throw new NullPointerException()
 Optional optionalAuthor = Optional.ofNullable(author);
 optionalAuthor.ifPresent(System.out::println);

get方法 不推荐 可能出现异常

public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}
  • orElseGet
// 创建Optional对象
 Optional optionalAuthor = Optional.ofNullable(getAuthor());
 // 没有值 则返回默认值
 Author author = optionalAuthor.orElseGet(() -> new Author());
  • orElseThrow
// 创建Optional对象
        Optional optionalAuthor = Optional.ofNullable(getAuthor());

        try {
            Author author = optionalAuthor.orElseThrow(() -> new RuntimeException("author==null"));
            System.out.println(author);
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
    private static void testFilter() {

        // 创建Optional对象
        Optional optionalAuthor = Optional.ofNullable(getAuthor());

        //Optional author = optionalAuthor.filter(new Predicate() {
        //    @Override
        //    public boolean test(Author author) {
        //        return author.getAge() > 15;
        //    }
        //});
        //
        //author.ifPresent(author1 -> System.out.println(author1.getName()));

        optionalAuthor.filter(author -> author.getAge()>15).ifPresent(result -> System.out.println(result.getName()));

    }
    // 判断是否为空
    public boolean isPresent() {
        return value != null;
    }

    public void ifPresent(Consumer consumer) {
        if (value != null)
            consumer.accept(value);
    }

map

    private static void testMap() {
        Optional optionalAuthor = Optional.ofNullable(getAuthor());
        Optional> optionalBooks = optionalAuthor.map(author -> author.getBooks());
        optionalBooks.ifPresent(new Consumer>() {
            @Override
            public void accept(List books) {
                books.forEach(book -> System.out.println(book.getName()));
            }
        });
    }

只有一个抽象方法的接口称为函数式接口。

@FunctionalInterface

mapToInt

    private static void test23() {
        List authors = getAuthors();
        authors.stream()
                .map(author -> author.getAge())
                .map(age -> age + 10)
                .filter(age -> age > 18)
                .map(age -> age + 2)
                .forEach(System.out::println);
        // 优化 mapToInt
        authors.stream()
                .mapToInt(author -> author.getAge())
                .map(age -> age + 10)
                .filter(age -> age > 18)
                .map(age -> age + 2)
                .forEach(System.out::println);
    }
    private static void test24() {
        Stream stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = stream.parallel() // 并行流
                .peek(new Consumer() { // 调试用 消费数据
                    @Override
                    public void accept(Integer num) {
                        System.out.println(num+"--"+Thread.currentThread().getName());
                    }
                })
                .filter(num -> num > 5)
                .reduce((result, element) -> result + element)
                .get();
        System.out.println(sum);
    }

示例使用的数据

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode //去重使用
public class Author {

    private Long id;

    private String name;

    private Integer age;

    private String intro;

    private List books;

}

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Book {
    private Long id;

    private String name;

    private String category;

    private Integer score;

    private String intro;

}

    private static List getAuthors() {
        Author author = new Author(1L, "张三", 33, "卡时间段圣诞节啊", null);
        Author author2 = new Author(2L, "李四", 15, "卡时间段圣诞节啊2", null);
        Author author3 = new Author(3L, "王五", 13, "卡时间段圣诞节啊3", null);
        Author author4 = new Author(3L, "王五", 13, "卡时间段圣诞节啊3", null);

        ArrayList books1 = new ArrayList<>();
        ArrayList books2 = new ArrayList<>();
        ArrayList books3 = new ArrayList<>();

        books1.add(new Book(1L, "高数", "分类1,分类2", 5, "高数啊"));
        books1.add(new Book(2L, "高数1", "分类2", 2, "高数啊1"));

        books2.add(new Book(3L, "大学物理", "分类3,分类2", 4, "大学物理啊"));
        books2.add(new Book(3L, "大学物理", "分类3,分类2", 4, "大学物理啊"));
        books2.add(new Book(4L, "大学物理2", "分类3", 4, "大学物理啊2"));

        books3.add(new Book(5L, "大学物理3", "分类4", 2, "大学物理啊3"));
        books3.add(new Book(6L, "大学物理4", "分类4,分类5", 2, "大学物理啊4"));
        books3.add(new Book(6L, "大学物理4", "分类4,分类5", 2, "大学物理啊4"));

        author.setBooks(books1);
        author2.setBooks(books2);
        author3.setBooks(books3);
        author4.setBooks(books3);

        return new ArrayList<>(Arrays.asList(author, author2, author3, author4));
    }

Original: https://www.cnblogs.com/iforeverhz/p/16256930.html
Author: iforeverhz
Title: 函数式编程

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/583234/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球