文章摘要
预备工作
java中 有且 只有一个 抽象方法 的 接口 称为:=> 函数式接口
函数式接口的注解:@FunctionalInterface
写在接口上可以通知编译器进行抽象方法检查。
Java中拥有大量函数式接口
,位于:java.util.function 包中。📂
🚫Lambda表达式 只 支持 函数式接口
Lambda 表达式简介
JDK8开始 支持Lambda 表达式,让程序 更优雅。开发起来,更顺畅。利用Lambda 表达式可以更简洁的实现匿名内部类
与函数声明与调用
。Lambda 表达式提供了:strean流式处理极大简化对集合的操作。
传统代码 与 Lambda 表达式 de 比较
传统代码
List<String> names = Arrays.asList("peter","anna","mike","xenia");
//实现集合排序
Collections.sort(names,new Comparator<String>()){
@override
public int compare(String a,String b){
return b.compareTo(a);
}
});
Lambda 表达式
List<String> names = Arrays.asList("peter","anna","mike","xenia");
//通过lambda表达式简化匿名类的编写
Collections.sort(names,(a,b) -> b.compareTo(a))
一、Lambda语法格式
经典使用 案例:四则运算🎮
Lambda表达式还能 简化👇👇👇:省略了参数类型
YunSuan add = (a,b)->{
return a+b+0f;
};
System.out.println(add.siZe(5,3))
Lambda表达式还能 再简化👇👇👇:单行实现可省略大括号
YunSuan add = (a,b)-> a+b+0f;
System.out.println(add.siZe(5,3))
二、函数式编程
🔧函数式编程: 基于 函数式接口
并使用 Lambda表达式
编写写代码。
强调“你想做什么”,而不是“你想怎么做”。将代码作为可重用数据,带入程序中(案例一演示)。
1、函数式编程案例一:
说明:案例中使用 Predicate<T>
这个函数式接口。 该函数接口,用于测试传入的数据是否满足判断要求。和if语句差不多,满足条件返回true反之flase。该函数接口,需要实现test()方法进行逻辑判断。
对 list 集合 选取 - 奇偶数
public class PredicateSample {
public static void main(String[] args) {
// 先实验下 该接口的用法
// Predicate<Integer> predicate = n -> n>4;
// boolean result = predicate.test(5);
// System.out.println(result);
//对 list 集合 选取 - 奇偶数
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
filter(list,n -> n%2==1);//n 不是就是 下面number 的意思吗?
}
public static void filter(List<Integer> list , Predicate<Integer> predicate){
for (Integer number : list){
if (predicate.test(number)){
System.out.print(number+" ");
}
}
}
}
2、函数式编程案例二:
说明:案例中使用 Consumer<T>
这个函数式接口。 该函数接口,用于有一个输入参数,无输出的功能代码。
如何灵活的控制输出?
public class ConsumerSample {
//如何灵活的控制输出?
public static void output(Consumer<String> consumer){
String test = "他日若遂凌云志,敢笑黄巢不丈夫!";
consumer.accept(test);
}
public static void main(String[] args) {
output(s -> System.out.println("向控制台打印:"+s));
output(s -> {
//因为重写的方法返回值是void 所以下面没有return
System.out.println("向CSN打印:"+s);
});
}
}
3、函数式编程案例三:
说明:案例中使用 Function<T,R>
这个函数式接口。 该函数接口,用于有一个输入参数,且需要返回数据的功能代码。它有两个泛型:第一个泛型是说明参数的类型。第二个泛型说明返回的数据类型是什么。
利用 Function 接口 生成定长随机字符串
public class LambdaSample {
public static void main(String[] args) { //要生成多长的字符串
Function<Integer,String> randomStringFunction = n -> {
//生成字符的范围 字符集
String chars = "zbcdefghijklmnopqrstuvwxyz0123456789";
//随机挑选字符 最后连接起来
StringBuffer stringBuffer = new StringBuffer();
//生成随机数
Random random = new Random();
//来生成定长的随机字符串
for (int i = 0; i < n ; i ++){
//每次循环 会产生新的随机数,这个数据的范围是 我们设置的字符串长度内
//返回的数字代表了要截取的 哪一个 字符的位置
int index = random.nextInt(chars.length());
//chars.charAt(index) 是按照位置将字符提取出来,然后追加到stringBuffer里面
stringBuffer.append(chars.charAt(index));
}
//返回我们需要的字符串
return stringBuffer.toString();
};
String randomString = randomStringFunction.apply(16);
System.out.println(randomString);
}
}
三、Stream 流式处理
✈️Stream 流式处理是建立在Lambda基础上的多数据处理技术。 对集合数据处理进行高度抽象,极大简化代码量。Stream可以对集合进行迭代、去重、筛选、排序、聚合等一系列操作。 因为,最终产物是 一步一步加工出来的。像似流水线,所以称:流式处理。👈
Stream典型书写演示:👇👇👇
获取List集合中最大的奇数
Optional<Integer> op = Arrays.asList(1,2,3,4,5,6).stream()
.filter(x -> x%2 == 1)
.sorted((a,b) -> b-a)
.findFirst();
System.out.println(op.get());
Stream 常用方法:🏊🏊🏊
接口 | 用途 |
---|---|
forEach | 循环遍历 |
map | map 方法用于映射每个元素到对应的结果 |
filter | filter 方法用于通过设置条件过滤出元素 |
limit | limit 方法用于获取指定数量的流 |
sorted | sorted 方法用于对流进行排序 |
Collectors | Collectors 类实现将流转换成集合 和聚合元素 |
1、Streatm类 对象的创建
第1️⃣种创建方式: 基于数组进行创建
public void test1(){
String[] arr = {"A","B","C","D"};
//调用of()方法 对数组 解析 进行创建
Stream<String> stream = Stream.of(arr);
//括号里用的式Cosumer接口,然后用Lambda表达式实现,用法在案例二。
stream.forEach(s -> System.out.println(s));
}
要掌握 Stream.of() 生成与之对应的流对象。forEach()中可以使用Lambda表达式
第2️⃣种创建方式: 基于集合进行创建
public void Test2(){
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
//如何得到Stream对象呢? list 天生自带strea()方法
Stream<String> stream = list.stream()
stream.forEach(s -> System.out.println(s));
}
2、Streatm类 使用案例
🔶案例一、提取集合中所有偶数并求和
public void test(){
List<String> list = new Arrays.asList("1","2","3","4");
int sum = list.stream();//获取stream对象
.mapToInt(s -> Integer.parseInt(s))//映射到整数类型
.filter(n -> n%2 == 0)//对流中数据进行过滤
.sum();//求和
System.out.println(sum);
}
🔶案例二、所有名字首字母大写
public void test(){
List<String> list = new Arrays.asList("tom","jack","maaper");
List newlist = list.stream()
//获取每个元素。截取每个字符串的第一个字符。转大写。后半部分链接起来
.map(s -> s.substring(0,1).toUpperCase()+s.substring(1))
//.forEach(s -> System.out.println(s));
//可以将流中的数据 包装成新的list 或者set 并返回集合
.collect(Collectors.toList())
System.out.println(newlist);
}
🔶案例三、将所有奇数从大到小排列,且不许出现重复
public void test(){
List<String> list = Arrays.asList(2,61,33,87,35,90,77,99,38,61);
List newlist = list.stream().distinct()//去除重复的流数据
.filter(n -> n%2 ==1)
.sorted((a,b) -> b-a)//流数据去重
.collect(Collectors.toList());
System.out.println(newlist);
}
♨️Stream流式处理 就是提供了一系列方法,通过不同方法的进行组合=>得到一些复杂的运算操作。更多的方法细节可以去看API。百度搜索:java.util.stream。
总结
码字不易🐌,如果对您有所帮助不妨点个赞赞吧💖💖💖~
我爱你 ~ 无论我们在这个日子是否在一起,我也知道,爱一个人是劫,有人劫后重生,有人在劫难逃。😞
🙏愿: 宇宙的尽头没有 流式处理。