Java语法进阶及常用技术(六)--Lambda表达式

Lambda表达式

一、什么是Lambda表达式

JDK8开始支持Lambda表达式,用来让程序编写更优雅。
利用Lambda可以更简洁的实现匿名内部类函数声明与调用
基于Lambda提供stream流式处理极大简化对集合的操作。

1、传统代码

在这里插入图片描述

2、使用Lambda表达式

在这里插入图片描述

二、Lambda表达式语法

1、Lambda语法格式

在这里插入图片描述

2、Lambda表达式案例

//四则运算接口
public interface MathOperation{
	public Float operate(Integer a, Integer b);
}
public class LambdaSample{
	public static void main(String[] args){
		//1.标准使用方式
		MathOperation addition = (Integer a, Integer b)->{
			return a+b+0f;
		}
		addition.operate(5,3);//8.0
		//2.Lambda允许忽略参数类型
		MathOperation substraction = (a,b)->{
			return a-b+0f;
		}
		substraction.operate(5,3);//2.0
		//3.单行实现代码可以省略大括号和return
		MathOperation multiplication = (a,b)->a*b+0f;
		multiplication.operate(5,3);//15.0
	}
}

约束条件:Lambda表达式只能实现有且只有一个抽象方法的接口,Java称为“函数式接口”。

三、函数式编程

1、什么是函数式编程

函数式编程是基于函数式接口并使用lambda表达的编程方式。
函数式编程理念是将代码作为可重用数据代入到程序运行中。
函数式编程强调“你想做什么”,而不是“你想怎么做”。

2、什么是函数式接口

函数式接口是有且只有一个抽象方法的接口。
Java中拥有大量函数式接口,如java.lang.Runnable。
JDK8后提供了一系列新的函数式接口,位于java.util.function。
官方文档:
https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
JDK8常用函数式接口
在这里插入图片描述
可以通过@FunctionalInterface通知编译器这是函数式接口,进行抽象方法检查。

3、函数式接口Predicate

Predicate是新增的函数式接口,位于java.util.function。
Predicate用于测试传入的数据是否满足判断要求。
Predicate接口需要实现test()方法进行逻辑判断。
Predicate案例

public class PredicateSample{
	public static void main(String[] args){
		Predicate<Integer> predicate = n->n>4;
		predicate.test(10);//true	
		List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
		/*
		for(Integer num:list){
			if(num%2==1){
				sout(num+" ");
			}
		}
		*/
		filter(list, n->n%2==1);//取所有奇数 1 3 5 7 9
		filter(list, n->n%2==0);//取所有偶数 2 4 6 8 10
		filter(list, n->n>5 && n%2==0);//取所有大于5的偶数 6 8 10
	}
	public static void filter(List<Integer> list, Predicate<Integer> predicate){
		for(Integer num:list){
			if(predicate.test(num)){
				sout(num+" ");
			}
		}
	}

}

4、函数式接口Consumer

对应有一个输入参数无输出的功能代码。

public class ConsumerSample{
	public static void main(String[] args){
		output(s->sout("向控制台打印:"+s));
	}
	public static void output(Consumer<String> consumer){
		String text = "abc";
		consumer.accept(text);
	}
}

5、函数式接口Function<T,R>

对应有一个输入参数且需要返回数据的功能代码。

//利用Function函数式接口生成定长随机字符串
public class FunctionSample{
	public static void main(String[] args){
		Function<Integer, String> randomStringFunction = l->{
			String chars = "qwertyuiopasdfghjklzxcvbnm1234567890";
			StringBuffer stringBuffer = new StringBuffer();
			Random random = new Random();
			for(int i=0; i<l; i++){
				int position = random.nextInt(chars.length());
				stringBuffer.append(chars.charAt(position));
			}
			return stringBuffer.toString();
		}
		randomStringFunction.apply(32);//生成32位长随机字符串
	}
}

6、函数式编程与面向对象编程比较

在这里插入图片描述

四、Stream流式处理

Stream流式处理是建立在Lambda基础上的多数据处理技术。
Stream对集合数据处理进行高度抽象,极大简化代码量。
Stream可对集合进行迭代,去重,筛选,排序,聚合等一系列处理。
Stream示例
在这里插入图片描述

1、Stream常用方法

在这里插入图片描述
官方文档
https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

2、Stream操作实例

Stream流对象的五种创建方式

public class StreamGenerator{
	//1.基于数组进行创建
	@Test
	public void generator1(){
		String[] arr = {"Lily","Andy","Jackson","Smith"};
		Stream<String> stream = Stream.of(arr);
		stream.forEach(s->sout(s));
	}
	//2.基于集合进行创建
	@Test
	public void generator2(){
		List<String> list = new ArrayList<>();
		list.add("Lily");
		list.add("Andy");
		list.add("Jackson");
		list.add("Smith");
		Stream stream = list.stream();
		stream.forEach(s->sout(s));
	}
	//3.利用generate方法创建无限长度流,需要和limit配合使用
	@Test
	public void generator3(){
		Stream<Integer> stream = Stream.generate(()->new Random().nextInt(100000)); 
		stream.limit(10).forEach(i->sout(i));
	}
	//4.基于迭代器创建无限长度流,需要和limit配合使用
	@Test
	public void generator4(){
		Stream<Integer> stream = Stream.iterate(1,n->n+1); 
		stream.limit(100).forEach(i->sout(i));
	}
	//5.基于字符序列创建流
	@Test
	public void generator5(){
		String str = "abcdefg";
		IntStream stream = str.chars();
		stream.forEach(c->sout(c));//会输出每个字符的ANSI码
		stream.forEach(c->sout((char)c));//转成char后正常输出字符
	}
}

Stream方法案例

public class StreamMethod{
	//提取集合中所有偶数并求和
	@Test
	public void case1(){
		List<String> list = Arrays.asList("1","2","3","4","5","6");
		int sum = list.stream()//获取stream对象
			.mapToInt(s->Integer.parseInt(s))//mapToInt将流中每一个数据转换为整数
			.filter(n->n%2==0)//filter对流数据进行过滤
			.sum();//求和
		sout(sum);//12
	}
	//所有名字首字母大写
	@Test
	public void case2(){
		List<String> list = Arrays.asList("lily","smith","jackson");
		List newList = list.stream()
			//map按规则对每一个流数据进行转换
			.map(s->s.substring(0,1).toUpperCase()+s.substring(1))
			//.forEach(s->sout(s));	
			//collect对流数据进行收集,生成新的List/Set
			.collect(Collectors.toList());
	}
	//将所有奇数从大到小进行排序,且不允许出现重复
	@Test
	public void case3(){
		List<Integer> list = Arrays.asList(1,23,38,23,34,38,3);
		List newList = list.stream().distinct()//去除重复的流数据
			.filter(n->n%2==1)
			.sorted((a,b)->b-a)
			.collect(Collectors.toList());
		sout(newList);//[23,3,1]	
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值