Java十分钟快速掌握Stream流

1、什么是Stream流:

Stream 是Java 8 提出的一个新概念,不是输入输出的 Stream 流 (和IO流其实没有任何关系哈),而是一种使用函数式编程方式在集合类上进行操作的工具。简而言之,是以内部迭代的方式处理集合数据的操作,内部迭代可以将更多的控制权交给集合类。Stream 和 Iterator 的功能类似,只是Iterator 是以外部迭代的形式处理集合数据的操作。

当然Stream也有自己特性:

  • 不是一种数据结构,不会存数据,只是在原数据集上定义了一组操作
  • 这些操作是惰性的,即每当访问到流中的一个元素,才会在此元素上执行这一系列操作
  • 因为不保存数据,故每个Stream流只能使用一次。

Stream流的实现图:

2、创建流:

想要用Stream流来操作集合,那么就需要将数组或者集合先转换成Stream流才可以操作

Stream的官方文档:

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/stream/Stream.html

先来看四个方法:

  • filter:通过lambda表达式来实现条件过滤
  • limit:截取流,截取一段流
  • skip:跳过流
  • distinct:去除重复

创建Stream:

public class Test {
    public static void main(String[] args) {

        String [] arr = {"东","南","西","北"};

        //将数组转换成Stream
        Stream<String> stream = Arrays.stream(arr);
        stream = Stream.of(arr);
        stream = Stream.of("东","南","西","北");

        //将list集合转换成stream
        List<String> list = Arrays.asList("aa","cc","bb","aa","dd");
        stream = list.stream();

        //排序、去重、遍历
        list.stream().sorted().distinct().forEach(System.out::println);

        //用过Stream流操作完集合后还可以再转换成一个新的集合
        List<String> newList = list.stream().sorted().distinct().collect(Collectors.toList());
        System.out.println(newList.toString());
    }
}

输出:

//遍历并去重后的结果:
aa
bb
cc
dd
//用过Stream流操作完集合后还可以再转换成一个新的集合
[aa, bb, cc, dd]

四个方法的操作:

Person类:

这个类代码比较多,所有不把get/set方法写进去了,大家的使用的时候别忘!!

public class Person {
    private String  name;
    private Integer age;
    private  String country;
    private  char sex;

    @Override
    public String toString() {
        return "信息表:{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", country='" + country + '\'' +
                ", sex=" + sex +
                '}';
    }

//这里节省的get/set代码

//重写toString() 和 equals 和 hashcode 方法
    @Override
    public boolean equals(Object o){
        if(this == o)
            return true;
        if(o == null || getClass() != o.getClass())
            return false;
        Person person = (Person) o;

        if(country != null){
            if(this.country.equals(person.country)){
                return  true;
            }else{
                return false;
            }
        }
        return false;
    }

    @Override
    public int hashCode(){
        return Objects.hash(country);
    }
}

测试类:

结合了lambda表达式来写

public class Test {
    public static void main(String[] args) {
        List<Person> perosnList = new ArrayList<>();

        perosnList.add(new Person("王一", 30, "中国", 'M'));
        perosnList.add(new Person("张三", 19, "美国", 'F'));
        perosnList.add(new Person("李四", 29, "日本", 'F'));
        perosnList.add(new Person("小美", 74, "英国", 'M'));
        perosnList.add(new Person("熊二", 15, "意大利", 'F'));
        perosnList.add(new Person("熊大", 66, "韩国", 'F'));

        //返回年龄大于20岁的学生集合
        System.out.println("返回年龄大于20岁的学生集合");
        perosnList.stream().filter(p -> p.getAge() > 20).forEach(System.out::println);

        //返回年龄大于50岁的学生集合
        System.out.println("返回年龄大于50岁的集合");
        List<Person> list = perosnList.stream().filter(p -> p.getAge() > 50).collect(Collectors.toList());
        System.out.println(list);

        //返回年龄大于20岁的中国学生
        System.out.println("返回年龄大于20岁的中国人");
        perosnList.stream().filter(p -> p.getAge() > 20).filter(p -> p.getCountry().equals("韩国")).forEach(System.out::println);

        //年龄大于20  中国  性别M
        System.out.println("返回年龄大于20  中国  性别M");
        perosnList.stream().filter(p -> p.getAge() > 20 && p.getCountry().equals("中国") && p.getSex() == 'M').forEach(System.out::println);

    }
}

看看结果:

返回年龄大于20岁的学生集合
信息表:{name='王一', age=30, country='中国', sex=M}
信息表:{name='李四', age=29, country='日本', sex=F}
信息表:{name='小美', age=74, country='英国', sex=M}
信息表:{name='熊大', age=66, country='韩国', sex=F}

返回年龄大于50岁的集合
[信息表:{name='小美', age=74, country='英国', sex=M}, 信息表:{name='熊大', age=66, country='韩国', sex=F}]

返回年龄大于20岁的中国人
信息表:{name='熊大', age=66, country='韩国', sex=F}

返回年龄大于20 中国 性别M
信息表:{name='王一', age=30, country='中国', sex=M}

小结:

使用Stream流可以容易操作数组或者集合,可以结合Lambda表达式,可以让一句表达式整洁明了,其实既然是Java退出的新特性,那么肯定是有用处的。

3、Stream的map映射流

public class Test {
    public static void main(String[] args) {

        //map的作用是迭代取到每个list元素,再通过map里面的函数进行相应的操作
        List<String> list1 = Arrays.asList("a","bb","ccc","dddd");
        //通过map取到每个集合元素的长度并返回
        Stream<Integer> stream = list1.stream().map(p->p.length());

        stream.forEach(System.out::println);
        System.out.println("----------------");

        List<String> userList = new ArrayList<>();
        userList.add("周杰伦.tom");
        userList.add("尼古拉斯.赵四");
        userList.add("牛顿.巴基斯");
        userList.add("赵少华.思密达");

        List<String> uList = userList.stream().map(p->p.substring(p.indexOf(".")+1,
                p.length())).collect(Collectors.toList());
        System.out.println(uList.toString());
    }
}

输出:

1
2
3
4
----------------
[tom, 赵四, 巴基斯, 思密达]

4、Stream查找与匹配

Stream内还有一个 anyMatch(Predicate<? super T> predicate) 的方法:

返回此流中的任何元素是否匹配所提供的词

Demo:

public class Test {
    public static void main(String[] args) {

        List<String> list = Arrays.asList("周杰伦","王力宏","孙燕姿","林俊杰");
        boolean flag1 = list.stream().anyMatch(ele->ele.contains("燕"));
        System.out.println("有没有名字包含燕的同学:"+flag1);

        //判断开头:
        boolean flag2 = list.stream().anyMatch(ele->ele.startsWith("王"));
        System.out.println("有没有名字开头是王的同学:"+flag2);

        //判断结尾:
        boolean flag3 = list.stream().anyMatch(ele->ele.endsWith("杰"));
        System.out.println("有没有名字结尾是杰的同学:"+flag3);

        // anyMatch是匹配所有的,要满足条件

        boolean flag4 = list.stream().anyMatch(ele->ele.length()>2);
        System.out.println("所有同学的名字都是两个字以上的吗"+flag4);

        boolean flag5 = list.stream().anyMatch(ele->ele.startsWith("王"));
        System.out.println("所有同学的名字都有王吗?"+flag5);

        //noneMatch
        boolean flag6 = list.stream().noneMatch(ele->ele.contains("燕"));
        System.out.println("集合中都没有包含'燕'这个字吗"+flag5);
    }
}

输出:

有没有名字包含燕的同学:true
有没有名字开头是王的同学:true
有没有名字结尾是杰的同学:true
所有同学的名字都是两个字以上的吗true
所有同学的名字都有王吗?true
集合中都没有包含'燕'这个字吗true

使用anyMatch()里面的方法可以很容易对这个流的信息匹配。

最后附上一张Stream流的方法速记图啦:

到此这篇关于Java十分钟快速掌握Stream流的文章就介绍到这了,更多相关Java Stream流内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java8中Stream流式操作指南之入门篇

    目录 简介 正文 1. 流是什么 2. 老板,上栗子 3. 流的操作步骤 4. 流的特点 5. 流式操作和集合操作的区别: 总结 简介 流式操作也叫做函数式操作,是Java8新出的功能 流式操作主要用来处理数据(比如集合),就像泛型也大多用在集合中一样(看来集合这个小东西还是很关键的啊,哪哪都有它) 下面我们主要用例子来介绍下,流的基操(建议先看下lambda表达式篇,里面介绍的lambda表达式.函数式接口.方法引用等,下面会用到) 正文 1. 流是什么 流是一种以声明性的方式来处理数据的AP

  • Java 8 Stream流强大的原理

    目录 1.Stream的组成与特点 2.BaseStream接口 3.Stream接口 4.关闭流操作 5.并行流和串行流 6.ParallelStream背后的男人:ForkJoinPool 7.用ForkJoinPool的眼光来看ParallelStream 8.并行流的性能 9.NQ模型 10.遇到顺序 前言: Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象. Stream API可以极大提高Java程序员的生产力,让程

  • Java关于JDK1.8新特性的Stream流

    目录 Java 的Stream流 一.定义 二.操作的特征 三.代码示例 1.生成流 2.forEach 迭代 3.limit方法用于获取指定数量的流 4.map 5.sorted 6.并行(parallel)程序 7.Collectors 8.转化(将枚举类转成map) Java 的Stream流 一.定义 JDK1.8 中增加了Stream流,Stream流是一个来自数据源的元素队列并支持聚合操作.元素是特定类型的对象,形成一个队列,Java中的Stream并不会存储元素,而是按需计算数据源

  • 总结一下关于在Java8中使用stream流踩过的一些坑

    Java8的stream流 第一个坑: Collectors.toAsList()其实是new了一个list,在向里面赋值. 注意这里Collectors.toList()的写法,这里其实是底层new ArraryList().筛选的数据放到一个新的list.虽然标1处和标2处是同一个变量,但是内存地址是不一样啊.下面的逻辑时把hldrPolVOList中的某些元素删除.但是这个方法执行完后其实是没有删除里面元素的.原因就是这里的new ArraryList()更改了内存地址造成的. 测试: 解

  • 一篇文章带你了解Java Stream流

    目录 一.Stream流引入 现有一个需求: 1.用常规方法解决需求 2.用Stream流操作集合,获取流,过滤操作,打印输出 二.Stream流的格式 三.获取流 四.Stream流的常用方法 方法演示: 1.count方法: 2.filter方法: 3.forEach方法 4.limit方法 5.map方法 6.skip方法 7.concat方法 五.收集Stream流 总结 一.Stream流引入 Lambda表达式,基于Lambda所带来的函数式编程,又引入了一个全新的Stream概念,

  • java8新特性之stream流中reduce()求和知识总结

    1.stream().reduce()单字段求和 (1)普通数字求和 public static void test2(){ List<Integer> list= Arrays.asList(new Integer[]{1,2,3,4,5,6,7,8,9}); Integer sum=list.stream().reduce((x,y)->x+y).get(); System.out.println(sum); } 2.BigDecimal求和 public static void m

  • 手把手带你了解Java-Stream流方法学习及总结

    目录 前言 forEach() map() map()源码: filter() filter()源码: sorted() sorted()源码: collect() collect()源码: 总结 前言 Stream是一个来自数据源的元素队列并支持聚合操作,其中具有以下特性: Stream只负责计算,不存储任何元素,元素是特定类型的对象,形成一个队列 数据源可以实集合.数组.I/O channel.generator等 聚合操作有类似SQL的:filter.map.match.sorted等操作

  • 基于Java8并行流(parallelStream)的注意点

    Java8并行流(parallelStream)注意点 在最初使用并行流的时候,查询列表会偶尔性报空指针异常,这令我非常纳闷 代码是这样的: List<OrderListVO> orderListVOS = new LinkedList<OrderListVO>(); baseOrderBillList.parallelStream().forEach(baseOrderBill -> { OrderListVO orderListVO = new OrderListVO()

  • Java十分钟快速掌握Stream流

    1.什么是Stream流: Stream 是Java 8 提出的一个新概念,不是输入输出的 Stream 流 (和IO流其实没有任何关系哈),而是一种使用函数式编程方式在集合类上进行操作的工具.简而言之,是以内部迭代的方式处理集合数据的操作,内部迭代可以将更多的控制权交给集合类.Stream 和 Iterator 的功能类似,只是Iterator 是以外部迭代的形式处理集合数据的操作. 当然Stream也有自己特性: 不是一种数据结构,不会存数据,只是在原数据集上定义了一组操作 这些操作是惰性的

  • Java十分钟快速掌握单例模式

    目录 前言 1.什么是单例模式: 2.单例模式的优缺点: 3.懒汉模式(比较常用) 4.饿汉模式[推荐使用] 5.单例模式的应用场景 6.单例模式的应用实例 小结: 前言 首先在Java中有23种设计模式: 创建型模式: 工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式结构型模式: 适配器模式.装饰者模式.代理模式.外观模式.桥接模式.组合模式.享元模式行为型模式::策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释

  • Java十分钟入门多线程下篇

    目录 1.线程池: 2.创建线程池: 1.newCacheThreadPool: 2.newSingleThreadExecutor: 3.newFixedThreadPool(inta): 4.newScheduledTreadPool: 3.线程池创建自定义线程: 4.Runnable和Callable的区别: 5.线程池总结: 1.线程池: 什么是线程池? 咱们也不看长篇大论,通俗的来讲,线程池就是装线程的容器,当需要用的时候去池里面取出来,不用的时候放回去或者销毁.这样一个线程就可以反复

  • Java十分钟入门多线程中篇

    目录 1.线程的调度: 1.设置优先级(Priority): 2.休眠(sleep) 3.强制运行(join) 4.礼让(yield) 2.定时器线程: 3.线程的同步: 举例说明: 我们知道飞机在天上飞行是有固定的航线(可以理解成线程),每个机场都有最大的运行负载能力,当运行情况超过了负载能力的时候,这就需要塔台调度参与,会根据每架飞机的优先级排序.当在航线的时候,如果出现紧急情况,会让其他飞机避让,让这架飞机优先级提高,先降落.这就是调度,计算机程序线程运行也是这样的. 1.线程的调度: 在

  • Java十分钟入门多线程上篇

    什么是多线程? 在学习前,我们先对程序.进程.线程.并行.并发有个基础的概念了解: 程序: 为完成指定任务,用编程语言编写的一组指令的集合,即指一段静态的代码,静态对象. 进程: 是程序的一次执行过程,是一个动态的过程,进程自身有产生.使用和消亡的过程.(也称为生命周期,在后面会介绍) 线程: 进程可进一步细化为线程,是一个程序内部的一条执行路径,也就是进程内有线程 并行: 指两个或者多个事件在同一时刻发生,(同时发生) 并发: 指两个或者多个事件在同一个时段内发生,(并不是同时发生) 更好的理

  • Java十分钟精通反射机制原理

    什么是反射? 反射机制是在运行状态中,它为Java提供一种"操作对象"的能力,在运行状态下,通过Class文件对象,可以调用到任何类里面的属性.方法.以及构造方法,包括私有的,所有的类在反射机制面前都是透明的 自己的概括:通过Class文件对象可以看到这个类里面的所有东西,并且可以使用和修改 反射的前提是获取Class文件对象((字节码对象),那么一共有三种方式获取: Class.forName("全类名") ----通过Class类的静态方法(最常用) 类名.cl

  • Java十分钟精通集合的使用与原理上篇

    目录 什么是集合? 集合分为Collection和Map两种体系 一.Collection接口: 二.Map接口下分为HashMap和TreeMap: 集合总结: Collections工具类: 什么是集合? 比如我们去买超市买很多东西,我们不可能拿一样就去收银台,我们可能是先放到购物车内,然后再统一处理,所以购物车相当于一个容器,可以装很多东西,在Java中的集合也是相当于一个容器,可以装很多数据. 集合继承关系图: 但是这张图太复杂了,我们看一张简便的: 集合分为Collection和Map

  • Java十分钟精通集合的使用与原理下篇

    List集合: ArrayList: 底层是数组结构,储存有序并且可以重复的对象 package SetTest; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ArrayListTest { public static void main(String[] args) { //创建ArrayList的对象 List<Integer> list = ne

  • Java十分钟精通Log4j日志的使用

    目录 为什么要用日志? 下载: 详细步骤: 一.打开IDEA 二.创建日志对象 为什么要用日志? 我们知道,程序在运行过程中会产生很多很多信息,比如在几点几分的时候运行了,运行的结果是怎么样的?为了我们更加了解程序运行的情况,可以通过日志来查看,日志可以在控制台输出,也可以输出至指定的文件内,在下面的文章中具体的给大家介绍. 下载: Log4J是Apache公司的开源项目,用于日志处理.下载地址: https://logging.apache.org/log4j/2.x/download.htm

  • Java十分钟精通异常处理机制

    目录 异常处理机制的底层原理 异常的继承关系图 异常的处理 一.try-catch-finally结构 二.多catch处理不同的异常: 三.throws声明异常/throw抛出异常: 四.自定义异常: 五.常见的异常 异常处理机制的底层原理 抛出异常,在执行一个方法时,如果发送了异常,则这个方法生成代表该异常的一个对象,停止当前执行的 路径,并把异常提交给jre. 捕获异常:jre得到该异常后,虚招相应的代码来处理该异常.jre在方法的调用栈中查找,从生成异常的 方法开始回溯,直到找到相应的异

随机推荐