Java基础——Lambda表达式

1.8新特性

Lambda表达式

简介

Lambda表示式(又称为闭包)是整个JAVA8发现版中最受期待的在Java语言层面上的改变
Lambda允许把函数作为一个参数(函数作为参数传递进方法中),或者把代码看成数据
Lambda表达式用于简化Java中接口式的匿名内部类,被称为函数式接口的概念,函数式接口就是一个具有一个方法的普通接口,像这样的接口可以被隐式转换为Lambda表达式

作用:简化代码
要求:一个接口或抽象类中只有一个抽象方法
优点:
	1、简化代码
	2、不会生成class文件
缺点:
	1、有限制
	2、对新手代码阅读增加困难

语法

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

Lambda表达式与函数式接口

1、没有参数时使用lambda表达式
public class Test01 {
	public static void main(String[] args) {
		IEatImpl iEatImpl = new IEatImpl();
		iEatImpl.eat();
		IEat iEat = new IEat() {
			@Override
			public void eat() {
				// TODO Auto-generated method stub
				System.out.println("吃东西01");
			}
		};
		iEat.eat();
		/**
		 * Labdma写法
		 */
		IEat iEat02 = ()->{
			System.out.println("吃东西02");
		};
		iEat02.eat();
	}
}
interface IEat{
	void eat();
}
class IEatImpl implements IEat{
	@Override
	public void eat() {
		// TODO Auto-generated method stub
			System.out.println("吃东西");
	}
}
2、带有参数时使用lambda表达式
public class Test01 {
	public static void main(String[] args) {
		IEat iEat01 = (String foodName)->{
			System.out.println("吃"+foodName);
		};
		iEat01.eat("桃子");
		
		IEat iEat02 = (foodName)->{
			System.out.println("吃"+foodName);
		};
		iEat02.eat("桃子");
		//方法中只有一个参数可以忽略()不写
		IEat iEat03 = foodName->{
			System.out.println("吃"+foodName);
		};
		iEat03.eat("桃子");
		IEat02 iEat04 = (foodName,name)->{
			System.out.println(name+"吃"+foodName);
		};
		iEat04.eat("桃子","张三");
	}
}
interface IEat{
	void eat(String foodName);
}
interface IEat02{
	void eat(String foodName,String name);
}
3、代码块中只有一句代码时使用lambda表达式
public class Test01 {
	public static void main(String[] args) {
		IEat iEat02 = ()->System.out.println("吃东西");
		iEat02.eat();
	}
}
interface IEat{
	void eat();
}
4、代码块中有多句代码时使用lambda表达式
public class Test01 {
	public static void main(String[] args) {
		IEat iEat = ()->{
			System.out.println("准备干饭");
			System.out.println("吃东西");
			System.out.println("就餐完毕");
		};

		iEat.eat();
	}
}
interface IEat{
	void eat();
}
5、有返回值的代码块
public class Test01 {
	public static void main(String[] args) {
		IEat iEat = ()->{
			System.out.println("吃东西");
			return true;
		};
		iEat.eat();
		//有返回值得方法体只有一句代码,忽略大括号与return关键字
		IEat iEat = ()->true;
		iEat.eat();
	}
}
interface IEat{
	boolean eat();
}
6、参数中使用final关键字
public class Test01 {
	public static void main(String[] args) {
		IEat iEat = (final String foodName)->{
			System.out.println("吃"+foodName);
			return true;
		};
		iEat.eat();
	}
}
interface IEat{
	boolean eat(final String foodName);
}

相关注解

@FunctionalInterface

常见函数式接口

接口名称			类型				方法
Consumer<T>		消费型接口		void accept(T t):操作t
Supplier<T>		供给型接口		T get():返回t
Function<T,R>	函数型接口		R apply(T t):操作t,返回r
Predicate<T>	断言型接口		boolean test(T t):操作t,返回boolean

方法引用

简介

方法引用是Lambda表达式的一种简写形式
要求:如果Lambda表达式方法体中只是调用一个特殊的已经存在的方法,则可以使用方法引用

语法

1、对象::实例方法
	要求:lambda传入的参数与就是所调用的方法的参数,并且方法体中只有一行代码
	代码:
		Consumer<String> consumer=s->System.out.println(s);
		consumer.accept("hello");
		Consumer<String> consumer2=System.out::println;
		consumer2.accept("world");
2、类::静态方法
	要求:lambda传入的参数与就是所调用的方法的参数,并且方法体中只有一行代码
	代码:
		Comparator<Integer> com=(o1,o2)->Integer.compare(o1, o2);
		Comparator<Integer> com2=Integer::compare;
3、类::实例方法
	要求:lambda传入的参数类型就是调用该方法的对象,并且方法体中只有一行代码
	代码:
		Function<Employee, String> function=e->e.getName();
		Function<Employee, String> function2=Employee::getName;
		System.out.println(function2.apply(new Employee("小明", 50000)));
		class Employee{
			private String name;
			private int money;
			public Employee(String name,int money) {
				this.money = money;
				this.name = name;
			}
			public String getName() {
				return name;
			}
		}
4、类::new
	要求:lambda方法体中只有一行创建对象的代码,并且返回值就是该对象
	代码:
		Supplier<Employee> supplier=()->new Employee();
		Supplier<Employee> supplier2=Employee::new;
		Employee employee=supplier.get();
		class Employee{
			private String name;
			private int money;
			public Employee(String name,int money) {
				this.money = money;
				this.name = name;
			}
			public String getName() {
				return name;
			}
		}

Stream

简介

Stream:流
	与集合类似,但是集合中存储的是数据,而Stream中存储的是对数据的操作过程
如图:
	原料 -> 工序1 -> 工序2 -> 工序n -> 产品
注意:
	1,Stream不会存储数据
	2,Stream不会改变原数据,他们会返回一个持有加工后数据的新Stream
	3,Stream会延迟执行,会等到需要的结果才执行

使用步骤

创建:
	新建一个Stream
	
中间操作:
	在一个或多个步骤中,将初始Stream转换为另一个Stream的中间操作
	
终止操作:
	使用一个终止操作来产生一个结果,该操作会强制之前的延迟操作立即执行.此后该Stream不能在使用

获取Stream

1,通过集合对象(Collection)stream()parallelStream()方法
	代码:
		ArrayList<String> arrayList=new ArrayList<>();
		//并行流
		Stream<String> stream = arrayList.parallelStream();ArrayList<String> list = new ArrayList<String>();
		Stream<String> stream = list.stream();
2,通过Arrays工具类的静态stream方法
	代码:
		String[] arr= {"aaa","bbb","ccc"};
		Stream<String> stream2=Arrays.stream(arr);
3,通过Stream接口中的静态of,iterate,generate方法
	代码:of普通流
		Stream<Integer> stream = Stream.of(10,20,30,40,50);
	代码:iterate迭代流
		Stream<Integer> iterate = Stream.iterate(0, x->x+2);
	代码:generate生成流
		Stream<Integer> generate = Stream.generate(()->new
		Random().nextInt(100));
4,通过IntStream,LongStream,DoubleStream接口的of,range,rangeClosed方法
	代码:
		IntStream stream = IntStream.of(100,200,300);
	代码:
		IntStream range = IntStream.rangeClosed(0, 50);

中间操作

1,filter过滤
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		//获取薪资大于15000,forEach终止操作,遍历结果
		list.stream()
			.filter(e->e.getMoney()>15000)
			.forEach(System.out::println);
2,limit限制
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		//获取集合中前两个输出
		list.stream()
			.limit(2)
			.forEach(System.out::println);
3,skip跳过
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		//跳过集合中前两个输出
		list.stream()
			.skip(2)
			.forEach(System.out::println);
4,distinct去掉重复
	注意:存储对象必须实现hashCode()equals()方法,用这两个方法判断是否重复,先调用哪个
hashCode方法,如果该方法的返回值与存储其他数据一致,在调用equals比较
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		list.stream()
			.distinct()
			.forEach(System.out::println);
5,sorted排序
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		list.stream()
			.sorted((e1,e2)->Double.compare(e1.getMoney(), e2.getMoney()))
			.forEach(System.out::println);
6,map映射操作
	简介:将当前Stream中的每个元素都映射转换为另一个元素,从而得到一个新的Stream
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		list.stream()
			.map(e->e.getName())
			.forEach(System.out::println);
7,parallel并行流
	简介:采用多线程 效率高
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		list.stream().parallel()
		.forEach(System.out::println);

终止操作

1,forEach遍历
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		list.stream().forEach(System.out::println);
		
2,min最小值
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		Optional<Employee> min = list.stream().min((o1,o2)-
>Integer.compare(o1.getMoney(), o2.getMoney()));
		System.out.println(min.get());

3,max最大值
	代码:
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		Optional<Employee> max = list.stream().max((e1,e2)->Integer.compare(e1.getMoney(), e2.getMoney()));
		System.out.println(max.get());

4,count数量
	代码:
		//薪资大于20000的人数
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		long count = list.stream().filter(o -> o.getMoney()>20000).count();
		System.out.println(count);

5,reduce规约
	代码:
		//所有员工薪资和
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		Optional<Double> sum = list.stream()
			.map(e->e.getMoney())
			.reduce((x,y)->x+y);
		System.out.println(sum.get());

6,collect收集
	代码:
		//获取所有的员工姓名,封装成一个list集合
		ArrayList<Employee> list=new ArrayList<>();
		list.add(new Employee("小王", 15000));
		list.add(new Employee("小张", 12000));
		list.add(new Employee("小李", 18000));
		list.add(new Employee("小孙", 20000));
		list.add(new Employee("小刘", 25000));
		list.add(new Employee("小刘", 25000));
		List<String> names = list.stream()
			.map(e->e.getName())
			.collect(Collectors.toList());
		for (String string : names) {
			System.out.println(string);
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值