lambda学习笔记
Lambda的常见函数式接口
自定义的符合函数式接口加入@FunctionInterface注解为该类添加合法性校验
以下的函数式内建接口都是java.util.function包提供的API,都是通过lambda实现的传入某对象 进行一定的业务处理后(业务处理需要自己写)返回某种数据类型 或不返回。
调用 | 方法类 | 方法描述 |
---|---|---|
test(T) | Predicate | 接受参数对象T,返回boolean类型结果 |
accep(T) | Comsumer | 接受参数对象T,不返回任何结果 |
apply(T) | Function | 接受T对象,返回R对象 |
get() | Supplier | 不接收任何参数,提供T的创建工厂 |
常见的 应用广泛的
调用 | 方法类 | 方法描述 |
---|---|---|
apply(T) | UnaryOperator | 接收T,返回T。(继承了Function,调父类) |
apply(T) | BinaryOperator | 接收两个T,返回一个T。(也继承了Function) |
小笔记
lambda基本语法:
类名<T> 变量名 = (...参数可无) -> {处理的业务代码}
如果箭头后只有一行代码可省略大括号,也可不用写return。
lambda表达式类型检查:
lambda会自动推到类型进行相关的匹配。
new Thread(() -> {
实现业务代码
});
会自动推到出括号内 是 new Runable()的实现。
lamda中方法重载的情况 JVM会找不到具体的对应关系。应为重载参数不一样,有多个对应关系JVM分不清具体是哪一个,所以会直接报错。此时不要使用lambda,直接用匿名内部类来实现。
lambda的方法引用
- 匿名内部类方法实现List排序:
List<Integer> collections = new ArrayList<Integer>();
coolection.add(1);
coolection.add(5);
coolection.add(8);
coolection.add(10);
collections.sort(collections,new Compareto<Integer> (){
@Override
public itn compare(Integer i1, Integer i2){
return i1-i2;
}
});
- lambda 实现List排序
List<Integer> collections = new ArrayList<Integer>();
collections.add(1);
collections.add(5);
collections.add(8);
collections.add(10);
collections.sort(collections,(i1 , i2) -> i1-i2);
- 通过封装对象内的静态方法
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person{
//姓名
private String name;
//年龄
private Integer age;
pubilc static int sortPerson(Person p1 , Person p2){
return p1.getAge()-p2.getAge();
}
}
List<Person> collections = new ArrayList<Person>();
collections.add(new Person("张三",18));
collections.add(new Person("李四",20));
collections.sort(collections,Person::sortPerson);
- 通过实例方法引用(没有静态方法)
与上面的静态方法一样,只不过需要在Person::sortPerson之前先new出Person的对象用对
象去调用里面的方法。
Stream流处理获取流对象
- 通过Stream的形式过滤长度大于等于5的数据
List <String> accounts = new ArrayList<String>();
accounts.add("123");
accounts.add("456");
accounts.add("123456");
accounts.add("456789");
List<String> s = accounts.stream().filter(s -> s.length >= 5)
.collect(Collectors.toList());
获取Stream对象的几种方法
- 从集合或数组中获取
Collection.Stream()
Colledction.parallelStream() //支持并发处理的流对象
Arrays.Stream(T[] t)
map.entrySet().Stream() //map集合获取流数据用entrySet()获取。
2.通过BufferReader 获取流对象
BufferReader.lines() -> Stream()
- 静态工厂获取流对象
java.util.stream.IntStream.range()
java.nio.file.Files.walk()
- 等等等等
Stream流处理中间操作API
中间操作可分为
无状态:无状态是指不受前面中间操作的影响,用的还是操作的元数据。
常用的无状态API: map()/filter()/parallel()/sequential()
有状态:有状态是指受前面的操作影响,用的不是原来的数据而是之前中间操作完的数据。
常用的有状态API: distinct()/sorted()/limit()/skip()
无状态API例子
map() 进行处理拼接等操作
Collection.Stream().map(x -> "梁山好汉"+x).collect(Collectors.toList());
//将集合的每一项的前面都拼接了一个字符串 “梁山好汉”
filter() 过滤操作
Collection.Stream().filter(x -> s.length()>5).collect(Collectors.toList()));
peek() 迭代数据,完成单个数据的处理
Collection.Stream().peek(x -> System.out.println("peek1: " + x))
.peek(x -> System.out.println("peek2: "+ x))
.collect(Collectors.toList()));
有状态API例子
skip() 跳过一部分数据,不做相关的处理操作::::有状态
Collection.Stream().skip(3).foreach(System.out::println);
不会输出前3条的数据
limit() 限制数据的处理量::::有状态
Collection.Stream().skip(3).limit(5).foreach(System.out::println);
会跳过前3条从第4条进行输出,从第4条往后输出5条数据。
distinct() 剔除重复的数据
sorted() 排序
max() 最大值
collection.Stream().max(Integer::compare);
min() 最小值 (x,y) -> y-x
reduce() 合并处理数据
Stream流处理终结操作
注意: Stream对象当使用了终结操作之后里面就没数据了,啥也不是!!!
终结操作分为
非短路操作:处理完全部的数据,数据才会有变化。
常见非短路操作:forEach()/forEachOrdered()/toArray()/reduce()/collect()/ min()/max()/count()/iterator()
短路操作:处理时满足了一定的条件,数据就会发生变化
常见短路操作:anyMatch()/allMatch()/noneMatch()/findFirst()/findAny() //等等等,,,无限大的数据返回一个有限的数据时使用。
Stream对象处理完数据转化会相应对象的API
---转化为数组
Object[] o = stream.toArry(); //转为数组
String[] s = stream.toArray(Strng[]::new); //转化为指定的类型数据。
---转化为字符串
String s = stream.Collect(Collectors.joining()).toString();
---转化为列表
List<String> l = (List<String>)stream.Collect(Collectors.toList);
---转化为集合
Set s = stream.Collect(Collectors.toSet());
---转化为Map
Map<String , String> m = stream.Collect(Collectors.toMap(x -> x,y -> y));
小笔记
-
stream处理
-
paralleStream处理
-
for处理
-
foreach处理
-
iterator处理
在以上这几种处理数据方式中如果处理的是基本类型数据的话可以使用迭代的方式去操作。如果是对象的操作可以通过并行stream(paralleStream)的方式去进行操作会更快,但是要确保线程安全。