ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Stream流

2026/8/16 13:11:06 拓冰建站 浏览量
Stream流

文章目录

  • Stream流
    • Stream流的使用方式
    • 模拟Stream流的过程
    • Stream流的生成方式
    • Stream中间流
    • Stream结束流
    • 案例 - 翻页的逻辑

Stream流

Stream流的使用方式

  • 生成流:通过数据源(数组或者集合)生成流,list.stream()

  • 中间流:一个流后面可以跟随任意个中间操作,其目的是打开流,在过程中做 过滤/映射,然后返回一个新的流交给下一个操作使用,filter()

  • 结束流:一个流只能有一个终结操作,当这个操作执行后,流就被使用 了。forEach()

Stream 才是真正的把函数式编程带给了 Java

demo: 筛选数据的两种方式:

  1. 正常调用方法,一步步筛选
  2. 通过Steam流的方式,把集合转成流,调用filter方法,进行筛选
package com.itxs.demo09;import java.util.ArrayList;/*** @Classname : demo01* @Description : TODO 简单使用一下Stream流* @Author : lin_refuel@qq.com*/
public class demo01 {public static void main(String[] args) {// 定义一个集合ArrayList<String> list = new ArrayList<>();beginningList(list); // 初始化集合里面的数据// 找出集合里面名字是三个字以上的成员并且进行输出ArrayList<String> three = new ArrayList<>();for (String name : list) {if(name.length() >= 3)three.add(name);}// 输出threefor (String name : three) {System.out.println(name);}System.out.println("==================================");// 找出集合three里面里面姓郭的成员ArrayList<String> threeguo = new ArrayList<>();for (String name : three) {if(name.startsWith("郭"))threeguo.add(name);}for (String name : threeguo) {System.out.println(name);}System.out.println("===================================");// 通过Stream流的方式System.out.println("通过Stream流的方式");list.stream().filter(s -> s.length() >= 3).filter(s ->s.startsWith("郭")).forEach(System.out::println);}/*** 初始化集合里面数据* @param list 目标集合*/private static void beginningList(ArrayList<String> list) {list.add("郭德纲");list.add("郭麒麟");list.add("郭汾阳");list.add("郭冬临");list.add("郭美美");list.add("郭靖");list.add("黄蓉");list.add("小龙女");list.add("杨过");list.add("迪丽热巴");list.add("古力娜扎");}
}

模拟Stream流的过程

demo:对象的连贯操作,进行字符串拼接

定义一个名字为MyStringBuilder类

package com.itxs.demo09;/*** @Classname : MyStringBuilder* @Description : TODO* @Author : lin_refuel@qq.com*/
public class MyStringBuilder {// 定义一个空的字符串串private String str = "";public String getStr() {return str;}// 模拟起始流public MyStringBuilder append(String s){str += s;return this;// 返回当前自己}// 结束流public void printInfo(){System.out.println(str);str = "";// 重置字符串}
}

测试类:demo02

package com.itxs.demo09;/*** @Classname : demo02* @Description : TODO 对象的连贯操作 - 模拟流的过程* @Author : lin_refuel@qq.com*/
public class demo02 {public static void main(String[] args) {MyStringBuilder msb = new MyStringBuilder();// 对象连贯操作msb.append("JavaSE ").append("MySQL ").append("JDBC ").append("Linux").printInfo();System.out.println( msb.getStr());}
}

运行结果:
在这里插入图片描述

Stream流的生成方式

Stream只能是针对数组或者集合进行操作

demo: 集合和数组生成流的方式

package com.itxs.demo09;import java.util.*;
import java.util.stream.Stream;/*** @Classname : demo03* @Description : TODO 集合,数组 生成流的方式* @Author : lin_refuel@qq.com*/
public class demo03 {public static void main(String[] args) {// Collection 单列集合 分为 Arraylist 和 SetArrayList<String> list = new ArrayList<>();Stream<String> stream = list.stream();// Arraylist的生成流的方式//***********************************************************// Set集合生成流的方式Set<String> s = new HashSet<>(); // Set集合中的HashSetStream<String> stream1 = s.stream();// Set集合生成流//***********************************************************// Map 双列集合HashMap<String, String> hm = new HashMap<>();Stream<String> stream2 = hm.keySet().stream();// 获取键值的流Stream<String> stream3 = hm.values().stream();// 获取键对应的值的流Set<Map.Entry<String, String>> entries = hm.entrySet();Stream<Map.Entry<String, String>> stream4 = entries.stream();// 获取键值对的流//*************************************************************// 数组生成流的方式String[] strArr ={};Stream<String> S01 = Stream.of(strArr);// 第二种方式,Stream。of()里面放入的是可变长的参数Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);// 直接生成一个Integer类型的流Stream<String> stringStream = Stream.of("1", "2", "3");// 生成一个String类型的流}

Stream中间流

中间流常用的方法

package com.itxs.demo09;import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Stream;/*** @Classname : demo04* @Description : TODO 中间流 & 结束流* @Author : lin_refuel@qq.com*/
public class demo04 {public static void main(String[] args) {// 定义一个集合ArrayList<String> list = new ArrayList<>();beginningList(list); // 初始化集合里面的数据// 找出集合里面姓氏为郭的// filter数据筛选//list.stream().filter((s)->s.startsWith("郭")).forEach(System.out::println);//***************************************************************************// 截取集合里面前面6个数据//list.stream().limit(6).forEach(System.out::println);//***************************************************************************// 跳过前面2个数据//list.stream().skip(2).forEach(System.out::println);//***************************************************************************// 跳过前面2个数据 截取后面6个数据// list.stream().skip(2).limit(6).forEach(System.out::println);//***************************************************************************// 结合两个流// 跳过前面2个组成一个流//Stream<String> s01 = list.stream().skip(2);;// 取前面的4个//Stream<String> s02 = list.stream().limit(4);// 进行结合// Stream.concat(s01,s02).forEach(System.out::println);// 不去重复//Stream.concat(s01,s02).distinct().forEach(System.out::println);// 去重复//***************************************************************************// Stream流数据比较// list.stream().sorted().forEach(System.out::println);// 自然规则进行排序list.stream().sorted(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {int res = o1.length() - o2.length(); // 按照字符串长度进行比较return res == 0 ? o1.compareTo(o2) : res;}}).forEach(System.out::println);// 自定义规则进行排序}/*** 初始化集合里面数据** @param list 目标集合*/private static void beginningList(ArrayList<String> list) {list.add("郭德纲");list.add("郭麒麟");list.add("郭汾阳");list.add("郭冬临");list.add("郭美美");list.add("郭靖");list.add("黄蓉");list.add("小龙女");list.add("杨过");list.add("迪丽热巴");list.add("古力娜扎");}
}

Stream结束流

结束流常用的一些方法

package com.itxs.demo09;import java.util.ArrayList;
import java.util.Comparator;
import java.util.OptionalDouble;
import java.util.OptionalInt;/*** @Classname : demo05* @Description : TODO 结束流用到的一些常用的方法* @Author : lin_refuel@qq.com*/
public class demo05 {public static void main(String[] args) {// 定义一个集合ArrayList<String> list = new ArrayList<>();// 调用add进行添加元素list.add("23456789");list.add("3456789");list.add("123456789");list.add("6789");list.add("56789");list.add("456789");// 通过流的方式进行自然排序//list.stream().sorted().forEach(System.out::println);//*****************************************************// 通过流的方式,按照字符串长度进行排序//list.stream().sorted(Comparator.comparingInt(String::length).thenComparing(o -> o)).forEach(System.out::println);//*****************************************************// 把字符串转换成为Integer类型后进行排序 - 从小到大进行排序//list.stream().map(Integer::parseInt).sorted().forEach(System.out::println);//*****************************************************// 求出上面字符串转成Integer类型后的和//int sum = list.stream().mapToInt(Integer::parseInt).sum();//System.out.println("sum = " + sum);//*****************************************************// 求出上面字符串转成Integer类型后的平均值
//        OptionalDouble res = list.stream().mapToInt(s -> Integer.parseInt(s)).average();
//        // OptionalDouble是一个对象,输出格式如下
//        System.out.println(res);// 输出结果:OptionalDouble[2.5148455666666668E7]
//        // 调用方法 getAsDouble 可以获取对应类型值
//        double asDouble = res.getAsDouble();
//        System.out.println(asDouble);// 输出结果:2.5148455666666668E7//*****************************************************// 可以统计流中元素个数的方法 count//long count = list.stream().count();//System.out.println(count);// 6个元素//通过元素中长度超过6的元素个数//long count = list.stream().filter(s -> s.length() > 6).count();//System.out.println(count); // 3个//******************************************************// 可以求出字符串转Integer类型后元素的最大值和最小值// 获取到对象maxOptionalInt max = list.stream().mapToInt(s -> Integer.parseInt(s)).max();// 获取整数类型的值 getAsIntSystem.out.println(max.getAsInt());// 123456789// 最小值OptionalInt min = list.stream().mapToInt(Integer::parseInt).min();System.out.println(min.getAsInt());// 6789}
}

案例 - 翻页的逻辑

  1. 每页输出5个数据
  2. 通过N(下一页) 和 B(上一页)进行换页码
package com.itxs.demo09;import java.util.ArrayList;
import java.util.Scanner;/*** @Classname : demo06* @Description : TODO 翻页的逻辑* @Author : lin_refuel@qq.com*/
public class demo06 {public static void main(String[] args) {// 定义一个集合ArrayList<String> list = new ArrayList<>();beginningList(list); // 初始化集合里面的数据//=============================================final int number = 5;// 每页展示的数据个数为5int pageNumber = (list.size() / number) + (list.size() % number == 0 ? 0 : 1);// 页码数int pages = 0;// 控制页码数//=============================================while (true) {// 输出第一页的5个数据 skip中间流用于每次翻页跳过五个数据 limit用于取到5个数据list.stream().skip(pages * number).limit(number).forEach(System.out::println);System.out.println("N -- 下一页 || B -- 上一页 ");// 重复进行调用方法进行选择翻页还是上一页nswitch (new Scanner(System.in).next()) {case "N":case "n":pages = Math.min(pages + 1, pageNumber - 1);// 设置翻页的下限,返回最小值break;case "B":case "b":pages = Math.max(pages - 1, 0);// 设置翻页的上限,返回一个最大值break;default:System.out.println("操作无效");}}}/*** 初始化集合里面数据** @param list 目标集合*/private static void beginningList(ArrayList<String> list) {list.add("郭德纲");list.add("郭麒麟");list.add("郭汾阳");list.add("郭冬临");list.add("郭美美");list.add("郭靖");list.add("黄蓉");list.add("小龙女");list.add("杨过");list.add("迪丽热巴");list.add("古力娜扎");list.add("小厮");list.add("小v");list.add("小a");}
}