lambda以前没太关注,直到前段时间写了个接口,数据处理逻辑本身稍有些繁琐,写了几个处理方法看着可读性差,用stream流与lamdba后简化了不少。在这梳理入门级应用场景,至少要还看的懂java代码。
特地到oracle官网看了看这方面特性的介绍。
一、lambda
Java原本属于静态类型语言,由于lambda的出现,也在一定程度上和动态类型语言(javascript、python、lua等)沾上了亲戚。lambda的参数既是在运行期对数据类型做检查,并且在字节码文件的操作指令中添加invokeDynamic给lamdba使用。
静态类型语言在编译阶段检查数据的类型,需要显示的声明变量数据类型。
动态类型语言在运行期间才做数据类型检查。
1.1 lambda基础语法
前面(int a,int b)是接口的参数列表,后面{}是执行的方法体。
//声明函数式接口
public interface Lambda {
void test(int a,int b);
}
public interface Lambda1 {
void test(int a);
}
public interface Lambda2 {
int test(int a);
}
//实现多个参数 无返回值的接口
Lambda lambda = (int a,int b) ->{
System.out.println("a的值是" + a + ",b的值是" + b);
};
lambda.test(10,20);
1.2 对lambda进行精简
//精简1 方法体只有一句代码、无返回值,花括号可以省略;当参数列表只有1个参数时,参数列表的括号可以省略
Lambda1 lambda1 = a -> System.out.println("haha+" +a);
lambda1.test(15);
//精简2 有返回值时,省略方法体的{}与return
Lambda2 lambda2 = a -> a+a;
lambda1.test(15);
1.3 函数的引用
public class FunctionA {
private interface Calculate{
int calculate(int a, int b);
}
public static void main(String[] args) {
/**
* 静态方法函数引用
* 前提:方法的参数列表和返回值类型 必须和接口一致
* 类::静态方法
*/
Calculate cal2 = FunctionA::calculate;
System.out.println(cal2.calculate(10, 25));
/**
* 用对象来引用非静态方法
*/
Calculate cal3 = new FunctionA()::calculate2;
System.out.println(cal3.calculate(20,30));
}
//非静态方法
private int calculate2(int a,int b){
if(a == b){
return a + b;
}else {
return a + 10;
}
}
//静态方法
private static int calculate(int a, int b){
if (a > b){
return a-b;
}else {
return a + b;
}
}
}
二、Stream流
2.1 Stream常见用法
1 Java 中的 流 ( Stream ) 表示来自 源 ( source ) 的一系列对象,它支持统计、求和、求平均值等聚合操作。
2 流具有以下特征:
2.1 元素序列 : 流以顺序方式提供特定类型的一组元素。流只会按需获取/计算元素。但它从不存储元素。
2.2 源 ( Source ):流可以将集合,数组或 I/O 资源作为输入源。
2.3 聚合操作: 流支持聚合操作,如 filter、map、limit、reduce、find、match 等
2.4 管道 ( pipelining ):大多数流操作都返回流本身,以便可以对其结果进行流水线操作。这些操作称为 中间 操作,它们的功能是获取输入,处理它们并将输出返回到目标。collect() 方法是一个终端操作,通常在流水线操作结束时出现,以标记流的结尾。
2.5 原子性迭代 ( Automatic iterations ) : 与需要显式迭代的集合相比,流操作在内部对所提供的源元素进行迭代。
ALT+7先看一下Stream类的方法列表
大致常见的几种用法如下代码示例:
public class StreamTest1 {
public static void main(String[] args) {
/**
* 聚合的操作
* limit()限制流内元素的个数
*/
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
//map()方法
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
/**
* map()方法通过lambda表达式对数据做操作
* distinct()对流内数据去重
*/
List<Integer> squaresList = numbers.stream().map(i -> i*i).distinct().collect(Collectors.toList());
System.out.println(squaresList);
/**
* filter()过滤器
* filter()方法体内返回true 则过滤
*/
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
long count = strings.stream().filter(string -> string.isEmpty()).count();
System.out.println(count);
/**
* sorted() 方法
* 对数据进行由小及大的排序
*/
random.ints().limit(10).sorted().forEach(System.out::println);
/**
* stream()方法只能是串行的方案
* parallelStream()是需要并发处理的流的替代方案
*/
List<String> stringList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//get count of empty string
long count2 = stringList.parallelStream().filter(string -> string.isEmpty()).count();
System.out.println(count2);
/**
* 收集器 ( Collectors )
*
* Collectors 类提供了大量方法用于指示如何收集元素。
* 比如 Collectors.toList() 方法可以将流中的元素收集起来,并转换为列表
*
* 比如 Collectors.joining(",")将流中的数据按照一定规则收集起来
*/
List<String> strings1 = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings1.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("Filtered List: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);
/**
* 统计 ( Statistics )
*/
List<Integer> numbers2 = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
//前提是我们先要在流上调用 summaryStatistics() 方法返回统计信息概要,然后在调用相应的方法来获取具体的统计信息。
IntSummaryStatistics stats = numbers2.stream().mapToInt(x -> x).summaryStatistics();
//调用 getMax() 方法获取最大值
System.out.println("Highest number in List : " + stats.getMax());
//调用 getAverage() 方法获取平均值
System.out.println("Average of all numbers : " + stats.getAverage());
}
}
2.2 备注特殊用法
2.2.1 从集合中取出某个属性集合
Person p1 = new Person("zhangsan",false,19,60);
Person p2 = new Person("lisi",true,20,80);
Person p3 = new Person("wangmazi",false,28,70);
Person p4 = new Person("meiyoule",true,15,50);
Person p5 = new Person("evsd",true);
Person p6 = new Person("evsd",true);
List<Person> personList = Arrays.asList(p1,p2,p3,p4,p5,p6);
List<String> nameList = personList.stream().map(Person::getName).collect(Collectors.toList());