Lambda表达式、函数式接口

Lambda

概述

Lambda表达式是一种没有名字的函数,也可称为闭包,是Java 8 发布的最重要新特性。

本质上是一段匿名内部类,也可以是一段可以传递的代码。

还有叫箭头函数的...

优点

是匿名内部类的简写方式,使代码更加简洁

和匿名内部类对比

package day_7_26_1_Lambda;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Lambda_1 {
	public static void main(String[] args) {
		String[] str ={"12","48","16","15"};
		//转换为List
		List<String> strings=Arrays.asList(str);
		//匿名内部类
		Collections.sort(strings,new Comparator<String>(){

			@Override
			public int compare(String o1, String o2) {
				Integer i1=Integer.valueOf(o1);
				Integer i2=Integer.valueOf(o2);
				//升序
				return i1-i2;
			}
		});
		System.out.print(strings);
		//箭头函数
		Collections.sort(strings,(s1,s2)->{
			//多条语句
			Integer i1=Integer.valueOf(s1);
			Integer i2=Integer.valueOf(s2);
			//降序
			return i2-i1;
		});
		System.out.println(strings);
	}
}

语法结构

(参数,参数,参数...) -> {方法体}

1 无参和多参,小括号必须写

2 只有一个参数的时候,小括号可以不写

3 如果只有一条语句,大括号也可以不写,并且语句结尾不需要 分号

4 如果只有一条语句,并且也是返回值语句的话,return 也要省略

5 如果是多条语句,必须加{},就是正常编码,该写分号写分号,该写return就写return

案例

package day_7_26_1_Lambda;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Lambda_2 {
	public static void main(String[] args){
		Integer[] is={1,5,6,8,4};
		List<Integer>list=Arrays.asList(is);
		//1.8之前的写法
		Collections.sort( list,new Comparator<Integer>(){
			@Override
			public int compare(Integer o1, Integer o2) {
				return o2-o1;
			}
		});
		//lambda写法
		Collections.sort(list,(x,y)->x-y);
		System.out.println(list);	
	}
}
package day_7_26_1_Lambda;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class Lambda_3 {
	public static void main(String[] args) {
		Integer[] is={1,5,9,7,3};
		List<Integer> list=Arrays.asList(is);
		//1.8之前的写法
		for(Integer integer:list){
			System.out.println(integer);
		}
		System.out.println("----");
		//1.8匿名内部类
		list.forEach(new Consumer<Integer>(){

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

	}

}

函数式接口

概述

英文称为Functional Interface

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

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

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

特点

函数式接口是仅制定一个抽象方法的接口

可以包含一个或多个静态或默认方法

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

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

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

自定义

package day_7_26_1_Function;

public class Function_1 {
	public static void main(String[] args) {
		//子实现类的写法
		Test test=new Test();
		m1(test);
		//匿名内部类
		m1(new MyFunction () {

			@Override
			public void print() {
				System.out.println("匿名内部类写法");
			}
		});
		//lambda写法
		m1(()->System.out.println("lambda的表达式写法"));
		
		
		
	}
		public static void  m1(MyFunction function){
			function.print();	
		}
}
//函数接口中,只允许出现一个抽象方法和n个非抽象方法
interface  MyFunction{
	public void print();
	
}
class Test implements  MyFunction{

	@Override
	public void print() {
		System.out.println("我是Test实现类");
	}
}

JDK自带的函数式接口

Supplier : 表示供应商,有个get方法,无参,有返回值,一般用于获取数据

Consumer : 表示消费者,accept,有参,无返回值

Function ,函数操作, apply , 有参也有返回值

Predicate 断言,用于做判断校验操作,test,需要传入参数并返回boolean类型

方法、构造器、数组

概述

Lambda表达式的另外一种形式

方法引用

package day_7_26_1_Funcall;

import java.util.function.Supplier;


/**
 * 对象引用 : 成员方法名
 * 
 * @author 啊超
 * @Date 2021年7月26日
 */
public class FunCall_1 {

	public static void main(String[] args) {
		Integer i1=12;
		Supplier<String>supplier=i1::toString;
		System.out.println(supplier.get());
		System.out.println(i1.toString());

	}

}
package day_7_26_1_Funcall;

import java.util.function.Function;
/**
 * 
 * 
 * 类名::静态方法名
 * @author 啊超
 * @Date 2021年7月26日
 */
public class FunCall_2 {
	public static void main(String[] args) {
		String string="123";
		Function<String,Integer> function= Integer::parseInt;
		int value =function.apply(string);
		System.out.println(value);
	}
}
package day_7_26_1_Funcall;

import java.util.function.BiPredicate;



/**
 * 
 * 
 * 类名::成员方法名
 * @author 啊超
 * @Date 2021年7月26日
 */
public class FunCall_3 {
	public static void main(String[] args) {
		BiPredicate<String,String> predicate= String::equals;
		System.out.println(predicate.test("a", new String("a")));
	}
}

构造器引用

package day_7_26_1_Funcall;

import java.util.function.Function;
import java.util.function.Supplier;
/**
 * 
 * 
 * 构造方法
 * @author 啊超
 * @Date 2021年7月26日
 */
public class FunCall_4 {
	public static void main(String[] args) {
		//无参构造
		Supplier<Object>s1=Object::new;
		System.out.println(s1.get());
		//有参构造
		Function< String,String> f1=String::new;
		System.out.println(f1.apply("dwa"));
		
	}
}

数组引用

package day_7_26_1_Funcall;

import java.util.function.Function;

public class FunCall_5 {
	public static void main(String[] args) {
		//泛型第一个是长度,第二个是返回值
		Function<Integer,Integer[]>fun=Integer[]::new;
		Integer[] arr=fun.apply(5);
		for(Integer integer :arr ){
			System.out.println(integer);
		}
	}
}

Stream  API

概述

数据渠道、管道,用于操作数据源(集合、数组等)所生成的元素序列。

集合讲的是数据,流讲的是计算

即一组用来处理数组,集合的API。

特点

Stream 不是数据结构,没有内部存储,自己不会存储元素。

Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。

Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

不支持索引访问。

延迟计算

支持并行

很容易生成数据或集合

支持过滤,查找,转换,汇总,聚合等操作。

应用场景

流式计算处理,需要延迟计算、更方便的并行计算

更灵活、简洁的集合处理方式场景

创建流的五种方式

package day_7_26_1_Stream;

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

public class Stream_1 {
	public static void main(String[] args) {
		//1数组
		String []strings={"a","c","e","g"};
		Stream<String > stream1=Stream.of(strings);
		
		//2通过集合
		List<String>string2=Arrays.asList(strings);  //集合
		Stream<String> stream2=string2.stream();   //流
		
		//3通过Stream.generate来创建
		//创建一个无限流,里面全是1,并且通过limit限制条数是5条
		Stream<Integer> generate=Stream.generate(()->1);  //无参,只有一个返回值
		generate.limit(5).forEach(x->System.out.println(x));
		
		//4通过一个Stream.iterate来创建
		//创建一个无限流,里面的数据有序,从2开始,步长为3;
		Stream<Integer>iterate=Stream.iterate(2, x->x+3);    // 必须有序
		iterate.limit(5).forEach(x->System.out.println(x));

		//5通过已有API
		String string="abc";
		IntStream chars=string.chars();
		chars.forEach(x->System.out.println(x));
	}
}

转换算子

概述

转换算子,又称为 中间操作,所有的转换算子得到的都是一个新的流,所以一般用于链式调用
 * 
 * 常用的转换算子
 * limit; 取集合中的前几条数据
 * filter;对元素进行过滤,不符合条件的就不要了
 * distinct;去除重复
 * skip;跳过
 * map;更改数据
 * sorted;排序
 * 注意;只有转换算子是不执行的,必须执行动作才会真正执行

常用方法

package day_7_26_1_Stream;

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




/**
 * 
 * 转换算子,又称为 中间操作,所有的转换算子得到的都是一个新的流,所以一般用于链式调用
 * 
 * 常用的转换算子
 * limit; 取集合中的前几条数据
 * filter;对元素进行过滤,不符合条件的就不要了
 * distinct;去除重复
 * skip;跳过
 * map;更改数据
 * sorted;排序
 * 注意;只有转换算子是不执行的,必须执行动作才会真正执行
 * 
 * 
 * @author 啊超
 * @Date 2021年7月26日
 */
public class Stream_2 {
	public static void main(String[] args) {
		List<String> strings=Arrays.asList("a","b","c","d");
		//只要a
		Stream<String> stream=strings.stream();
		//collect动作算子,把流中的数据转换为集合
		//filter不符合条件就不要了,返回false就是不要,true就是要
		List<String> value=stream.filter(x ->x.equals("a")).collect(Collectors.toList());
		System.out.println(value);
		//不要偶数
		List<Integer>integers=Arrays.asList(1,2,5,4,8,7478,745,42,7);
		Stream<Integer> stream1=integers.stream();
		List<Integer> value2=stream1.filter(x->x%2==1).collect(Collectors.toList());
		System.out.println(value2);
		//skip跳过元素
		stream1=integers.stream();
		value2=stream1.skip(2).collect(Collectors.toList());
		System.out.println(value2);	
		// distinct : 去重
				stream = strings.stream();
				value = stream.distinct().collect(Collectors.toList());
				System.out.println(value);
				
				// map : 遍历过程中对元素进行操作,比如涨薪
				List<Double> sal = Arrays.asList(1152.2,2000.5,8888.8);
				Stream<Double> salStream  = sal.stream();
				List<Double> newSal  = salStream.map(x->x*10).collect(Collectors.toList());
				System.out.println(newSal);
				
				// limit 前几条,比如查看前两名
				salStream  = sal.stream();
				// sorted 进行排序 y-x 是降序 , x-y 是升序
				newSal = salStream.sorted((x,y)->{
					if(y>x){
						return 1;
					}else if (y == x) {
						return 0;
					}else{
						return -1;
					}
				}).limit(2).collect(Collectors.toList());
				System.out.println(newSal);
	}
}

动作算子

package day_7_26_1_Stream;

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

public class Stream_3 {

	public static void main(String[] args) {
		List<String> strings = Arrays.asList("a", "b", "c", "a", "b", "c", "a",
				"b", "c");
		Stream<String> stream = strings.stream();
		// forEach
		stream.forEach(x -> System.out.println(x));

		// 计数 count
		stream = strings.stream();
		long count = stream.filter(x->x.equals("a")).count();
		System.out.println(count);
		
		// max 获取最大值  min 最小值
		List<Integer> integers = Arrays.asList(1,2,3,4,5);
		Stream<Integer> integerStream = integers.stream();
		Integer i1 = integerStream.max((x,y)->x-y).get();
		System.out.println(i1);
		
		// anyMatch 匹配数据,比如是否包含
		integerStream = integers.stream();
		boolean flag = integerStream.anyMatch(x->x==5);
		System.out.println(flag);
		// 当然这种是否包含可以使用contains解决,但是有的是contains解决不了的
		System.out.println(integers.contains(5));
		
		// 比如 所有的用户中 是否有19岁的
		List<User> users = new ArrayList<User>();
		users.add(new User("a", 18));
		users.add(new User("b", 19));
		users.add(new User("c", 20));
		Stream<User> userStream = users.stream();
		flag = userStream.anyMatch(u->u.age==19);
		System.out.println(flag);
	}
}
class User{
	String name;
	int age;
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值