Java开发从入门到精通(二十):Java的面向对象编程OOP:Stream流

Java大数据开发和安全开发

  • (一)Java的新特性:Stream流
    • [1.1 什么是Stream?](#1.1 什么是Stream?)
    • [1.2 Stream流的使用步骤](#1.2 Stream流的使用步骤)
    • [1.3 获取Stream流](#1.3 获取Stream流)
    • [1.4 Stream流常见的中间方法](#1.4 Stream流常见的中间方法)
    • [1.5 Stream流常见的终结方法](#1.5 Stream流常见的终结方法)

(一)Java的新特性:Stream流

1.1 什么是Stream?

  • 也叫Stream流,是Jdk8开始新增的一套API(java.util.stream.*),可以用于操作集合或者数组的数据

Stream流的优势:

  • Stream流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操
    作集合或者数组中的数据,代码更简洁,可读性更好。

    体验Stream流
    需求:
    把下面集合中所有以"张"开头,且是3个字的元素存储到一个新的集合。
java 复制代码
import java.util.ArrayList;
import java.util.List;

public class StreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
    }
}

使用集合和数组的API

java 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class StreamTest {
    public static void main(String[] args) {
        List<String>names =new ArrayList<>();
        Collections.addAll(names,"张三丰","张无忌","周芷若","赵敏","张强");
        System.out.println(names);
        // names=[张三丰,张无忌,周芷若,赵敏,张强】
        //          name
        // 找出姓张,且是3个字的名字,存入到一个新集合中去。
        List<String> list =new ArrayList<>();
        for(String name :names) {
            if (name.startsWith("张") && name.length() == 3) {
                list.add(name);
            }
        }
            System.out.println(list);
    }
}

开始使用Stream流来解决这个需求

java 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class StreamTest {
    public static void main(String[] args) {
        List<String> names =new ArrayList<>();
        Collections.addAll(names,"张三丰","张无忌","周芷若","赵敏","张强");
        System.out.println(names);
        //开始使用Stream流来解决这个需求。
        List<String> list2 = names.stream().filter(s -> s.startsWith("张")).filter(a ->a.length()==3).collect(Collectors.toList());
        System.out.println(list2);
    }
}

1.2 Stream流的使用步骤


1.3 获取Stream流

  • 获取集合的Stream流
  • 获取 数组 的Stream流
  • 各种集合和数组获取Stream流的代码示例
java 复制代码
import java.util.*;
import java.util.stream.Stream;

public class StreamTest {
    public static void main(String[] args) {
        //1、如何获取List集合的Stream流?
        List<String> names = new ArrayList<>();
        Collections.addAll(names,"张三丰","张无忌","周芷若","赵敏","张强");
        Stream<String> stream =names.stream(); //获取stream流

        // 2、如何获取Set集合的Stream流?
        Set<String> set = new HashSet<>();
        Collections.addAll(set,"刘德华","张曼玉","蜘蛛精","马德","德玛西亚");
        Stream<String>stream1=set.stream();  //获取stream流
        stream1.filter(s ->s.contains("德")).forEach(s -> System.out.println(s));

        // 3、如何获取Map集合的Stream流?
        Map<String,Double> map = new HashMap<>();
        map.put("古力娜扎",172.3);
        map.put("迪丽热巴",168.3);
        map.put("马尔扎哈",166.3);
        map.put("卡尔扎巴",168.3);

        Set<String> keys = map.keySet();
        Stream<String> ks = keys.stream(); //获取stream流 

        Collection<Double>values =map.values();
        Stream<Double>vs=values.stream();  //获取stream流

        Set<Map.Entry<String,Double>>entries = map.entrySet();
        Stream<Map.Entry<String, Double>> kvs = entries.stream();  
        kvs.filter(e ->e.getKey().contains("巴"))
                .forEach(e ->System.out.println(e.getKey()+ "-->"+ e.getValue()));

        // 4、如何获取数组的stream流?
        String[] names2 ={"张翠山","东方不败","唐大山","独孤求败"};
        Stream<String>sl=Arrays.stream(names2); //获取stream流
        Stream<String>s2=Stream.of(names2); //获取stream流

    }
}

1.4 Stream流常见的中间方法

  • 中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)。
  • 常见的中间方法的代码示例
java 复制代码
package com.qianxin.jihekuangjia;

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

public class StreamTest {
    public static void main(String[] args) {
        List<Double> scores =new ArrayList<>();
        Collections.addAll(scores,88.5,100.0,60.0,99.0,9.5,99.6,25.0);
        // 需求1:找出成绩大于等于60分的数据,并升序后,再输出。
        scores.stream().filter(s-> s>=60).sorted().forEach(s ->System.out.println(s));

        List<Student> students =new ArrayList<>();
        Student s1= new Student( "蜘蛛精",26, 172.5);
        Student s2 = new Student( "蜘蛛精",26,172.5);
        Student s3 = new Student( "紫霞",23, 167.6);
        Student s4= new Student( "白晶晶",25,169.0);
        Student s5 = new Student( "牛魔王", 35,183.3);
        Student s6=new Student( "牛夫人",34,168.5);
        Collections.addAll(students,s1,s2,s3,s4,s5,s6);
        // 需求2:找出年龄大于等于23,且年龄小于等于30岁的学生,并按照年龄降序输出
        students.stream().filter(s ->s.getAge()>= 23 && s.getAge()<= 30)
                .sorted((o1,o2)->o2.getAge()-o1.getAge())
                .forEach(s ->System.out.println(s));
        // 需求3:取出身高最高的前3名学生,并输出。
        students.stream().sorted((o1,o2)-> Double.compare(o2.getHeight(), o1.getHeight()))
                .limit(3).forEach(s ->System.out.println(s));//不同写法1

        students.stream().sorted((o1,o2)-> Double.compare(o2.getHeight(), o1.getHeight()))
                .limit(3).forEach(System.out::println);//不同写法2
        // 需求4:取出身高倒数的2名学生,并输出。
        students.stream().sorted((o1,o2)-> Double.compare(o2.getHeight(),o1.getHeight()))
                .skip(students.size()-2).forEach(System.out::println);
        //需求5:找出身高超过168的学生叫什么名字,要求去除重复的名字,再输出。
        students.stream().filter(s ->s.getHeight()> 168).map(Student::getName)
                .distinct().forEach(System.out::println);

        // distinct去重复,自定义类型的对象(希望内容一样就认为重复,重写hashCode,equal
        students.stream().filter(s->s.getHeight()> 168).distinct().forEach(System.out::println);

        Stream<String> st1 = Stream.of("张三","李四");
        Stream<String>st2= Stream.of("张三2","李四2","王五");
        Stream<String> allSt=Stream.concat(st1,st2);
        allSt.forEach(System.out::println);
    }
}
java 复制代码
package com.qianxin.jihekuangjia;

import java.util.Objects;

public class Student {
    private String name;
    private int age;
    private double height;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Double.compare(height, student.height) == 0 && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, height);
    }

    public Student() {
    }

    public Student(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    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 double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

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

1.5 Stream流常见的终结方法

  • 终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了
  • 常见的终结方法的代码示例
java 复制代码
import java.util.*;
import java.util.stream.Collectors;

public class StreamTest {
    public static void main(String[] args) {
        List<Student> students =new ArrayList<>();
        Student s1= new Student( "蜘蛛精",26, 172.5);
        Student s2 = new Student( "蜘蛛精",26,172.5);
        Student s3 = new Student( "紫霞",23, 167.6);
        Student s4= new Student( "白晶晶",25,169.0);
        Student s5 = new Student( "牛魔王", 35,183.3);
        Student s6=new Student( "牛夫人",34,168.5);
        Collections.addAll(students,s1,s2,s3,s4,s5,s6);

        // 需求1:请计算出身高超过168的学生有几人。
        long size = students.stream().filter(s ->s.getHeight()> 168).count();
        System.out.println(size);

        // 需求2:请找出身高最高的学生对象,并输出。
        Student s = students.stream().max((o1, o2)-> Double.compare(o1.getHeight(), o2.getHeight())).get();
        System.out.println(s);

        // 需求3:请找出身高最矮的学生对象,并输出。
        Student ss = students.stream().min((o1,o2)-> Double.compare(o1.getHeight(), o2.getHeight())).get();
        System.out.println(ss);    
    }
}

收集Stream流的方法

收集Stream流:就是把Stream流操作后的结果转回到集合或者数组中去返回

Stream流:方便操作集合/数组的手段; 集合/数组:才是开发中的目的

java 复制代码
import java.util.*;
import java.util.stream.Collectors;

public class StreamTest {
    public static void main(String[] args) {
        List<Student> students =new ArrayList<>();
        Student s1= new Student( "蜘蛛精",26, 172.5);
        Student s2 = new Student( "蜘蛛精",26,172.5);
        Student s3 = new Student( "紫霞",23, 167.6);
        Student s4= new Student( "白晶晶",25,169.0);
        Student s5 = new Student( "牛魔王", 35,183.3);
        Student s6=new Student( "牛夫人",34,168.5);
        Collections.addAll(students,s1,s2,s3,s4,s5,s6);
      
        // 需求4:请找出身高超过170的学生对象,并放到一个新集合中去返回,
        // 流只能收集一次。
        List<Student> students1 = students.stream().filter(a -> a.getHeight()> 170).collect(Collectors.toList());
        System.out.println(students1);

        Set<Student> students2 = students.stream().filter(a -> a.getHeight()> 170).collect(Collectors.toSet());
        System.out.println(students2);
        // 需求5:请找出身高超过170的学生对象,并把学生对象的名字和身高,存入到一个Map集合返回。
        Map<String,Double> map =
                students.stream().filter(a->a.getHeight()>170)
                        .distinct().collect(Collectors.toMap(a ->a.getName(),a-> a.getHeight()));
                        
		Object[] arr = students.stream().filter(a -> a.getHeight()> 170).toArray();
        System.out.println(Arrays.toString(arr));

        Student[] arr1 =students.stream().filter(a ->a.getHeight()>170).toArray(len -> new Student[len]);
        System.out.println(Arrays.toString(arr1));
    }
}
相关推荐
四谎真好看1 小时前
Java 黑马程序员学习笔记(进阶篇18)
java·笔记·学习·学习笔记
桦说编程1 小时前
深入解析CompletableFuture源码实现(2)———双源输入
java·后端·源码
java_t_t1 小时前
ZIP工具类
java·zip
lang201509282 小时前
Spring Boot优雅关闭全解析
java·spring boot·后端
pengzhuofan3 小时前
第10章 Maven
java·maven
百锦再3 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
刘一说3 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多3 小时前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring
百锦再4 小时前
对前后端分离与前后端不分离(通常指服务端渲染)的架构进行全方位的对比分析
java·开发语言·python·架构·eclipse·php·maven
DokiDoki之父4 小时前
Spring—注解开发
java·后端·spring