Java函数式接口和Stream流

函数式接口

函数式接口概述
  • 概念
    有且仅有一个抽象方法的接口
  • 如何检测一个接口是不是函数式接口
    @FunctionalInterface
    放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败
  • 注意事项
    我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算我不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。但是,建议加上该注解
  1. 函数式接口可以作为方法的参数 //也就是用lambda表达式作为参数,下方同理
  2. 函数式接口可以作为方法的返回值
函数式接口Supplier
  • Supplier接口
    Supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产
    什么类型的数据供我们使用。
方法名说明
T get()按照某种实现逻辑(由Lambda表达式实现)返回一个数据
import java.util.function.Supplier;

public class example_2 {
    public static void main(String[] args) {
        String s = show(() -> {
            return "hello";
        });
        System.out.println(s);
    }

    private static String show(Supplier<String> supplier) {
        return supplier.get();
    }
}
函数式接口Consumer
  • Consumer接口
    Consumer接口也被称为消费型接口,它消费的数据的数据类型由泛型指定
方法名说明
void accept(T t)对给定的参数执行此操作
default Consumer andThen(Consumer after)返回一个组合的Consumer,依次执行此操作,然后执行after操作
import java.util.function.Consumer;

public class example_4 {
    public static void main(String[] args) {
        operatorString("Java", s -> {
            StringBuilder reverse = new StringBuilder(s).reverse(); //将字符串翻转
            System.out.println(reverse);
        });
    }

    private static void operatorString(String name, Consumer<String> consumer) {
        consumer.accept(name);
    }
}

使用方法andThen()方法需要两个参数
例如

con1.andThen(con2).accept(name);

意思就是操作完1后再操作2

函数式接口Predicate
  • Predicate接口
    Predicate接口通常用于判断参数是否满足指定的条件
方法名说明
boolean test(T t)对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
default Predicate negate()返回一个逻辑的否定,对应逻辑非
default Predicate and(Predicate other)返回一个组合判断,对应短路与
default Predicate or(Predicate other)返回一个组合判断,对应短路或
import java.util.function.Predicate;

public class example_5 {
    public static void main(String[] args) {
        boolean b = checkString("hello", s -> {
            return s.length() > 88;
        });
        System.out.println(b);
    }

    private static boolean checkString(String s, Predicate<String> predicate) {
        return predicate.negate().test(s);  //由于进行了negate操作所以就为true
    }
}
函数式接口Function
  • Function接口
    Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值
方法名说明
R apply(T t)将此函数应用于给定的参数default Function
andThen(Function after)返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果

将字符串类型转为int类型

import java.util.function.Function;

public class example_6 {
    public static void main(String[] args) {
        convert("711" , s -> {    //myBirthday:)
            return Integer.parseInt(s);
        });
    }

    private static void convert(String s, Function<String,Integer> function) {
        Integer apply = function.apply(s);
        System.out.println(apply);
    }
}

Stream流

  • Stream流的好处
    • 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义
    • Stream流把真正的函数式编程风格引入到Java中

先看一个例子

import java.util.ArrayList;

public class example_7 {
    public static void main(String[] args) {
        ArrayList<String> studentList = new ArrayList<String>();
        studentList.add("梁小敏");
        studentList.add("许三多");
        studentList.add("梁非凡");
        studentList.add("刘松");
        studentList.add("梁飞");
        //不使用Stream流的代码量:
        System.out.println("不使用Stream流:");
        ArrayList<String> arrayList = new ArrayList<>();
        for (String s :
                studentList) {
            if (s.startsWith("梁")) {    //过滤姓梁的学生
                arrayList.add(s);
            }
        }
        ArrayList<String> arrayList2 = new ArrayList<>();
        for (String s :
                arrayList) {
            if (s.length() == 3) {  //只要名字长度为3的
                arrayList2.add(s);
            }
        }
        for (String s :
                arrayList2) {   //遍历
            System.out.println(s);
        }
        //使用Stream流的代码量:
        System.out.println("使用stream流");
        studentList.stream().filter(s -> s.startsWith("梁")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
    }
}

在这里插入图片描述
从例子看出使用Stream流可以使代码量大大减少,接下来是对Stream流的具体介绍和使用

Stream流的常见生成方式
  • 生成Stream流的方式
    • Collection体系集合 //也就是ListSet
      使用默认方法stream()生成流, default Stream stream()
    • Map体系集合
      把Map转成Set集合,间接的生成流 //通过方法将Map转为Set
    • 数组
      通过Stream接口的静态方法of(T… values)生成流
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;

public class example_1 {
    public static void main(String[] args) {
        
        //Collection体系的集合可以使用stream()方法生成流
        ArrayList<String> arrayList = new ArrayList<>();
        Stream<String> stream = arrayList.stream();
        HashSet<String> hashSet = new HashSet<>();
        Stream<String> stringStream = hashSet.stream();

        //Map体系间接生成
        HashMap<String, Integer> hashMap = new HashMap<>();
        Set<String> keySet = hashMap.keySet();  
        Stream<String> stringStream1 = keySet.stream(); //间接生成
        
        //数组
        String[] strArray = {"hello","hi","Java"};
        Stream<String> strArray1 = Stream.of(strArray); //接口调用静态方法生成
        Stream<String> stringStream2 = Stream.of("10", "20", "30"); //通过数组的可变参数生成
    }
}
Stream流中间操作方法
  • 概念
    中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作。
方法名说明
Stream filter(Predicate predicate)用于对流中的数据进行过滤
Stream limit(long maxSize)返回此流中的元素组成的流,截取前指定参数个数的数据
Stream skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static Stream concat(Stream a, Stream b)合并a和b两个流为一个流
Stream distinct()返回由该流的不同元素(根据Object.equals(Object) )组成的流
Stream sorted()返回由此流的元素组成的流,根据自然顺序排序
Stream sorted(Comparator comparator)返回由该流的元素组成的流,根据提供的Comparator进行排序
Stream map(Function mapper)返回由给定函数应用于此流的元素的结果组成的流
IntStream mapToInt(ToIntFunction mapper)返回一个IntStream其中包含将给定函数应用于此流的元素的结果

上述方法也就是其参数是一个lambda表达式进行相关的操作

ps: mapToInt()方法里面可以调用sum()方法对整形集合进行求和操作

Stream流终结操作方法
  • 概念
    终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作。
方法名说明
void for each(Consumer action)对此流的每个元素执行操作 //用得较多
long count()返回此流中的元素数

ps : 总而言之使用Stream流的目的就是使代码更加简单明了,开发的效率提高

CET4P232

  • crust
  • insight
  • guideline
  • fireman
  • junior
  • observation
  • whale
  • nuclear
  • brand
  • mention
  • whatever
  • relax
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值