Stream流
1、Stream流的基本使用
//Stream基本使用
public class StreamDemo1 {
public static void main(String[] args) {
/* //创建集合,存储多个元素
ArrayList<String> al = new ArrayList<String>();
al.add("上海市");
al.add("北京市");
al.add("上饶市");
al.add("北海市");
al.add("深圳市");
al.add("北戴河");
al.add("北下");
//筛选出以北开头的元素,存储到新的集合中
ArrayList<String> a2 = new ArrayList<String>();
for (String str : al) {
if (str.startsWith("北")) {
a2.add(str);
}
}
//System.out.println(a2);
//把以北开头的元素,长度为3的元素存储到新集合中
ArrayList<String> a3 = new ArrayList<String>();
for(String s:a2) {
if (s.length() == 3) {
a3.add(s);
}
}
//System.out.println(a3);
for(String ss: a3){
System.out.println(ss);
}
System.out.println("---------------------------");*/
ArrayList<String> al = new ArrayList<String>();
al.add("上海市");
al.add("北京市");
al.add("上饶市");
al.add("北海市");
al.add("深圳市");
al.add("北戴河");
al.add("北下");
//lambda表达式方式对上面代码改进
al.stream().filter(s->s.startsWith("北")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
//方法引用改进上一行代码
al.stream().filter(s->s.startsWith("北")).filter(s->s.length()==3).forEach(System.out::println);
}
}
2、Stream流的生成方式
常见的三种Stream流生成方式:
//常见的几种Stream流生成方式
public class StreamDemo2 {
public static void main(String[] args) {
//list直接生成流
List<String> list = new ArrayList<String>();
Stream<String> stream1 = list.stream();
//set直接生成流
Set<String> set = new HashSet<String>();
Stream<String> stream2 = set.stream();
//map集合只能间接生成流
Map<String,String> map = new HashMap<>();
Stream<String> keystream = map.keySet().stream();
Stream<String> valuestream = map.values().stream();
Stream<Map.Entry<String, String>> entrystream = map.entrySet().stream();
//数组生成流
String[] str = {"中国","北京","黑马"};
Stream<String> str1 = Stream.of(str);
//数组可变参数
Stream<String> streamname = Stream.of("浙江", "杭州", "西湖");
Stream<Integer> integerStream = Stream.of(12, 21, 34, 54);
}
}
3、Stream流的常见中间操作方式
public class StreamDemo3 {
public static void main(String[] args) {
//创建一个集合,存储多个元素
List<String> list = new ArrayList<>();
list.add("北京市");
list.add("南海市");
list.add("北海市");
list.add("北京");
list.add("北上广");
list.add("杭州市");
list.add("西安市");
list.add("深圳市");
//筛选出名字是北开头的
/*list.stream().filter((String s)->{
return s.startsWith("北");
}).forEach(System.out::println);*/
list.stream().filter(s->s.startsWith("北")).forEach(System.out::println);//优化上面的代码
System.out.println("----------");
//把长度为3的元素筛选出来
list.stream().filter(s->s.length()==3).forEach(System.out::println);
System.out.println("----------");
//筛选出名字是北开头的,并且长度为3的元素筛选出来
list.stream().filter(s->s.startsWith("北")).filter(s->s.length()==3).forEach(System.out::println);
}
}
//Stream的limit()、skip()两个方法
public class StreamDemo4 {
public static void main(String[] args) {
//创建一个集合,存储多个元素
List<String> list = new ArrayList<>();
list.add("北京市");
list.add("南海市");
list.add("北海市");
list.add("北京");
list.add("北上广");
list.add("杭州市");
list.add("西安市");
list.add("深圳市");
//取前3个元素在控制台输出
list.stream().limit(3).forEach(System.out::println);
System.out.println("---------");
//跳过前3个,把剩下的元素在控制台输出
list.stream().skip(3).forEach(System.out::println);
System.out.println("---------");
//跳过前3个元素,把剩下的元素中的前3个元素在控制台输出
list.stream().skip(3).limit(3).forEach(System.out::println);
}
}
//Stream的concat()、distinct()两个方法
public class StreamDemo5 {
public static void main(String[] args) {
//创建一个集合,存储多个元素
List<String> list = new ArrayList<>();
list.add("北京市");
list.add("南海市");
list.add("北海市");
list.add("北京");
list.add("北上广");
list.add("杭州市");
list.add("西安市");
list.add("深圳市");
//需求1:取前4个数据组成一个流
Stream<String> s1 = list.stream().limit(4);
//需求2:跳过前2个数据组成一个流
Stream<String> s2 = list.stream().skip(2);
//需求3:合并需求1、需求2组成一个流,在控制台输出
Stream.concat(s1,s2).forEach(System.out::println);
//需求4:合并需求1、需求2组成一个流,把合并流中重复的数据去除,在控制台输出
Stream.concat(s1,s2).distinct().forEach(System.out::println);
}
}
//Stream中的sorted方法
public class StreamDemo6 {
public static void main(String[] args) {
//创建一个集合,存储多个元素
List<String> list = new ArrayList<>();
list.add("zhangsan");
list.add("lisi");
list.add("zhangwuji");
list.add("wangxiaohu");
list.add("liuergou");
list.add("xuexiaoqi");
list.add("qianyisheng");
list.add("guokangxia");
//按照字符顺序在控制台输出
list.stream().sorted().forEach(System.out::println);
System.out.println("--------");
//按照字符串长度在控制台输出
list.stream().sorted((s1,s2)->{
int num = s1.length() - s2.length();
int num2 = num== 0 ?s1.compareTo(s2):num;
return num2;
}).forEach(System.out::println);
}
}
//通过maoToInt得到IntStream中的求和方法sum()
public class StreamDemo7 {
public static void main(String[] args) {
//创建一个集合,存储多个元素
List<String> list = new ArrayList<>();
list.add("10");
list.add("20");
list.add("30");
list.add("40");
list.add("50");
list.add("60");
list.add("70");
list.add("80");
//需求:将集合中的字符串转换为整数之后在控制台输出
//list.stream().map(s->Integer.parseInt(s)).forEach(System.out::println);
//list.stream().map(Integer::parseInt).forEach(System.out::println);//方法引用对上一句进行优化
//list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);//maoToInt方法对上一句优化
//int sunm()是IntStream中的求和方法
int result = list.stream().mapToInt(Integer::parseInt).sum();
System.out.println(result);
}
}
4、Stream流的常见终结操作方式
//Stream流的count()方法
public class StreamDemo8 {
public static void main(String[] args) {
//创建一个集合,存储多个元素
List<String> list = new ArrayList<>();
list.add("北京市");
list.add("南海市");
list.add("北海市");
list.add("北京");
list.add("北上广");
list.add("杭州市");
list.add("西安市");
list.add("深圳市");
//集合中的元素在控制台输出
//list.stream().forEach(System.out::println);
//统计集合中有几个以北开头的元素,在控制台输出
long count = list.stream().filter(s -> s.startsWith("北")).count();
System.out.println(count);
}
}
5、Stream流的练习
//Stream流小练习
public class StreamDemo9 {
public static void main(String[] args) {
//创建一个集合,存储男演员
ArrayList<String> list1 = new ArrayList<>();
list1.add("周润发");
list1.add("成龙");
list1.add("刘德华");
list1.add("吴京");
list1.add("周星驰");
list1.add("李连杰");
//创建一个集合,存储女演员
ArrayList<String> list2 = new ArrayList<>();
list2.add("林心如");
list2.add("张曼玉");
list2.add("林青霞");
list2.add("柳岩");
list2.add("林志玲");
list2.add("王祖贤");
/*//男演员只要名字为3个字的前三人
Stream<String> manStream = list1.stream().filter(s -> s.length() == 3).limit(3);
//女演员只要姓林的,并且不要第一个
Stream<String> menStream = list2.stream().filter(s -> s.startsWith("林")).skip(1);
//把过滤后的男、女演员合并到一起,存储到一个新的Stream流中
Stream<String> newStream = Stream.concat(manStream, menStream);
//把合并后的新Stream流作为构造方法的参数,创建演员对象,并且遍历该对象数据
//newStream.map(Actor::new).forEach(System.out::println);//Actor类中没有重写toString方法,所以这里拿到的是地址值
newStream.map(Actor::new).forEach(p-> System.out.println(p.getName()));*/
//对上一部分代码优化
Stream.concat(list1.stream().filter(s->s.length()==3).limit(3),
list2.stream().filter(s->s.startsWith("林")).skip(1)).map
(Actor::new).forEach(p-> System.out.println(p.getName()));
}
}
6、Stream流的收集操作
//Stream流的收集操作
public class StreamDemo10 {
public static void main(String[] args) {
//创建一个集合,存储女演员
ArrayList<String> list2 = new ArrayList<>();
list2.add("林心如");
list2.add("张曼玉");
list2.add("林青霞");
list2.add("柳岩");
list2.add("林志玲");
list2.add("王祖贤");
//需求1:得到名字为3个字的元素
Stream<String> listStream = list2.stream().filter(s -> s.length() == 3);
//需求2:把使用Stream流操作的数据收集到list集合中并遍历
//这就是对上一步流的操作后,还可以收集到集合中
List<String> names = listStream.collect(Collectors.toList());
for(String name: names){
System.out.println(name);
}
Set<Integer> set = new HashSet<Integer>();
set.add(10);
set.add(20);
set.add(30);
set.add(40);
set.add(50);
//需求2:得到大于25的流
Stream<Integer> setStream = set.stream().filter(age -> age > 25);
//需求4:把使用Stream流操作完毕的数据收集到Set集合中并遍历
Set<Integer> ages = setStream.collect(Collectors.toSet());
for(Integer age: ages){
System.out.println(age);
}
//定义一个字符串数组,每一个字符串数组由姓名和年龄组合而成
String[] str = {"林青霞,21","张曼玉,28","王祖贤,35","柳岩,42","林志玲,45"};
//需求5:得到字符中数组中年龄大于28的流
Stream<String> arrayStream = Stream.of(str).filter(s -> Integer.parseInt(s.split(",")[1])>28);
//需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作为键、年龄作为值
Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
Set<String> keySet = map.keySet();
for(String key: keySet){
Integer value = map.get(key);
System.out.println(key+","+value);
}
}
}