Java基础——Lambda表达式,函数式接口和Stream类

Lambda表达式

  1. 概念:
    本质上是一个对象,可以当作是匿名内部类创建的对象的简写格式。
  2. 格式:
    (参数)->{方法体}
  3. 说明:
    参数:需要重写的抽象方法中的形参列表
    ->:为了分隔前后两部分,Lambda运算符或者箭头运算符
    方法体:需要对抽象方法重写的内容
  4. 举例:
    (1)如果抽象方法没有参数,方法体只有一句:
    方法体外的大括号可以省略。
    格式:()->方法体语句;
    (2)如果抽象方法中有一个参数:
    参数的类型可以省略,参数外的小括号可以省略
    格式:参数名->{方法体语句};
    (3)如果方法的参数有多个:
    参数外的小括号不能省略,参数类型可以省略,方法体外的大括号可以省略。
    格式:(参数名称)->方法体语句;
    (4)如果方法有返回值:
    直接在方法体中的大括号中对数据进行return即可
    格式:(参数名称)->{
    方法体语句:
    return语句;
    };
    (5)如果方法需要返回值,而且方法体只有一句:
    可以将大括号和return关键字一起省略
    格式:(参数名称)->要返回的数据;
  5. Lanbda表达式和匿名内部类的区别:
    (1)如果接口中只有一个抽象方法,既可以使用匿名内部类创建,也可以使用Lambda创建。
    如果接口中有多个抽象方法,那么只能使用匿名内部类创建
    (2)在传递实际参数时,如果形参是接口,可以使用Lambda表达式传递,也可以使用匿名内部类传递。
    如果形参是某一类型,只能使用匿名内部类传递。(原因:不能使用Lambda表达式创建抽象类的子类对象)
    (3)匿名内部类会在磁盘中生成一个字节码文件,Lambda表达式则没有

函数式接口

  1. 概念:
    一个接口中如果只有一个抽象方法,那么这个接口就是一个函数式接口。
  2. 通过注解检测一个接口是否是一个函数式接口:
    @FunctionalInterface
    在接口上直接加上注解,如果这个接口是一个函数式接口则不报错,否则编译报错
  3. 使用场景:
    (1)Lambda表达式的使用前提
    (2)可以将函数式接口定义为方法的形参,再调用方法时,可以将利用Lambda表达式当作实参进行传递。
    (3)可以将函数式接口定义为方法的返回值类型,在调用方法时,可以利用Lambda表达式返回数据。
内置的函数式接口

1、在jdk8之后,官方定义了一些常用的函数式接口,如果以后需要使用类似的接口,直接使用即可,不需要再单独定义。
2、分类:
-Consumer :消费型接口
void accept(T t)
-Supplier :供给型接口
T get()
-Function<T,R> :函数型接口
R apply(T t)
-Predicate :断言型接口
boolean test(T t);

消费型接口
  1. Consumer
    void accept(T t):消费一个参数数据
    default Consumer andThen(Consumer<? super T> after) :
    返回一个组合的 Consumer ,按顺序执行该操作,然后执行 after操作。
  2. 概述:该接口中的方法可以接收一个参数,接收的参数类型由泛型指定,对参数的操作方式根据该接口的实现类决定,不需要返回值。
public static void main(String[] args) {
		Consumer<String> c1 = s->System.out.println(s);
		Consumer<String> c2 = s->System.out.println(s.length());
		//执行两个用andThen()
		get("雀食蟀",c1.andThen(c2));
	}
	public static void get(String s,Consumer<String> con) {
		con.accept(s);
	}
供给型接口
  1. Supplier :
    T get():该方法不需要参数,它会按照某种逻辑,返回一个具体的数据
  2. 概述:
    该接口也被称为生产型接口,如果指定了泛型是什么类型,那类中的get方法就会返回一个该类型的一个具体数据。返回的数据,由该接口的实现类对象决定。
//	1、定义一个方法,该方法可以返回一个集合,集合中可以存储10个1-10的随机整数。
	public static void main(String[] args) {
		System.out.println(get(()->new Random().nextInt(10)+1));
	}
	public static ArrayList<Integer> get(Supplier<Integer> s){
		ArrayList<Integer> list = new ArrayList<Integer>();
		for(int i = 1; i<=10;i++) {
			int x = s.get();
			list.add(x);
		}
		return list;
	}
函数型接口
  1. Function<T,R>
    R apply(T):接收一个数据,操作数据之后,返回一个新的数据
    default Function andThen(Function f):
    先通过调用者对象处理参数,将处理的结果再通过f对象处理,将两个处理的结果进行返回。
  2. 概述:
    该接口可以接收一个数据,数据的类型根据泛型指定,然后通过该接口的实现类对象对该数据进行操作,操作之后返回一个新的数据。
public static void main(String[] args) {
		System.out.println(get("100",s->Integer.parseInt(s)));
	}
	//输入字符串类型,返回整数类型
	public static Integer get(String s,Function<String, Integer> f) {
		Integer i = f.apply(s);
		return i;
	}
断言型接口
  1. Predicate:
    boolean test(T t):对数据做出指定的判断
  2. 概述:
    该接口是一个判断接口,接口可以接收一个指定泛型的参数,并根据该接口的实现类 对象对该参数做出对应的判断,返回只为boolean类型
  3. 额外功能:
    and(Predicate p):先将参数通过调用者判断真假,再将参数通过p判断真假,全真为真,否则为假
    or(Predicate p):全假为假,否则为真
    negate():取反
public static void main(String[] args) {
		Predicate<Integer> p1 = i-> i>=100;
		Predicate<Integer> p2 = i-> i<=100;
		System.out.println(p1.and(p2).test(100));//true
		System.out.println(p1.or(p2).test(101));//true
		//将参数使用p1的方式判断,将判断结果取反
		System.out.println(p1.negate().test(100));//false
	}
方法引用

1、概念:
对lambda表达式的扩展,在定义lambda表达式中的重写内容时,如果这个重写的内容之前已经写过,只需要去调用即可,不需要再写一遍。
2、格式:
如果是一个构造方法:类名::new
如果是一个静态方法:类名::方法名
如果是一个非静态方法:对象名::方法名

Stream类

  1. 概述:Java8之后提供的一个新的类型,该类型可以更加方便的操作一系列元素。
Stream类对象的获取
  1. Collection集合的获取方式:
    对象名.stream();
  2. Map集合获取方式:
    ketSet().Stream();
    values().stream();
    entrySet.stream();
  3. 数组的获取方式:
    Strem.of(数组名);
Stream类的常用方法
  1. Stream类中包含了一些对数据过滤和筛选以及获取的方法。
  2. 分类:
    延迟方法:使用完这个方法之后,返回值也是一个Stream类的对象,可以继续调用类中的方法。
    终结方法:使用完这个方法之后,返回值不再是一个Stream类的对象,不能继续使用这个类中的方法。
    3、方法罗列:
    (1)forEach(Consumer<? super T> action) :终结方法
    该方法可以自动获取流中每一个数据,并对获取的数据操作
    数据的操作方式根据消费型接口的实现类重写。
    (2)count() :返回此流中的元素数。终结方法
    (3)filter(Predicate<? super T> predicate) :延迟方法
    该方法可以自动获取流中的每一个数据进行判断,如果数据判断结果为真,就在流中存储,否则不存储该数据
    (4)limit(long m) :将流中的前m个元素保留,其余的删除 延迟方法
    (5)skip(long n) : 跳过前n个元素,保留后面的元素 延迟方法
    (6)map(Function<? super T,? extends R> mapper) : 延迟方法
    该方法自动获取流中的每一个数据,并对数据处理,处理之后返回一个新的数据。具体的处理方式根据实现类对象确定。
    (7)concat(Stream<? extends T> a, Stream<? extends T> b): 延迟方法(静态方法)
    将两个流中的数据进行合并,合并为一个流对象
    (8)distinct():去除流中重复的元素 延迟方法
    (9)toArray():把stream流中的数据收集到数组中
    (10)collect(Collector c):把stream流中的数据收集到指定的集合中
    Collector:参数的类型 是一个接口获取可以通过工具类Collectors的方法获取
    常用:
    获取List集合:Collectors.toList()
    获取Set集合: Collectors.toSet()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值