Steam流编程—jdk增效锦集

Stream流编程

Stream流编程—创建

分类相关方法
集合 Collection.stream/parallelStream
数组Arrays.stream
数字 lntStream/LongStream.range/rangeClosed
Random.ints/longs/doubles
自定义Stream.generate/iterate

测试

public static void main(String[] args) {
    // 从集合创建
    ArrayList<String> strings = new ArrayList<>();
    strings.stream();
    strings.parallelStream();

    // 从数组创建
    int[] arr = {1,23,123};
    Arrays.stream(arr);

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

    // 创建一个无限流
    new Random().ints().limit(10);

    // 自定义
    Random random = new Random();
    Stream.generate(() -> random.nextInt()).limit(20);
}



Stream流编程—中间操作

分类相关方法
无状态操作map/mapToXxx
password
filter
peek (和forEach作用一样,区别在于forEach是终止操作)
unordered
有状态操作distinct
sorted
limit/skip

使用演示,mapfilter

public static void main(String[] args) {
    String str = "i love java";

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

    // 2.打印每个单词的长度,小于等于1的不打印
    Stream
        .of(str.split(" "))
        .map(String::length)
        .filter(length -> length >1)
        .forEach(System.out::println);
}

使用演示,limit主要用于无限流

 // 产生10个,大于等于1小于100的数
new Random().ints().filter(i-> i>=1 && i<100).limit(10).forEach(System.out::println);



Stream流编程—终止操作

分类相关方法
非短路操作forEach/ forEachOrdered
collect/ toArray
reduce
min / max / count
有状态操作findFirst/ findAny
allMatch/ anyMatch/ noneMatch

forEachOrdered的作用

public static void main(String[] args) {
    String str = "i love java";

    // 使用并行流,forEach遍历顺序会乱
    str.chars().parallel().forEach(value -> System.out.println((char)value));
    // forEachOrdered保证顺序
    str.chars().parallel().forEachOrdered(value -> System.out.println((char)value));
}

collect

public static void main(String[] args) {
    String str = "i love java";

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

使用 reduce 拼接字符串

public static void main(String[] args) {
    String str = "i love java";

    Optional<String> reduce = Stream.of(str.split(" ")).reduce((s, s2) -> s + "|" + s2);
    System.out.println(reduce.orElse("内容为空"));
    // 结果 i|love|java
}



Steam流编程—并行流

parallel效果演示,具体的效果请各位自行体会。

public class Test {
    public static void debug(int i){
        System.out.println("debug" + i);
        try {
            // 睡眠3秒,方便查看效果
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public static void main(String[] args) {
    // 每3秒打印一次
    IntStream.range(1,100).forEach(Test::debug);

    // 每3秒打印8次
    IntStream.range(1,100).parallel().forEach(Test::debug);
}

效果查看,gif图片可能存在不能正常播放的情况,建议自行使用代码体会!
在这里插入图片描述

问题一:改成并行流后,我们新的需求出现了,先并行执行,然后串行执行。

IntStream.range(1,100).parallel().peek(Test::debug).sequential().peek(Test::debug).count();

sequential 代表串行的意思,最终代码以串行执行。结论:多次调用串行并行,以最后一次调用为准

问题二:串行执行的线程数可以改变吗?

//使用这个属性可以修改默认的线程数
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","20");



Steam流编程—收集器

准备工作

创建性别枚举类

public enum Gender {

    /**
     * 男
     */
    MALE,

    /**
     * 女
     */
    FEMALE,
}

创建班级枚举类

public enum Grade {

    /**
     * 一班
     */
    ONE,

    /**
     * 二班
     */
    TWO,

    /**
     * 三班
     */
    THREE,

    /**
     * 四班
     */
    FOUR
}

创建学生类

@Data
@AllArgsConstructor
public class Student {

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private int age;

    /**
     * 性别
     */
    private Gender gender;

    /**
     * 班级
     */
    private Grade grade;

}

初始化数据

public static void main(String[] args) {
    List<Student> students = Arrays.asList(
        new Student("小明", 10, Gender.MALE, Grade.ONE),
        new Student("大明", 9, Gender.MALE, Grade.THREE),
        new Student("小白", 8, Gender.FEMALE, Grade.TWO),
        new Student("小黑", 13, Gender.FEMALE, Grade.FOUR),
        new Student("小红", 7, Gender.FEMALE, Grade.THREE),
        new Student("小黄", 13, Gender.MALE, Grade.ONE),
        new Student("小青", 13, Gender.FEMALE, Grade.THREE),
        new Student("小紫", 9, Gender.FEMALE, Grade.TWO),
        new Student("小王", 6, Gender.MALE, Grade.ONE),
        new Student("小李", 6, Gender.MALE, Grade.ONE),
        new Student("小马", 14, Gender.FEMALE, Grade.FOUR),
        new Student("小刘", 13, Gender.MALE, Grade.FOUR)
    );
}

实战演练

public static void main(String[] args) {
    List<Student> students = Arrays.asList(
        new Student("小明", 10, Gender.MALE, Grade.ONE),
        new Student("大明", 9, Gender.MALE, Grade.THREE),
        new Student("小白", 8, Gender.FEMALE, Grade.TWO),
        new Student("小黑", 13, Gender.FEMALE, Grade.FOUR),
        new Student("小红", 7, Gender.FEMALE, Grade.THREE),
        new Student("小黄", 13, Gender.MALE, Grade.ONE),
        new Student("小青", 13, Gender.FEMALE, Grade.THREE),
        new Student("小紫", 9, Gender.FEMALE, Grade.TWO),
        new Student("小王", 6, Gender.MALE, Grade.ONE),
        new Student("小李", 6, Gender.MALE, Grade.ONE),
        new Student("小马", 14, Gender.FEMALE, Grade.FOUR),
        new Student("小刘", 13, Gender.MALE, Grade.FOUR)
    );

    // 获取所有学生的年龄列表
    List<Integer> ages = students.stream().map(Student::getAge).collect(Collectors.toList());

    // 获取所有学生的年龄列表(去重)
    Set<Integer> agesSet = students.stream().map(Student::getAge).collect(Collectors.toSet());

    // 统计汇总信息
    IntSummaryStatistics collect = students.stream()
        .collect(Collectors.summarizingInt(Student::getAge));
    System.out.println(collect); // count=12, sum=121, min=6, average=10.083333, max=14

    // 按性别分块-> 根据boolean分块,true为男生,false为女生
    Map<Boolean, List<Student>> genders = students.stream()
        .collect(Collectors.partitioningBy(student -> student.getGender() == Gender.MALE));

    // 按班级分组
    Map<Grade, List<Student>> grades = students.stream().
        collect(Collectors.groupingBy(Student::getGrade));
    
	// 按班级分组,查询每个班级的人数
     Map<Grade, Long> collect1 = students.stream()
         .collect(Collectors.groupingBy(Student::getGrade, Collectors.counting()));
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CV大魔王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值