Stream流特点:

属于管道流,只能被使用一次
image.png

原:

    public static void main(String[] args) {
        List<String> lisy = new ArrayList<>();
        lisy.add("zwqs");
        lisy.add("zqcl");
        lisy.add("qqqw");
        lisy.add("ccw");
        lisy.add("qcza");
        lisy.add("zcz");

        List<String> listA = new ArrayList<>();
        for (String s : lisy) {
            if (s.startsWith("z")) {
                if (s.length() == 4) {
                    listA.add(s);
                }
            }
        }
        System.out.println(listA);
    }

使用Stream流后

    public static void main(String[] args) {
        List<String> lisy = new ArrayList<>();
        lisy.add("zwqs");
        lisy.add("zqcl");
        lisy.add("qqqw");
        lisy.add("ccw");
        lisy.add("qcza");
        lisy.add("zcz");

        lisy.stream()
                .filter(name -> name.startsWith("z"))
                .filter(name -> name.length() == 4)
                .forEach(name -> System.out.println(name));
    }

Stream流式思想

Stream(流)是一个来自数据源的元素队列

  • 元素是特定类型的对象,行成一个队列,java中Stream并不存储元素
  • 数据源流的来源,可以是集合、数组等
  • Pipelining:中间操作都会返回流对象本身,可以对操作进行优化(延迟执行、短路等)
  • 内部迭代:(外部迭代:先有集合,再通过迭代器和增强for在集合外部进行迭代),流可以直接调用遍历方法

使用流的步骤:

  1. 获取一个数据源
  2. 数据转换
  3. 执行操作得到想要的结果

获取流

java.util.stream.Stream<T>(并不是函数式接口)

  1. 所有Collection集合都可以通过stream默认方法获取流
  2. Stream接口的静态方法of获取对应的流

default Stream<E> stream()

必须是一个单列集合,Map集合必须先准换成其他集合

    public static void main(String[] args) {
        List<String> lisy = new ArrayList<>();
        lisy.add("zwqs");
        lisy.add("zqwq");
        lisy.add("qqqw");
        lisy.add("ccw");
        lisy.add("qcza");
        lisy.add("zcz");

        Stream<String> stream1 = lisy.stream();

        //Set集合使用Stream
        Set<String> set = new HashSet<>();
        Stream<String> stream2 = set.stream();

        //Map集合使用Stream,间接使用
        Map<String, String> map = new HashMap<>();
        //获取键,存储到Set集合中
        Set<String> ketSet = map.keySet();
        Stream<String> stream3 = ketSet.stream();
        //获取值,存储到Collection集合
        Collection<String> values = map.values();
        Stream<String> stream4 = values.stream();
        //获取键值对
        Set<Map.Entry<String, String>> entries = map.entrySet();
        Stream<Map.Entry<String, String>> stream5 = entries.stream();
    }

static <T> Stream<T> of (T... values)

    public static void main(String[] args) {
        //数组转换为Stream流
        Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5);
        //可变参数可以传递数组
        Integer[] arr = {1, 2, 3, 4, 5};
        Stream<Integer> arr1 = Stream.of(arr);
        String[] arr2 = {"a", "b", "c"};
        Stream<String> arr21 = Stream.of(arr2);
    }

常用方法:

  • 延迟方法:返回值类型依然是Stream接口自身类型的方法,支持链式调用(除终结方法外,其余均为延迟方法)
  • 终结方法:返回值类型不是Stream接口自身类型的方法,不支持链式调用

终结方法

forEach —— 逐一处理

void foeEach(Consumer<? super T> action);
遍历之后不能继续调用Stream流中其他方法

    public static void main(String[] args) {
        Stream<String> stream = Stream.of("zhang", "wang", "heihei", "zqc");

        stream.forEach((String name) -> {
            //此处相当于重写accep方法
            System.out.println(name);
        });
    }
count —— 统计个数

long count():用于统计Stream流中元素的个数
与集合中size()方法类似

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(4);
        list.add(223);
        list.add(232);
        list.add(43);
        list.add(54);

        Stream<Integer> stream = list.stream();
        long count = stream.count();
        int size = list.size();
        System.out.println(size);
        System.out.println(count);
    }

延迟方法

filter —— 过滤

image.png

    public static void main(String[] args) {
        Stream<String> steam = Stream.of("zz", "xx", "qq", "zqc");
        //对流进行过滤
        Stream<String> stream2 = steam.filter((String name) -> {
            return name.startsWith("z");
        });

        //遍历stream2流
        stream2.forEach((String name) -> {
            System.out.println(name);
        });
    }
map —— 映射

image.png

    public static void main(String[] args) {
        Stream<String> stream = Stream.of("1", "2", "3", "4");

        Stream<Integer> stream1 = stream.map((String s) -> {
            return Integer.parseInt(s);
        });

        stream1.forEach((i) -> {
            System.out.println(i);
        });
    }
limit —— 取用前几个

Stream<T< limit(long maxSize)
对流进行截取,只取用前n个

    public static void main(String[] args) {
        String[] arr = {"123", "1233", "2131", "e432"};
        Stream<String> stream = Stream.of(arr);
        Stream<String> limit = stream.limit(2);
        limit.forEach(i -> System.out.println(i));
    }
skip —— 跳过前几个

Stream<T> skip(long n)
if(流的当前长度超过n)跳过前n个
else 返回长度为0的空流

    public static void main(String[] args) {
        String[] arr = {"123", "1233", "2131", "e432",
                "43432", "44d43"};
        Stream<String> stream = Stream.of(arr);
        Stream<String> skip = stream.skip(3);
        skip.forEach(i -> System.out.println(i));

    }
concat —— 组合

Stream接口中静态方法(与String类中的concat方法不同),把两个流合成一个流

    public static void main(String[] args) {
        Stream<String> stream = Stream.of("123", "1233", "2131",
                "e432", "43432", "44d43");

        String[] arr2 = {"dili, girl", "zz, girl",
                "hehei, male"};
        Stream<String> stream1 = Stream.of(arr2);

        Stream<String> streamS = Stream.concat(stream, stream1);
        streamS.forEach(name -> System.out.println(name));
    }

案例:
不用Stream流

    public static void main(String[] args) {
        ArrayList<String> one = new ArrayList<>();
        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("石破天");
        one.add("老子");
        one.add("洪七公");
        //1.第一个队伍只要名字成员为3个字的,存到新集合中
        ArrayList<String> one_1 = new ArrayList<>();
        for (String name : one) {
            if (name.length() == 3) {
                one_1.add(name);
            }
        }

        //2.第一支队伍筛选只要前三个人,存储到新集合中
        ArrayList<String> one_2 = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            one_2.add(one_1.get(i));
        }

        //第二支队伍
        ArrayList<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("张三丰");
        two.add("张张张");
        two.add("古力扎");
        two.add("古力娜扎");

        //只要姓张的,存入新集合
        ArrayList<String> two_1 = new ArrayList<>();
        for (String name : two) {
            if (name.startsWith("张")) {
                two_1.add(name);
            }
        }
        //再筛选不要前两个人
        ArrayList<String> two_2 = new ArrayList<>();
        for (int i = 2; i < two_1.size(); i++) {
            two_2.add(two_1.get(i));
        }

        //最后把两个集合整在一起
        ArrayList<String> all = new ArrayList<>();
        all.addAll(one_2);
        all.addAll(two_2);

        //根据姓名创建Person对象,存储到一个新集合
        ArrayList<Person> list = new ArrayList<>();
        for (String name : all) {
            //重点理解这句
            list.add(new Person(name));
        }

        for (Person person : list) {
            System.out.println(person);
        }
    }

Stream流优化以后:

    public static void main(String[] args) {
        ArrayList<String> one = new ArrayList<>();
        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("石破天");
        one.add("老子");
        one.add("洪七公");
        //1.第一个队伍只要名字成员为3个字的,存到新集合中
        //2.第一支队伍筛选只要前三个人,存储到新集合中
        Stream<String> oneStream = one.stream().filter(name -> name.length() == 3).limit(3);

        //第二支队伍
        ArrayList<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("张三丰");
        two.add("张张张");
        two.add("古力扎");
        two.add("古力娜扎");
        //只要姓张的,存入新集合
        //再筛选不要前两个人
        Stream<String> twoStream = two.stream().filter(name -> name.startsWith("张")).skip(2);

        //最后把两个集合整在一起
        //根据姓名创建Person对象,存储到一个新集合
        Stream.concat(oneStream, twoStream).
                map(name -> new Person(name)).forEach(p -> System.out.println(p));
    }

waikiki
4 声望2 粉丝