lambda表达式
- 标准格式:
- 组成
- 一些参数
- 一个箭头
- 一段代码
- 格式:(参数列表)->{重写方法的代码};
- 解释说明格式:
():接口中抽象方法的参数列表,没有参数就空着,多个参数逗号分隔
->:将参数传递给方法体 {}
- 组成
函数式接口
位于 java.util.function 包中,下面为最简单的几个接口使用示例
Supplier接口(其它接口看文档)
- 接口仅包含一个午餐的方法:T get()。用于获取一个泛型参数指定类型的对象数据,由于这是一个函数式接口,也就意味着对应的Lambda表达式需要"对外提供"一个符合泛型类型的对象数据
@Test public void test2(){ // Supplier<T> 接口称为生产型接口,指定接口的泛型是什么类型,那么接口中的get 方法就会产生什么类型的数据 System.out.println(getString(() -> "a")); } public String getString(Supplier<String> sup){ return sup.get(); }
Stream流(重点)
stream流属于管道流,只能被消费(使用)一次
第一个Stream流调用完方法后,数据就会流到下一个stream上,而这时第一个Stream 流已经使用完毕,就会关闭
案例引入,数组遍历
@Test
public void test3(){
List<String> list = new ArrayList<>();
list.add("aa");
list.add("ab");
list.add("bc");
list.add("bb");
list.add("cc");
list.add("cb");
// 过滤字符串,a 开头的存储到新集合
List<String> listA = new ArrayList<>();
for (String s : list){
if(s.startsWith("a"))
listA.add(s);
}
// 过滤字符串,b 开头的存储到新集合
List<String> listB = new ArrayList<>();
for (String s : list){
if(s.startsWith("b"))
listB.add(s);
}
//遍历 ListB
for (String s : listB) {
System.out.println(s);
}
}
- 循环遍历的弊端
java8的Lambda 让我们可以更加专注于做什么,而不是怎么做 - for 循环的语法就是 怎么做
- for 循环的循环体才是 做什么
为什么使用循环?因为要进行遍历。遍历是指每一个元素逐一进行处理,而不是从第一个到最后一个顺序处理的循环,前者是目的,后者是方式 - lombda方式
List<String> list = new ArrayList<>();
list.add("aa");
list.add("ab");
list.add("bc");
list.add("bb");
list.add("cc");
list.add("cb");
list.stream()
.filter(s->s.startsWith("a"))
.forEach(s-> System.out.println(s));
常用方法
1. 常用方法:forEach遍历
@Test
public void test5(){
//获取流
Stream<Integer> stream = Stream.of(1, 23, 4, 5, 6, 7, 89, 10);
//方式1
stream.forEach(num-> System.out.println(num));
//方式2
stream.forEach(System.out::println);
}
2. 常用方法:filter过滤
@Test
public void test6(){
//创建一个 Stream 流
Stream<String> stream = Stream.of("张三", "李四","张无忌", "王五", "赵六");
// 过滤流中元素,只要姓 张 的人
Stream<String> stream1 = stream.filter((name) -> name.startsWith("张"));
//遍历
stream1.forEach(System.out::println);
}
3. 常用方法:map 映射
将流中的元素映射到另一个流中,可 使用 map方法
@Test
public void test7(){
// 获取流
Stream<String> stream = Stream.of("1", "2", "3", "4", "5");
// 使用 map 方法将字符串类型的整数,转换(映射)为Integer类型的整数
Stream<Integer> stream1 = stream.map((s) -> {
return Integer.parseInt(s);
});// 也可以简写为: stream.map(s-> Integer.parseInt(s));
stream1.forEach(System.out::println);
}
4. 常用方法:count 统计个数
正如旧集合 Collection 当中的 size 方法一样,流提供 count 方法来数一数其中的元素个数
long count(); // 返回 long值
@Test
public void test8(){
// 获取流
Stream<String> stream = Stream.of("1", "2", "3", "4", "5");
System.out.println(stream.count());
}
5 常用方法:limit 取用前几个
limit 方法可以对流进行截取,只取用前 n 个,该方法为延迟方法,只是对流中元素进行截取,返回的是一个新的流,所以可以继续调用流中的其它方法
Stream limit(long size);
@Test
public void test9(){
// 获取流
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7);
// 使用 limit 方法对流中的元素进行截取,只要前 3 个元素
Stream<Integer> stream1 = stream.limit(3);
stream1.forEach(System.out::println);
}
6. 常用方法:skip 跳过前几个
Stream skip(long n);
@Test
public void test10(){
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7);
Stream<Integer> stream1 = stream.skip(2);
stream1.forEach(System.out::println);
}
7. 常用方法:concat 组合
static Stream concat(Stream<? extends T> a,Stream<? extends T> b,)
@Test
public void test11(){
Stream<Integer> stream = Stream.of(1, 2, 3);
Stream<Integer> stream1 = Stream.of(4, 5, 6);
Stream<Integer> stream2 = Stream.concat(stream, stream1);
stream2.forEach(System.out::println);
}
- 常用方法:distinct 去重
@Test public void test12(){ Stream<Integer> stream = Stream.of(1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7); stream.distinct().forEach(System.out::println);//1,2,3,4,5,6,7 }
11. 常用方法:排序
// 升序
resultList = resultList.stream().sorted(Comparator.comparing(User::getAge))
.collect(Collectors.toList());
// 降序
resultList = resultList.stream().sorted(Comparator.comparing(User::getAge)
.reversed())
.collect(Collectors.toList());
1. 获取用户集合中的id
List<String> idList = userList.stream().map(User::getId).collect(Collectors.toList());