Java函数式编程

289 阅读3分钟

1、 Lambda表达式

  • 1、基本形式
    Runnable noArguments = () -> System.out.println("Hello World!");
    ActionListener oneArgument = event -> System.out.println("Button Click.");
    Runnable multiStatement = () -> {
        System.out.println("Hello ");
        System.out.println("World!");
    };
    // 创建一个函数
    BinaryOperator<Long> add = (x, y) -> x + y;
  • 2、函数接口(Lambda表达式的类型)
接口 参数 返回类型 示例
Predicate T boolean 是否
Consumer T void 输出一个值
Function<T, R> T R
Supplier None T 工厂方法
UnaryOperator T T 逻辑非
BinaryOperator (T, T) T 两个数的乘积

2、流

  • 1、内部迭代和外部迭代

    foreach循环本质是通过Iterator迭代器实现的,属于外部迭代,即在应用代码中的迭代;

    Stream属于内部迭代,在集合内部迭代;

  • 2、惰性求值和及早求值

    Stream方法返回的是Stream类型则是惰性求值,返回的是空或者其他类型则是及早求值;

  • 3、优点

    不存储元素;

    不修改其他数据源;

    尽可能的惰性求值;

    遵循集合的排序,集合无序,则流无序;

  • 4、创建流

    // Stream.of(T... values)
    Stream.of("adjust");
    String words = "abandon,abroad";
    // ‘\\PL+’:非字母分隔符
    Stream.of(words.split("\\PL+"));    
    // Arrays.stream()
    String[] names = {"Mary,Jane"};
    Arrays.stream(names, 0, 1);
    // Stream.empty(),不包含任何元素
    Stream.empty();
    // Stream.generate(Supplier<T> s)
    // Stream.iterator(T seed, UnaryOperator<T> f)
    // 无限流,搭配limit()使用
    Stream.generate(() -> "repeat");    // 重复
    Stream.generate(Math::random);      // 随机
    Stream.iterate(0, i -> i + 1);  // 无限递增
    // Pattern.compile().splitAsStream,正则表达式
    Pattern.compile("\\PL+").splitAsStream(words);
    // Files.lines(),Files工具类,文件中每行数据流
    Files.lines(Paths.get(""));
  • 5、流转换新的流
    // filter(),条件过滤
    Stream<String> strStream = Stream.of(words.split("\\PL+")).filter(a -> a.length() > 10);
    // map(),类型转换
    Stream<Integer> intStream = Stream.of(words.split("\\PL+")).map(a -> a.length());
    // flatMap(),合并
    Stream<String> charStrStream = Stream.of(words.split("\\PL+"))
            .map(a -> Arrays.stream(a.split("")))
            .flatMap(a -> a)
  • 6、子流和连接流
    // limit(n),只保留n个元素
    Stream.generate(Math::random)
            .limit(10);
    // skip(n),跳过前n个元素
    Stream.of(words.split("\\PL+"))
            .skip(1);
    // concat(),连接流
    Stream.concat(
            Stream.generate(Math::random)
                    .limit(10),
            Stream.generate(Math::random)
                    .limit(10));
  • 7、去重、排序
    // distinct(),去重
    Stream.generate(Math::random)
            .limit(10)
            .distinct();
    // sorted(),多种规格排序,Comparable、Comparator
    Stream.of(words.split("\\PL+"))
            .sorted(Comparator.comparing(String::length));
    // peek(),产生一样的流,同时调用函数
    Stream.generate(Math::random)
            .limit(10)
            .peek(System.out::println);
  • 8、简单约简
    // min()、max(),最大值和最小值
    Stream.generate(Math::random)
            .limit(10).max(Double::compareTo);
    // findFirst()、findAny(),第一个和任意一个,搭配filter()使用
    Stream.generate(Math::random)
            .limit(10).findFirst();
    Stream.generate(Math::random)
            .limit(10).findAny();
    // anyMatch()、allMatch()、noneMatch(),存在任意一个、所有和没有,返回boolean
    Stream.generate(Math::random)
            .limit(10).anyMatch(a -> a == 1);
    Stream.generate(Math::random)
            .limit(10).allMatch(a -> a == 1);
    Stream.generate(Math::random)
            .limit(10).noneMatch(a -> a == 1);
  • 9、生成数组
    // toArray(),Object数组
    Stream.of(words.split("\\PL+"))
            .toArray();
    // toArray(),String数组
    Stream.of(words.split("\\PL+"))
            .toArray(String[]::new);
  • 10、生成List、Set、字符串
    // collect(Collectors.toList()),生成list
    Stream.of(words.split("\\PL+"))
            .collect(Collectors.toList());
    // collect(Collectors.toSet()),生成set
    Stream.of(words.split("\\PL+"))
            .collect(Collectors.toSet());
    // collect(Collectors.joining()),生成String
    Stream.of(words.split("\\PL+"))
            .collect(Collectors.joining());
  • 11、生成统计数据
    // collect(Collectors.summarizingInt(f)),统计数据
    IntSummaryStatistics statistics = Stream.of(words.split("\\PL+"))
            .collect(Collectors.summarizingInt(String::length));
    statistics.getAverage();
    statistics.getSum();
    statistics.getCount();
    statistics.getMax();
    statistics.getMin();
  • 12、生成map
    // collect(Collectors.toMap(f, f)),生成map
    Map<String, String> strMap = Stream.of(words.split("\\PL+"))
            .collect(Collectors.toMap(a -> a.substring(0, 1), a -> a));
    // collect(groupingBy),生成map/list
    Map<String, List<String>> strListMap = Stream.of(words.split("\\PL+"))
            .collect(Collectors.groupingBy(a -> a.substring(0, 1)));
    // collect(groupingBy, toSet/counting),生成map/set、count、sum等
    Map<String, Set<String>> strSetMap = Stream.of(words.split("\\PL+"))
            .collect(Collectors.groupingBy(a -> a.substring(0, 1), Collectors.toSet()));
    Map<String, Long> strCount = Stream.of(words.split("\\PL+"))
            .collect(Collectors.groupingBy(a -> a.substring(0, 1), Collectors.counting()));
    // collect(groupingBy, mapping(f, toSet()/toList)),多层分组
    Map<String, Set<String>> strSetMapMap = Stream.of(words.split("\\PL+"))
            .collect(Collectors.groupingBy(a -> a.substring(0, 2),
                    Collectors.mapping(a -> a.substring(0, 1),
                            Collectors.toSet())));
  • 13、约简操作
    // reduce(),约简
    IntStream.of(1, 2, 3).reduce(0, (x, y) -> x + y);
    Stream.of(words.split("\\PL+"))
            .reduce(0, 
                    (total, word) -> total + word.length(), 
                    (total1, total2) -> total1 + total2);
  • 14、基本类型流

    存储基本类型;

    IntStream:char、short、byte、boolean都可以用IntStream表示;

    DoubleStream:float都可以用DoubleStream表示;

    LongStream:无;