Day 27 Lambda表达式、函数式接口

1、Lambda

1.1 概述

Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

也叫箭头函数。

1.2 为什么要用

Lambda表达式其实就是一个匿名内部类的简写方式

可以使程序更加简洁清晰,编程效率也得到了提高

1.3 和匿名内部类对比

forEach(arr,new Array(){
   @Override
   public void m1(int i){
       System.out.println(i);
     }
});
//Lambda
  forEach(arr,i->System.out.println(i));

更简洁了

1.4 语法结构

可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。

可选的大括号:如果主体包含了一个语句,就不需要使用大括号。

如果不写{}  return 不能写  分号不能写

 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值

如果只有一条语句,并且是返回值语句,就可以不写return 不写 {}  

如果写上{}  就必须写return 和 ;

如果有 多条语句,必须写{}  return 和 ;  也必须写

1.5示例

public static void main(String[] args) {
		List<Integer>list=new ArrayList<Integer>();
	    list.add(1);
	    list.add(2);
	    list.add(3);
//	    常规写法
	    for(Integer integer:list){
	    	System.out.println(integer);
	    }
//	    匿名内部类写法
	    list.forEach(new Consumer<Integer>() {

			@Override
			public void accept(Integer t) {
				System.out.println(t);	
			}
		});
//	    Lambda写法
	 list.forEach(x->System.out.println(x));
	
	}

2、函数式接口

2.1 介绍

其本质是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。 

核心目标是为了给Lambda表达式的使用提供更好的支持,进一步达到函数式编程的目标,可通过运用函数式编程极大地提高编程效率。 

其可以被隐式转换为 lambda 表达式。

2.2 特点

函数式接口是仅制定一个抽象方法的接口,可以包含一个或多个静态或默认方法

专用注解即@FunctionalInterface 检查它是否是一个函数式接口,也可不添加该注解

如果有两个或以上 抽象方法,就不能当成函数式接口去使用,也不能添加@FunctionalInterface这个注解

如果只有一个抽象方法,那么@FunctionalInterface注解 加不加 都可以当做函数式接口去使用

2.3 代码实现

Consumer<T>接口

import java.util.function.Consumer;
//  Consumer 代表了消费者,提供了accept方法 有参数 但是无返回值
public class _01_Functions {
	public static void main(String[] args) {
		int[]arr={1,2,3,4};
		forEach(arr, (i) -> System.out.println(i + "++++++++++"));
		}

		// 封装的功能,完成遍历操作,但是需要传递数组,和要做的事
		// 该方法只是帮我们遍历而已
		public static void forEach(int[] arr, Consumer<Integer> c) {
			for (int i : arr) {
				c.accept(i);
			}
		}

	}

Function<T,R>接口

Function : 有参有返回值,提供了 apply方法

public static Integer m1(String string,Function<String,Integer>fun){
		return fun.apply(string);	
	}
	public static void main(String[]args){
		String string="123";
		int result=m1(string,s->Integer.parseInt(s)*10);
		System.out.println(result);
	}

Consumer<T>接口

Supplier 代表供应商,有返回值,可以获取数据使用

public static void main(String[] args) {
		String string ="张三";
		String result = getResult(()->"我叫"+string);
		System.out.println(result);

	
	}
//	Supplier 代表供应商,有返回值,可以获取数据使用
	public static String getResult(Supplier<String>supplier){
		 return supplier.get();
		// TODO Auto-generated method stub
		
	}

3、方法引用和构造器调用

3.1 对象调用成员

  对象引用::成员方法名

  要求:需要根据调用方法的入参和出参去选择对应的函数式接口才行

public static void main(String[] args) {
		Integer i1=new Integer(123);
		Supplier<String>su=()->i1.toString();
		System.out.println(su.get());
//		对象引用::成员方法名
		su=i1::toString;
		System.out.println(su.get());

3.2 类名调用静态

类名::静态

public class _02_FunCall {
	public static void main(String[] args) {
//类名::静态
		Function<String, Integer> fun = Integer::parseInt;
		System.out.println(fun.apply("123"));
// 前两个是入参,第三个是返回值
		BiFunction<Integer, Integer, Integer> bif = Integer::max;
		System.out.println(bif.apply(123, 323));

3.3 类名调用成员

类名::成员方法名

public class _03_FunCall {
	public static void main(String[] args) {
		BiPredicate<String, String>bp=String::equals;
		System.out.println(bp.test("abc","abc"));

4、StreamAPI

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class _01_Stream {
	public static void main(String[] args) {
		// 1 数组转换为流
		String[] strings = { "q", "w", "e", "r" };
		Stream<String> stream1= Stream.of(strings);

		// 2 通过集合
		// Arrays.asList : 把数组转换为集合
		List<String> list = Arrays.asList(strings);
		stream1  = list.stream();
		
		// 3 通过Stream的generate创建
		// 但是是一个无限流(无限大),所以经常结合limit一起使用,来限制最大个数
		// generate参数是一个 Supplier ,而 Supplier中有一个get方法用于获取数据
		// 而 get方法的返回值,会作为数据保存到这个流中,下面程序也就意味中该流中的数据都是1
		Stream<Integer> stream2 = Stream.generate(()->1);
		// limit 是中间操作,设置流的最大个数
		// forEach 遍历,是终止操作
		stream2.limit(5).forEach(x->System.out.println(x) );
		// 4 通过String.iterate
		// 同上,是无限流
		// 参数1 是起始值, 参数二 是function, 有参有返回值
		// x+2 等于步长为二  for(int i =1 ; true ; i+=2)
		Stream<Integer> stream3 = Stream.iterate(1, x->x+2);
		stream3.limit(10).forEach(x->System.out.println(x));
		
		// 5 已有类的API
		String string = "abc";
		IntStream chars = string.chars();
		chars.forEach(x->System.out.println(x));
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值