【Java学习|黑马笔记|Day18】Stream流|获取、中间方法、终结方法、收集方法及其练习

发布于:2025-07-21 ⋅ 阅读:(19) ⋅ 点赞:(0)

文章目录

    • 【DAY18】
      • 不可变集合
      • 一.Stream流
        • 1.1)获取Stream流
        • 1.2)中间方法
        • 1.3)终结方法
        • 1.4)收集方法collect
        • 2)练习
          • 2.1数据过滤
          • 2.2字符串过滤并收集
          • 2.3自定义对象并过滤

【DAY18】

不可变集合

  • 如果某个数据不能被修改,把它拷贝到不可变集合中
  • 当集合对象不被可信的库调用时不可变形式是安全的

创建不可变集合的书写格式

方法名称 说明
static list of(E…elements) 创建一个具有指定元素的List集合对象
static Setof(E…elements) 创建一个具有指定元素的Set集合对象
static<K,V> Map<K,V> of(E…elements) 创建一个具有指定元素的Map集合对象
List<String> list = List.of("a","b","c","d");
//参数要保持唯一性
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println(list.get(3));
for (String s : list) {
    System.out.println(s);
}
//细节:键不能重复,参数有上限,最多只能传递10个键值对
Map<String,String> map = Map.of("a","b","c","d","e","f");
Set<String> keys = map.keySet();
for (String key : keys) {
    System.out.println(key + "=" + map.get(key));
}
//创建Map的不可变集合,键值对的数量超过10个
//1.创建一个普通的Map集合
HashMap<String, String> hm = new HashMap<>();
hm.put("a","1");
hm.put("b","2");
hm.put("c","3");
hm.put("d","4");
hm.put("e","5");
hm.put("f","6");
hm.put("g","7");
hm.put("h","8");
hm.put("i","9");
//2.利用上面数据获取一个不可变的集合
//获取到所有的键值对对象(Entry对象)
Set<Map.Entry<String, String>> entries = hm.entrySet();
//把entries变成一个数组
Map.Entry[] arr1 = new Map.Entry[0];
//toArray方法在底层会比较集合的长度跟数组的长度两者的大小
//如果集合的长度 > 数组的长度 :数据在数组中放不下,此时会根据实际数据的个数,重新创建数组
//如果集合的长度 <= 数组的长度:数据在数组中放的下,此时不会创建新的数组,而是直接用

//简化
Map<String,String> map = Map.copyOf(hm);

在这里插入图片描述

一.Stream流

可理解为把一堆数据放到一个流水线上

作用:结合Lambda表达式,简化集合、数组的操作

1.1)获取Stream流

Stream流的使用步骤

  1. 先得到一条Stream流,并把数据放上去

    在这里插入图片描述

  2. 使用中间方法进行操作

  3. 使用终结方法进行操作

//单列集合获取Stream流
ArrayList<String> list = new ArrayList();
Collections.addAll(list,"a","b","c","d","e","f","g");
/*Stream<String> stream1 = list.stream();
stream1.forEach(new Consumer<String>() {
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
});*/
list.stream().forEach(s -> System.out.println(s));
//双列集合获取Stream流
HashMap<String, Integer> hm = new HashMap<>();
hm.put("a",1);
hm.put("b",2);
hm.put("c",3);
hm.put("d",4);
//第一种 键
hm.keySet().stream().forEach(s -> System.out.println(s));
//第二种 键值对
hm.entrySet().stream().forEach(s -> System.out.println(s));
//数组的Stream流
int[] arr = {1,2,3,4,5,6};
Arrays.stream(arr).forEach(s -> System.out.println(s));
String[] arr2 = {"a","b","c","d","e","f","g"};
Arrays.stream(arr2).forEach(s -> System.out.println(s));
//一堆零散数据
Stream.of(1,2,3,4,5,6,7,8,9).forEach(s -> System.out.println(s));
Stream.of("aa","bb","cc","dd").forEach(s -> System.out.println(s));
1.2)中间方法

在这里插入图片描述

filter

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"a","abc","ca","dc","ae","fs","gs");
//filter 过滤 留下以a开头的
 /*list.stream().filter(new Predicate<String>() {
     @Override
     public boolean test(String s) {
         //如果返回true 表示当前的要留下 反之不要
         return s.startsWith("a");
     }
 }).forEach(s -> System.out.println(s));*/

 //简化
 //list.stream().filter(s -> s.startsWith("a")).forEach(s -> System.out.println(s));
 //筛选a开头且长度为三的
 Stream<String> stream1 = list.stream().filter(s ->s.startsWith("a"));
 Stream<String> stream2 = stream1.filter(s -> s.length() == 3);
 stream2.forEach(s -> System.out.println(s));

 //化简
 list.stream()
         .filter(s -> s.startsWith("a"))
         .filter(s -> s.length() == 3)
         .forEach(s -> System.out.println(s));

limit 和 skip

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "a", "abc", "ca", "dc", "ae", "fs", "gs");

//limit 获取前几个元素
list.stream().limit(3)
        .forEach(s -> System.out.println(s));

//skip 跳过前几个元素
list.stream().skip(3)
        .forEach(s -> System.out.println(s));

distinct

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "a","a","abc", "abc", "ca", "dc", "ae", "fs", "gs");
//去重 依赖hashCode和equals
list.stream().distinct().forEach(s ->System.out.println(s));

concat

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "a","a","abc", "abc", "ca", "dc", "ae", "fs", "gs");
ArrayList<String> list2 = new  ArrayList<>();
Collections.addAll(list2, "a","a","abc", "abc", "ca", "dc", "ae", "fs", "gs");
Stream.concat(list.stream(), list2.stream()).forEach(s -> System.out.println(s));

map

ArrayList<String> list = new ArrayList<>();
//要求:只要数字
Collections.addAll(list, "a-11","a-12","abc-23", "abc-3", "ca-3", "dc-34", "ae-45", "fs-87", "gs-49");

//String 转 Integer
list.stream().map(new Function<String, Integer>() {
    //第一个类型 流中原本的数据
    //第二个类型 要转变之后的类型
    //apply的形参 依次表示流里面每一个数据
    //返回值 表示转换之后的数据
    @Override
    public Integer apply(String s) {
        String[] arr = s.split("-");
        String ageString = arr[1];//获取后面部分
        int age = Integer.parseInt(ageString);//转成Integer
        return age;
    }
}).forEach(s -> System.out.print(s + " "));
System.out.println();

//简化
list.stream()
        .map(s -> Integer.parseInt(s.split("-")[1]))
        .forEach(s -> System.out.print(s + " "));
1.3)终结方法

在这里插入图片描述

forEach

ArrayList<String> list = new ArrayList();
Collections.addAll(list,"a","b","c","d","e","f","g");
//遍历
//Consumer的泛型:表示流中数据的类型
//accept方法的形参:依次表示流里面是每一个数据
list.stream().forEach(new Consumer<>() {
    @Override
    public void accept(String s){
        System.out.println(s);
    }
});

list.stream().forEach(s -> System.out.println(s));

count

ArrayList<String> list = new ArrayList();
Collections.addAll(list,"a","b","c","d","e","f","g");
//统计 long类型
long count = list.stream().count();
System.out.println(count);//7

toArray

ArrayList<String> list = new ArrayList();
Collections.addAll(list,"a","b","c","d","e","f","g");
//toArray 收集流中数据并放到数组中
Object[] arr1 = list.stream().toArray();
System.out.println(Arrays.toString(arr1));//[a, b, c, d, e, f, g]

//IntFunction的泛型:具体类型的数组
//apply的形参:流中数据的个数,要跟数组的长度保持一致
//apply的返回值:具体类型的数组

//toArray方法参数的作用:负责创建一个指定类型的数组
//toArray方法的底层:依次得到流里面的每一个数据,并把数据放到数组里
//toArray方法的返回值:是一个载着流里面所有数据的数组
String[] arr = list.stream().toArray(new IntFunction<String[]>() {
    @Override
    public String[] apply(int value) {
        return new String[value];
    }
});
System.out.println(Arrays.toString(arr));

//化简
String[] arr2 = list.stream().toArray(value ->new String[value]);
System.out.println(Arrays.toString(arr2));
1.4)收集方法collect
//需求:收集所有的女性

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"z-女-11", "a-男-12","f-女-15","e-男-43", "e-男-11","w-女-92","o-男-11");

//收集到List中
List<String> newList = list.stream()
        .filter(s ->"女".equals(s.split("-")[1]))
        .collect(Collectors.toList());
System.out.println(newList);

//收集到Set中 可以自动去重
Set<String> newSet = list.stream()
        .filter(s ->"女".equals(s.split("-")[1]))
        .collect(Collectors.toSet());
System.out.println(newSet);

//收集到Map中
//键不能重复
Map<String,Integer> map = list.stream()
                .filter(s ->"女".equals(s.split("-")[1]))
                //toMap:参数一表示键的生成规则 
                //       参数二表示值的生成规则
                //参数一: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.parseInt(s.split("-")[2]);
                                }
                        }));

        System.out.println(map);



//化简
        Map<String,Integer> map2 = list.stream()
                .filter(s ->"女".equals(s.split("-")[1]))
                .collect(Collectors.toMap(
                        s -> s.split("-")[0],
                        s -> Integer.parseInt(s.split("-")[2])));
        System.out.println(map2);
2)练习
2.1数据过滤

定义一个集合,并添加整数1,2,3,4,5,6,7,8,9,10,过滤奇数只留下偶数并将结果保留起来

//练习一:
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);
//过滤奇数
List<Integer> newList = list.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());

System.out.println(newList);
2.2字符串过滤并收集

创建一个ArrayList集合,添加以下字符串,保留年龄大于24的人 并把结果收集到集合中

//练习二:
ArrayList<String> list = new ArrayList();
Collections.addAll(list,"zs,23","ls,24","ww,25");
Map<String,Integer> mp = list.stream()
        .filter(s ->Integer.parseInt(s.split(",")[1]) >= 24)
        .collect(Collectors.toMap(
                s -> s.split(",")[0],
                s -> Integer.parseInt(s.split(",")[1])));

System.out.println(mp);
2.3自定义对象并过滤

现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

  • 男演员只要名字为3个字的前三人
  • 女演员只要姓林的,并且不要第一个
  • 把过滤后的男演员姓名和女演员姓名合并到一起
  • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法

ArrayList<String> manList = new ArrayList<>();
ArrayList<String> womanList = new ArrayList<>();

Collections.addAll(manList, "aaa,24","bb,23","c,26","ddd,20","ee,30","fff,18");
Collections.addAll(womanList,"yq,23","ywwww,13","r,34","ttt,26","yp,25","oo,28");

Stream<String> stream1 = manList.stream()
        .filter(s -> s.split(",")[0].length() == 3)
        .limit(2);

Stream<String> stream2 = womanList.stream()
        .filter(s -> s.split(",")[0].startsWith("y"))
        .skip(1);

//合并 转String-> Actor对象
/*Stream.concat(stream1,stream2).map(new Function<String, Actor>() {
    @Override
    public Actor apply(String s) {
        String name = s.split(",")[0];
        int age = Integer.parseInt(s.split(",")[1]);
        return new Actor(name,age);
    }

}).forEach(s -> System.out.println(s));*/

//化简
 List<Actor> list  = Stream.concat(stream1,stream2)
         .map(s -> new Actor(s.split(",")[0],Integer.parseInt(s.split(",")[1])))
         .collect(Collectors.toList());
 System.out.println(list);

网站公告

今日签到

点亮在社区的每一天
去签到