[JAVA]函数式编程及Stream的操作

[JAVA]函数式编程及Stream的操作

0.前言

Java 8时为了实现函数式编程,引出了三个重要概念

  1. Lambda 表达式,Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。但仅当接口只有一个抽象方法时,才可以使用 lambda 表达式。
  2. 方法引用,可以直接引用已有Java类或对象(实例)的方法或构造器。
  3. 函数式接口,一个有且仅有一个抽象方法,但可以有多个非抽象方法。函数式接口有@FunctionalInterface注解。
    例如:
// 1. 无参无返回值
Runnable noArgsNoRet = () -> System.out.println("Hello Lambda");
// 2. 有参无返回值
Consumer<String> oneArgsNoRet = str -> System.out.println(str);
// 3. 无参有方法体
Supplier<String> noArgsHasRet = () -> {
    String str = "a" + "b";
    return str;
};
// 4. 有两个参数,有返回值,将方法体的计算结果作为返回值返回
BinaryOperator<Integer> add = (x, y) -> x + y;
// 5. 注明类型的参数
Consumer<String> oneArgs = (String str) -> System.out.println(str);

思想:Java 是面向对象的语言,变量只会被赋值为对象或基本类型,很显然函数不可能被赋值给变量!Java只是将函数这个行为,传递给了抽象接口的方法,告诉这个抽象接口,你的方法要用我的这个函数实现!
参考:https://zhuanlan.zhihu.com/p/407578877

1.四大函数式接口

1.1函数式接口说明

接口方法类型说明
Consumeraccept(Object)消费型接受单个输入参数且不返回任何结果
Predicatetest(Object)断言型接受单个输入参数且返回一个boolean
Supplierget()供给型无参数,有返回值
Functionapply(Object)函数型接受一个参数,有返回值
    public static void main(String[] args) {
        byte[] bytes = TestInterface.testFunction("abdsf", s -> s.getBytes());
        boolean bool = TestInterface.testPredicate("adqwcfasfadf", s -> s.length() > 2);
        String string = TestInterface.testSupplier(() -> "sad21da");
        Integer[] ints = {1,5,2,8,2,3};
        List<Integer> list = Arrays.asList(ints);
        TestInterface.testCosumer(list, integers -> integers.forEach(integer -> System.out.print(integer)));
        TestInterface.testCosumer(list, integers -> integers.forEach(System.out::print));

    }
    public static byte[] testFunction(String s, Function<String,byte[]> f){
        return f.apply(s);
    }
    public static boolean testPredicate(String s, Predicate<String> p){
        return p.test(s);
    }
    public static String testSupplier(Supplier<String> s){
        return s.get();
    }
    public static void testCosumer(List<Integer> array, Consumer<List<Integer>> c){
        c.accept(array);
    }

2.函数式接口在Stream中的应用

2.1Stream的生成

    /*
     1.生成流的常用方式
    */
    String[] strings = new String[]{"a","ab","a","cba"};
    //1.1通过集合生成流
    List<String> stringList = Arrays.asList(strings);
    Stream<String> listStream = stringList.stream();
    //1.2通过数组生成流
    Stream<String> arraysStream = Arrays.stream(strings);
    //1.3通过值
    Stream<String> valueStream = Stream.of("a", "ab", "abc", "cba");
    //1.4通过文件生成。通过Files.line方法得到流,每个流是文件中的一行
    Stream<String> lineStream = Files.lines(Paths.get("config.properties"), Charset.defaultCharset());

2.2函数式接口及Stream的操作

Stream的操作:
一类是转换操作,即把一个Stream转换为另一个Stream,即方法调用后仍为一个Stream,例如map()和filter();
另一类是聚合操作,即对Stream的每个元素进行计算,得到一个确定的结果,可能是一个对象,也可能是返回空,例如reduce()。

2.2.1转换操作
        /*
          2. 流的中间操作
         */

        //2.1 filter过滤,需要传Predicate类型的参数
        Stream<String> filterStream = valueStream.filter((s) -> s.length() > 2);
        //2.2 map
        Stream<Integer> mapStream = valueStream.map(s -> s.length());
        //2.3 sorted
        Stream<String> sortedStream = valueStream.sorted(String::compareTo);
        //2.4 distinct
        Stream<String> distinctStream = valueStream.distinct();
        //2.5 skip
        Stream<String> skipStream = valueStream.skip(2);
        //2.6 limit
        Stream<String> limitStream = valueStream.skip(2).limit(1);
        //2.7 concat
        Stream<String> concatStream = Stream.concat(valueStream, limitStream);
        //2.8 flatMap:flatMap的效果,各个数组不是分别映射成一个流,而是映射成流的内容
        Stream<List<String>> valueStream1 = Stream.of(Arrays.asList("ac", "ad"), Arrays.asList("ac", "ad"));
        Stream<String> stringStream = valueStream1.flatMap(list -> list.stream());
2.2.2转换操作
        /*
          3. 流的聚合操作
         */

        //3.1 reduce
        String reduceStream = valueStream.reduce("", (sall, s) -> sall + s);
        List<String> reduce = valueStream.map(s -> {
            List<String> asList = Arrays.asList(s.split(" "));
            return asList;
        }).reduce(new ArrayList<>(), (list, asList) -> {list.addAll(asList);return list;});
        //3.2 foreach
        valueStream.forEach(System.out::println);
        //3.3 collect
        List<String> collect = valueStream.collect(Collectors.toList());
        //3.4 count
        long count = valueStream.count();
        //3.5 max
        String s = valueStream.max((o1, o2) -> o1.compareTo(o2)).get();

参考:https://blog.csdn.net/qq_45797625/article/details/117636256

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值