Stream流 (Java Day25)

一,Stream流

  • 概述:是用来代替遍历容器行为,对容器中的数据进行处理的一种工具。stream不能承载任何数据,只对容器的数据进行维护处理。
  • ​ 举例:stream 流类似工厂的生产线 容器相当于产品 数据是在容器,每次变化变化的是数据,容器发生变化。【Stream相当于是流水线 他的方法属于一道道的工序 】
  • Stream类型数据的获取【把容器放到Stream(流水线)上】

  • Collection 的获取 stream 对象的方式:
  1. 集合对象.stream():  把集合对象转换为stream流对象。
  • Map的获取stream对象:不能直接获取Stream对象
  1. ​ 把双列集合转变成单列集合,采用单列集合转换 stream 流方式操作
  2. ​ 双列集合转换为单列集合的方式:keySet()、entrySet()、values()
  • 数组的获取stream对象
  1. ​ 采用 Stream 接口中的静态方法:Stream.of(数组对象)

代码示例


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;
import java.util.stream.Stream;
public class Demo_Stream01 {
public static void main(String[] args) {
    //list 单列集合
    ArrayList<Object> list = new ArrayList<>();
   //将list 集合放到流对象中去
    Stream<Object> list_stream = list.stream();
    list.add("春天");
    list.add("夏天");
    list.add("秋天");
    list.add("冬天");
    //数组
    int[] arr = {1,2,3,4,5,6};
    Stream<int []> arr_stream = Stream.of(arr);
    
    //map双列集合
    HashMap<Object, Object> map = new HashMap<>();
    Set<Object> set = map.keySet();//将双列集合变为单列集合
    Stream<Object> set_stream = set.stream();
    
    //终结方法
    //arr_stream.forEach((s)->{System.out.println(Arrays.toString(s));});   //[1, 2, 3, 4, 5, 6]
    //list_stream.forEach(System.out::println);  //春天 夏天 秋天 冬天 ---- 方法引用
    long len = arr_stream.count();
    System.out.println(len);  //数组看作是整体对象为1  输出为1,没有tostring方法无法深入到数组内部所有看作一个长度
    long len2 = list_stream.count();
    System.out.println(len2);  //4  4个字符串,四个内容
}
}
 
  • Stream中的常用方法

  • 常用方法:
  • 终结方法:就是stream调用该方法后返回的数据类型不是Stream对象的方法
  1. ​ foreach():打印 stream 中容器数据
  2. ​ count():获取 stream 中数据个数的
  • ​ 如何把生产线上处理好的数据拿下来存放到对应的容器中:
  1. ​ toArray():把 stream 处理后的数据取出到数组中
  2. ​ collect(Collector c):把 stream 中的数据取出放到集合中

代码示例:


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo_Stream01 {
public static void main(String[] args) {
    //首先使用stream流
    ArrayList<String > list = new ArrayList<>();
    list.add("春天");
    list.add("夏天");
    list.add("秋天");
    list.add("冬天");
    //将这些内容放到stream流里面
    Stream<String > stream = list.stream();
    
    //把stream的数据拿下来 放到对应的容器中
// Object[] arr = stream.toArray();
    //数组是不能直接强转的,只能遍历 对里面的数据一个一个的单独强转
// System.out.println(Arrays.toString(arr));  //[春天, 夏天, 秋天, 冬天]
    //参数需要的是collection的对象 如何获取对象? 使用一个工具类
    
// List<String >list2 = stream.collect(Collectors.toList());  //把stream中的数据添加到一个list集合中
// System.out.println(list2);  //[春天, 夏天, 秋天, 冬天]
    
    Set<String >set = stream.collect(Collectors.toSet());  ////把stream中的数据添加到一个set集合中
    System.out.println(set);  //[夏天, 秋天, 冬天, 春天]
}
}
延迟方法:就是stream调用该方法后返回的数据类型还是stream对象的方法
  1. ​ filter(Predicate p):过滤容器数据的
  2. ​ limit(long num):截取 stream 操作数据的前 num 个元素
  3. skip(long num):跳过开头的前 num 个元素
  4. map(Function f):把 stream 中的数据转换成其他数据
  5. ​ concat(Stream stream):拼接两个 stream 成为一个 stream
  • 在 stream 中除了终结方法就是延迟方法。
  • 总结:stream 流对象不能二次使用,用完就关闭了【用完就改变了】。

代码示例


import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo_Stream02 {
    public static void main(String[] args) {
        // 首先使用stream流
        ArrayList<String> list = new ArrayList<>();
        list.add("春天");
        list.add("夏天");
        list.add("秋天");
        list.add("冬天");
        list.add("春分分");
        list.add("夏至至");
        list.add("中秋秋");
        list.add("冬至至");
        list.add("端午");
        list.add("新年");
        Stream<String> stream = list.stream();
        // 延迟方法
        // (s)->{return s.length()==2;}传递一个筛选逻辑
        Stream<String> ft = stream.filter((s) -> {return s.length() == 2;});
//        ft.forEach(System.out::println);//调用foreach 方法打印内部的内容,字符串为2个字的全部筛选出来了6个

        // 获取前4个字符串
        Stream<String> lm = ft.limit(4);
        // System.out.println(lm); //java.util.stream.SliceOps$1@3b9a45b3 获取的是流的对象的地址值
        // stream流里面没有承载数据的能力只有处理数据的能力,流里面不存放任何东西
        // lm.forEach(System.out::println); //春天 夏天 秋天 冬天

        Stream<String> sk = lm.skip(1); // 跳过第一个字符串
        // sk.forEach(System.out::println); //夏天 秋天 冬天

        /*
         * Stream<ArrayList>map_Stream = sk.map((s)->{
ArrayList list1= newArrayList<>();
list1.add(s);
return list1;}); * map_Stream.forEach(System.out::println); //得到3个集合[夏天] [秋天] * [冬天],把string类型的变成了list类型的了
*/ // 流不能二次调用,一个流只能用一次 // 创建新的流 Stream<String> stream1 = list.stream(); // 拼接两个新流stream1和sk流 Stream<String> concat_Stream = Stream.concat(stream1, sk); concat_Stream.forEach(System.out::println); // 打印stream1 和sk 流里面的所有的内容 } }
练习
  • 有两个字符串数组,分别存储队伍中的多个成员姓名,使用Stream方式,进行以下操作:
  1. 第一个队伍只要名字为3个字的成员姓名【filter】
  2. 第一个队伍只要筛选之后的前三个人【limit】
  3. 第二个队伍只要姓张的【filter】
  4. 第二个队伍筛选之后不要前两个人【skip】
  5. 将两个队伍合并成一个队伍【concat】
  6. 合并之后的队伍中的所有人名字变为Person(自定义类型)对象,【map 自定义Person类】
  7. 将person对象存储到一个List集合中【collect】
  • 队伍1:宫本武藏、宋公明、苏有朋、石头人、时传祥、李耳、庄子、洪七公
  • 队伍2:帕瓦罗蒂、张三疯、赵薇薇、张自忠、孛儿只斤铁木真、张天爱、张翠花

代码示例

//定义一个Person类
public class Person {
        private String name;
public Person(String name) { super(); this.name = name; } public Person() { super(); // TODO Auto-generated constructor stub } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person [name=" + name + "]"; } } // 定义一个测试类 import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class Stream_Test { public static void main(String[] args) { String[] arr1 = "宫本武藏,宋公明,苏有朋,石头人,时传祥,李耳,庄子,洪七公".split(","); String[] arr2 = "帕瓦罗蒂,张三疯,赵薇薇,张自忠,孛儿只斤铁木真,张天爱,张翠花".split(","); //将字符串存入stream流中 Stream<String> stream1 = Stream.of(arr1); Stream<String> stream2 = Stream.of(arr2); //1、第一个队伍只要名字为3个字的成员姓名【filter】 //2、第一个队伍只要筛选之后的前三个人【limit】 Stream<String > limit1 = stream1.filter((s)->{return s.length() == 3;}).limit(3); //3、第二个队伍只要姓张的【filter】 //4、第二个队伍筛选之后不要前两个人【skip】 Stream<String> skip1= stream2.filter((s)->{return s.startsWith("");}).skip(2); //5、将两个队伍合并成一个队伍【concat】 Stream<String> concat = Stream.concat(limit1,skip1); //6、合并之后的队伍中的所有人名字变为Person(自定义类型)对象,【map 自定义Person类】 //Stream<Person> map =concat.map((s)->{return new Person(s);}); //把s封装到person里面 Stream<Person> map1 = concat.map(Person :: new); //简写--构造方法 类名::new //7、将person对象存储到一个List 集合中【collect】 List<Person> list = map1.collect(Collectors.toList()); System.out.println(list); //结果:[Person [name=宋公明], Person [name=苏有朋], Person [name=石头人], Person [name=张天爱], Person [name=张翠花]] } }
原文地址:https://www.cnblogs.com/nastu/p/12583121.html