Stream流编程学习笔记

Stream流编程:

       概念:一个强大而高级的迭代器,非数据结构,非集合,不能存放数据,等同于生活中的流水线。

外部迭代与内部迭代:

package com.tian.stream;

import java.util.stream.IntStream;

public class StreamDemo1 {
    public static void main(String[] args) {
        int [] arr={1,2,3,4};
        int sum=0;
        //外部迭代
        for (int a:arr) {
            sum+=a;
        }
        System.out.println(sum+"---外部迭代");

        //使用stream流的内部迭代
        System.out.println(IntStream.of(arr).sum()+"---Stream流内部迭代");
    }
}

中间操作、终止操作、惰性求值:

package com.tian.stream;

import java.util.stream.IntStream;

public class StreamDemo1 {
    public static void main(String[] args) {
        int [] arr={1,2,3,4};
        //中间操作返回的是Stream流
        //终止操作返回的是一个结果
        //未执行终止操作,中间操作就不会执行
        //惰性求值就是终止操作未调用的情况
        System.out.println(IntStream.of(arr).map(StreamDemo1::doubleNum).sum()+"---Stream流执行终止操作");

        //未执行终止操作
        System.out.println("未执行终止操作");
        System.out.println(IntStream.of(arr).map(StreamDemo1::doubleNum)+"---Stream流未执行终止操作");
    }
    public static int doubleNum(int i){
        return i*2;
    }
}

流的创建:

package com.tian.stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 流的创建
 *
 */
public class StreamDemo2 {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        //从集合中创建
        list.stream();
        list.parallelStream();

        //从数组中创建
        Arrays.stream(new int[]{1,2,3});

        //创建数字流
        IntStream.of(1,2,3);
        IntStream.rangeClosed(1,10);

        //使用random创建一个无线流
        new Random().ints().limit(10);

        //自己产生的流
        Random random=new Random();
        Stream.generate(()->random.nextInt()).limit(20);
    }

}

Stream流的中间操作:

package com.tian.stream;

import java.util.Random;
import java.util.stream.Stream;

public class StreamDemo3 {
    public static void main(String[] args) {
        String s="my name is tianyuan";

        //打印每一个单词的长度
        System.out.println("------map------");
        Stream.of(s.split(" ")).filter(i->i.length()>2).map(i->i.length()).forEach(System.out::println);

        //flatMap A->B属性(是个集合),最终得到所有A元素里所有的B属性集合
        //intStream/longStream 并不是Stream的子类,所以要进行装箱boxed()
        System.out.println("------flatMap------");
        Stream.of(s.split(" ")).flatMap(i->i.chars().boxed()).forEach(i->System.out.println((char)i.intValue()));

        //peek 用于debug  是个中间操作,和forEach是个终止操作
        System.out.println("------peek------");
        Stream.of(s.split(" ")).peek(System.out::println).forEach(System.out::println);

        //limit 主要用于一个无线流
        System.out.println("------limit------");
        new Random().ints().limit(5).forEach(System.out::println);


    }
}

流的终止操作:

package com.tian.stream;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamDemo4 {
    public static void main(String[] args) {
        String str="my name is helloworld";
        //使用并行流
        str.chars().parallel().forEach(i-> System.out.print((char)i));
        System.out.println();

        //使用forEachOrdered保证顺序
        str.chars().parallel().forEachOrdered(i-> System.out.print((char)i));
        System.out.println();

        //收集到list
        List<String> list = Stream.of(str.split(" ")).collect(Collectors.toList());
        System.out.println(list);

        //使用reduce拼接字符串
        String reduce = Stream.of(str.split(" ")).reduce("", (s1, s2) -> s1 + "|" + s2);
        System.out.println(reduce);

    }
}

并行流:

正常打印:

package com.tian.stream;

import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class StreamDemo5 {
    public static void main(String[] args) {
        IntStream.range(1,10).peek(StreamDemo5::debug).count();

    }
    public static void debug(int i){
        System.out.println("debug"+i);
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

并行打印:

package com.tian.stream;

import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class StreamDemo5 {
    public static void main(String[] args) {
        IntStream.range(1,10).parallel().peek(StreamDemo5::debug).count();

    }
    public static void debug(int i){
        System.out.println("debug"+i);
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

先并行再串行:(结论:多次调用并行和串行,以最后一次调用为准)

package com.tian.stream;

import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class StreamDemo5 {
    public static void main(String[] args) {
        IntStream.range(1,10)
                .parallel().peek(StreamDemo5::debug)
                .sequential().peek(StreamDemo5::debug2)
                .count();

    }
    public static void debug(int i){
        System.out.println("debug "+i);
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void debug2(int i){
        System.err.println("debug2 "+i);
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

package com.tian.stream;

import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class StreamDemo5 {
    public static void main(String[] args) {
        //并行流使用的默认线程池是:ForkJoinPool
        //默认线程数是当前机器的cpu个数
        //使用以下属性可以改变默认线程个数
        System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","6");
        IntStream.range(1,10).parallel().peek(StreamDemo5::debug).count();

    }
    public static void debug(int i){
        System.out.println(Thread.currentThread().getName()+":debug "+i);
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

对比注释属性结果:

自定义线程池:

package com.tian.stream;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class StreamDemo5 {
    public static void main(String[] args) {
        //使用自己创建的线程池,不使用磨人的线程池,防止任务阻塞
        //线程池名字ForkJoinPool
        ForkJoinPool forkJoinPool=new ForkJoinPool(6);
        forkJoinPool.submit(()->IntStream.range(1,10).parallel().peek(StreamDemo5::debug).count());
        forkJoinPool.shutdown();

        synchronized (forkJoinPool){
            try {
                forkJoinPool.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
    public static void debug(int i){
        System.out.println(Thread.currentThread().getName()+":debug "+i);
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

收集器:

package com.tian.stream;

import com.sun.xml.internal.ws.policy.PolicyMapUtil;

import java.util.*;
import java.util.stream.Collectors;

public class StreamDemo6 {
    public static void main(String[] args) {
        //测试数据
        List<Student> list = Arrays.asList(
                new Student("小明", 6, false, 7),
                new Student("小红", 7, true, 6),
                new Student("小橙", 8, false, 4),
                new Student("小黄", 9, true, 6),
                new Student("小绿", 10, true, 7),
                new Student("小青", 5, true, 3),
                new Student("小蓝", 7, true, 5),
                new Student("小紫", 6, false, 7),
                new Student("小黑", 9, false, 4),
                new Student("小白", 8, true, 6)
        );
        //得到所有学生的年龄列表
        List<Integer> ages = list.stream().map(s -> s.getAge()).collect(Collectors.toList());
        System.out.println("所有学生的年龄集合:" + ages);

        //s -> s.getAge()换成 Student::getAge 不会多生成类似lambda $0这样的函数
        Set<Integer> ages2 = list.stream().map(Student::getAge).collect(Collectors.toCollection(TreeSet::new));
        System.out.println("所有学生的年龄集合:" + ages2);

        //年龄汇总
        IntSummaryStatistics agecollect = list.stream().collect(Collectors.summarizingInt(Student::getAge));
        System.out.println("年龄汇总:" + agecollect);

        //分块
        Map<Boolean, List<Student>> booleanListMap = list.stream().collect(Collectors.partitioningBy(s -> s.isGender() == true));
        System.out.println("男女比例:" + booleanListMap);

        //分组
        Map<Integer, List<Student>> grades = list.stream().collect(Collectors.groupingBy(Student::getGrade));
        System.out.println("学生按年级分组:" + grades);

        //得到班级的学生的个数
        Map<Integer, Long> grade2 = list.stream().collect(Collectors.groupingBy(Student::getGrade, Collectors.counting()));
        System.out.println("学生按年级get数量:" + grade2);

    }
}
package com.tian.stream;

public class Student {
    private String name;
    private int age;
    private boolean gender;
    private int grade;

    public Student() {
    }

    public Student(String name, int age, boolean gender, int grade) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isGender() {
        return gender;
    }

    public void setGender(boolean gender) {
        this.gender = gender;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                ", grade=" + grade +
                '}';
    }
}

Stream 流运机制:

链式操作:所有操作为链式操作,每个元素只迭代一次,每一个中间操作返回一个新的流,流里面有一个属性sourceStage指向同一个链表头head

Head->sourceStage->sourcestage->....->null

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值