Day10 - 总结
一、Stream流的常见操作方法
1、Stream流的获取
1.1、单列集合:
- 格式:集合对象 .stream();
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
//简化前代码
Stream<String> stream = list.stream();
stream.forEach(s -> System.out.println(s));
//简化后代码
list.stream().forEach(s-> System.out.println(s));
1.2、双列集合:
- 双列集合不能直接获取Stream流 需通过 kaySet 或 entrySet来间接获取Stream流
-
kaySet格式:集合对象.keySet().stream(); //获取到所有的 键 对象
-
values格式:集合对象.values().stream(); //获取到所有的 值 对象
-
entrySet格式:集合对象.entrySet().stream(); //获取到所有的 键值对 对象
HashMap<String,Integer> map = new HashMap<>();
map.put("zhangsan",20);
map.put("lisi",22);
map.put("wangwu",24);
map.put("zhaoliu",26);
//keySat
//先获取到所有的键
//然后在把这个Set集合中的所有的键放到stream流中
map.keySet().stream().forEach(s-> System.out.println(s));
//values
//先获取到所有的值
//然后在把这个Set集合中的所有的值放到stream流中
map.values().stream().forEach(s-> System.out.println(s));
//entrySet
//先获取到所有的键值对对象
//然后在把这个set的集合中所有的键值对对象放到Stream流中
map.entrySet().stream().forEach(s-> System.out.println(s));
1.3、数组:
- 格式:Arrays.stream(数组名);
int[] arr = {1,2,3,4,5,6};
Arrays.stream(arr).forEach(s-> System.out.println(s));
1.4、同种数据类型的多个数据:
- 格式:Stream.of(数据1,数据2,数据3 …数据n);
Stream.of(1,2,3,4,5,6,7).forEach(s-> System.out.println(s));
2、中间操作方法
2.1、filter() 过滤方法
- Stream filter(Predicate predicate) : 用于对流中的数据进行过滤
- Predicate 接口中的方法
- boolean test(T t) : 对给定的参数进行判断,返回一个布尔值
ArrayList<String> list = new ArrayList<>();
list.add("孙悟空");
list.add("唐三藏");
list.add("猪八戒");
list.add("沙悟净");
list.add("谢广坤");
list.add("张良");
//filter方法获取流中的每一个数据。
//而test方法中的是,就是依次表示流中的每一个数据。
//我们只要 在test方法中对是进行判断就可以了。
//如果判断的结果为true, 则当前的数据留下
//如果判断的结果为false,则当前的数据就不要
// 方法一 使用匿名内部类方法实现 过滤
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
boolean result = s.startsWith("孙");
return result;
}
}).forEach(s -> System.out.println(s));
// 方法二 使用lambda 表达式
// 因为Predicate接口中只有一个抽象的方法test
// 所以我们可以使用lambda表达式来简化 代码
list.stream().filter(s -> {
boolean result = s.startsWith("孙");
return result;
}).forEach(s -> System.out.println(s));
// 再一次简化 lambda 表达式
list.stream().filter(s -> s.startsWith("孙")).forEach(s -> System.out.println(s));
2.2、limit() 截取方法
- Stream limit (long maxSize): 截取指定的参数个数的数据
ArrayList<String> list = new ArrayList<>();
list.add("孙悟空");
list.add("唐三藏");
list.add("猪八戒");
list.add("沙悟净");
//简化前代码:
Stream<String> stream = list.stream();
stream.forEach(s -> System.out.println(s));
//简化后代码:
list.stream().limit(2).forEach(s -> System.out.println(s));
// 结果:孙悟空
// 唐三藏
//注解:本方法截取就是 只保留前面的指定元素
2.3、skip() 跳过方法
- Stream skip (long n): 跳过指定参数个数的数据
ArrayList<String> list = new ArrayList<>();
list.add("孙悟空");
list.add("唐三藏");
list.add("猪八戒");
list.add("沙悟净");
//Stream<T> skip (long n): 跳过指定参数个数的数据
list.stream().skip(2).forEach(s -> System.out.println(s));
//结果:唐三藏
// 沙悟净
//注解: 与截取相反 本方法 是跳过前面的指定元素
2.4、conact() 合并方法
- static Stream concat (Stream a,Stream b): 合并a 和 b两个流为一个流
ArrayList<String> list1 = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
ArrayList<String> list2 = new ArrayList<>();
list2.add("张三丰夫人");
list2.add("张无忌夫人");
list2.add("张翠山夫人");
list2.add("王二麻子夫人");
list2.add("谢广坤夫人");
list2.add("张良夫人");
//简化前
Stream<String> stream1 = list1.stream();
Stream<String> stream2 = list2.stream();
Stream<String> stream3 = Stream.concat(stream1, stream2);
stream3.forEach(s -> System.out.println(s));
//简化后
Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));
2.5、distinct() 去重方法
- Stream distinct (): 去除流中重复的元素。 依赖(hashCode 和 equals方法)
ArrayList<String> list1 = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("王二麻子");
list.stream().distinct().forEach(s -> System.out.println(s));
/*结果:张三丰
张无忌
张翠山
王二麻子*/
3、终结操作方法
3.1、forEach() 打印方法
- void forEach(Consumer action) : 对此流的每一个元素执行操作
- Consumer接口中的方法 void accept(T t) : 对给定的参数执行此操作
ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("谢广坤");
list.add("张良");
list.add("张良");
//在forEach 方法的底层,会循环获取到每一个数据传递给accept方法
//s就依次表示了流中的每一个数据。
//所以,我们只要在accept方法中,写上处理业务逻辑就可以了。
list.stream().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
}
);
// lambda 表达式的简化格式
// 是因为Consumer 接口中,只有一个accept方法
list.stream().forEach((String s)->{
System.out.println(s);
} );
//lambda 表达式再一次进行简化
list.stream().forEach(s -> System.out.println(s));
3.2、count() 统计方法
- long count():返回此流中的元素中的个数
long count = list.stream().count();
System.out.println(count);
4、收集操作方法
4.1、toList()
- public static Collectors.toList() : 在底层会创建一个List集合,并把所有的数据添加到list集合中。
List<Integer> collect = list.stream().filter(number -> number % 2 == 0).collect(Collectors.toList());
System.out.println(collect);
//filter 负责过滤数据的
//collect 负责收集数据的, 获取流中剩余的数据,但是他不会负责创建容器,也不负责把数据添加到容器中。
4.2、toSet()
- public static Collectors.toSet() : 在底层会创建一个Set集合,并把所有的数据添加到Set集合中。**
Set<Integer> collect1 = list.stream().filter(number -> number % 2 == 0).collect(Collectors.toSet());
System.out.println(collect1);
//filter 负责过滤数据的
//collect 负责收集数据的, 获取流中剩余的数据,但是他不会负责创建容器,也不负责把数据添加到容器中。
4.3、toMap()
- public static Collectors.toMap(Function keyMapper,Function valueMapper): 把元素收集到Map集合中。
ArrayList<String> list = new ArrayList<>();
list.add("张三,23");
list.add("李四,26");
list.add("王五,27");
Map<String, Integer> map = list.stream().filter(
(String s) -> {
String[] split = s.split(",");
int age = Integer.parseInt(split[1]);
return age >= 24;
}
//collect 方法只能获取到流中剩余每一个数据
//在底层不能创建容器,也不能把数据添加到容器中
//Collectors.toMap 创建一个Map集合并将数据添加到集合当中
// s 依次表示流中的每一个数据
// 第一个 lambda表达式就是 如何获取到 Map中的 键
// 第二个 lambda表达式就是 如何获取 Map中的 值
).collect(Collectors.toMap(
(String s) -> {
return s.split(",")[0];
},
(String s) -> {
return Integer.parseInt(s.split(",")[1]);
}));
System.out.println(map);
// 简化 lambda 表达式 后
).collect(Collectors.toMap(
s -> s.split(",")[0],
s -> Integer.parseInt(s.split(",")[1])));
System.out.println(map);