一、收集方法collect
收集到List、Set中比较简单,收集到Map中是重点,有点复杂,需要好好的理解。注意收集的Map中的数据键不能重复,否则会抛出异常。
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class StreamDemo10 {
public static void main(String[] args) {
/*
collect(Collector collector) 收集流中的数据,放到集合中(List Set Map)
*/
// 创建数组
ArrayList<String> list =new ArrayList<>();
// 添加元素
Collections.addAll(list,"张无忌-男-15","周芷若-女-14","赵敏-女-13","张强-男-20",
"张三丰-男-100","张翠山-男-40","张良-男-35","王二麻子-男-37","谢广坤-男-41");
//收集List集合当中
//需求:
//我要把所有的男性收集起来
List<String> newList = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());
// 收集到Set集合中
// 需求:
// 我要把所有的男性收集起来
Set<String> newList2 = list.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
Map<String, Integer> map = list.stream().filter(s -> "男".equals(s.split("-")[1]))
/*
* 要用map收集数据注意键不能重复,否则会抛出异常
*
* toMap :参数一表示键的生成规则
* 参数二表示值的生成规则
*
* 参数一:
* Function泛型一:表示流中每一个数据的类型
* 泛型二:表示Map集合中键的数据类型
* 方法apply形参:依次表示流里面的每一个数据
* 方法体:生成键的代码
* 返回值:已经生成的键
*
* 参数二:
* Function泛型一:表示流中每一个数据的类型
* 泛型二:表示Map集合中值的数据类型
*
*
* 方法apply形参:依次表示流里面的每一个数据
* 方法体:生成值的代码
* 返回值:已经生成的值
*
*
*/
.collect(Collectors.toMap(new Function<String, String>() {
@Override
public String apply(String s) {
return s.split("-")[0];
}
}, new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.valueOf(s.split("-")[2]);
}
}));
//System.out.println(map);
// 改成lambda表达式
Map<String, Integer> map2 = list.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.valueOf(s.split("-")[2])));
System.out.println(map2);
}
}
二、小结
1.Stream流的作用
结合了Lambda表达式,简化集合、数组的操作
2.Stream的使用步骤
●获取Stream流对象
●使用中间方法处理数据
●使用终结方法处理数据
3.如何获取Stream流对象
●单列集合:Collection中的默认方法stream
●双列集合:不能直接获取
●数组:Arrays工具类型中的静态方法stream
●一堆零散的数据:Stream接口中的静态方法of
4.常见方法
中间方法:filter, limit, skip, distinct, concat, map
终结方法:forEach, count, collect
三、练习
第一题 数据过滤
定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10过滤奇数,只留下偶数,并将结果保存起来
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class DataFilter {
public static void main(String[] args) {
/*
* 定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
* 过滤奇数,只留下偶数,并将结果保存起来
*/
// 创建集合
List<Integer> list = new ArrayList<>();
// 添加元素
Collections.addAll(list, 1,2,3,4,5,6,7,8,9,10);
// 过滤奇数
List<Integer> newList = list.stream().filter(i -> i % 2 != 1).collect(Collectors.toList());
System.out.println(newList);
}
}
第二题 数据操作
创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
“zhangsan,23”
“lisi,24”
“wangwu,25”
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
public class DataOpratorate {
public static void main(String[] args) {
/*
* 创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
* “zhangsan,23”
* “lisi,24”
* “wangwu,25”
* 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
*/
// 创建列表
ArrayList<String> list = new ArrayList<>();
// 添加元素
Collections.addAll(list, "zhangsan,23", "lisi,24", "wangwu,25", "zhubajie,1322", "sunwukong,800");
// 过滤:保留大于24岁的人
// 收集:姓名为键,年龄为值
Map<String, Integer> map = list.stream().filter(s -> Integer.valueOf(s.split(",")[1]) > 24).collect(Collectors.toMap(
s -> s.split(",")[0],
s -> Integer.valueOf(s.split(",")[1])
));
// 打印
System.out.println(map);
}
}
第三题 数据操作
现在有两个ArrayList集合,
第一个集合中:存储6名男演员的名字和年龄。
第二个集合中:存储6名女演员的名字和年龄。
姓名和年龄中间用逗号隔开。比如:张三,23
要求完成如下的操作:
1,男演员只要名字为3个字的前两人
2,女演员只要姓杨的,并且不要第一个
3,把过滤后的男演员姓名和女演员姓名合并到一起
4,将上一步的演员信息封装成Actor对象。
5,将所有的演员对象都保存到List集合中。
备注:演员类Actor,属性只有二个:name,age
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ActorStreamDemo {
public static void main(String[] args) {
/*
现在有两个ArrayList集合,
第一个集合中:存储6名男演员的名字和年龄。
第二个集合中:存储6名女演员的名字和年龄。
姓名和年龄中间用逗号隔开。比如:张三,23
要求完成如下的操作:
1,男演员只要名字为3个字的前两人
2,女演员只要姓杨的,并且不要第一个
3,把过滤后的男演员姓名和女演员姓名合并到一起
4,将上一步的演员信息封装成Actor对象。
5,将所有的演员对象都保存到List集合中。
备注:演员类Actor,属性只有二个:name,age
*/
// 男演员
ArrayList<String> actors = new ArrayList<>();
// 女演员
ArrayList<String> actress = new ArrayList<>();
// 添加元素
Collections.addAll(actors, "旺财一,25", "张德,23", "朱思渺,38", "刘行,72", "王美雄,54", "黄得壮,48");
Collections.addAll(actress, "杨二小,26", "武连连,33", "刘美,58", "程天天,21", "李红,38", "杨美美,36");
//1,男演员只要名字为3个字的前两人
List<String> actorsWith3digitsLimit2 = actors.stream().filter(s -> s.split(",")[0].length() == 3).limit(2).collect(Collectors.toList());
//System.out.println(actorsWith3digitsLimit2);
//2,女演员只要姓杨的,并且不要第一个
List<String> yangActress = actress.stream().filter(s -> s.startsWith("杨")).skip(1).collect(Collectors.toList());
//System.out.println(yangActress);
//3.合并
List<String> concatedList = Stream.concat(actorsWith3digitsLimit2.stream(), yangActress.stream()).collect(Collectors.toList());
//System.out.println(concatedList);
//4-1,将上一步的演员信息封装成Actor对象。
concatedList.stream().map(new Function<String, Actor>() {
@Override
public Actor apply(String s) {
String[] split = s.split(",");
return new Actor(split[0], Integer.valueOf(split[1]));
}
}).forEach(actor -> System.out.println(actor));
//4-2,lambda将上一步的演员信息封装成Actor对象。
concatedList.stream().map(s -> new Actor(s.split(",")[0], Integer.valueOf(s.split(",")[1])))
.forEach(actor -> System.out.println(actor));
//5,将所有的演员对象都保存到List集合中。
List<Actor> ActorObjList = concatedList.stream().map(s -> new Actor(s.split(",")[0], Integer.valueOf(s.split(",")[1])))
.collect(Collectors.toList());
System.out.println(ActorObjList);
}
}