首页 > 其他分享 >枚举与stream流详解

枚举与stream流详解

时间:2024-09-02 08:53:03浏览次数:6  
标签:10 stream Stream 对象 int 枚举 详解

1 枚举语法特点

  • 枚举是jdk1.5提供的一个特性

  • 枚举是一个特殊的类,这个类的对象的数量是有限的。在定义枚举类的同时就已经确定了类对象及类对象的数量。

  • 枚举使用enum关键字定义

  • 在枚举类中的第一行,就需要提供枚举类的对象(名字)

    多个对象名之间使用逗号隔开。

    最后一个对象可以使用分号,也可以不用。强烈建议使用分号结束

    每一个对象都相当于public static final A a ; (编码规范:常量的名字都大写)

enum A{
    //public static final A a1 = new A();
    a1 , a2 , a3 , a4 ;
}

 

  • 枚举类中也可以有属性,方法和构造方法,其中属性和方法与普通类没有任何区别。

  • 构造方法可以是无参,也可以是有参。但必须是private

  • 在声明枚举对象时,可以指定调用的构造方法及为构造方法传递的参数。

enum B{
    B1, //new B()
    B2(), //new B()
    B3(10,20), //new B(10,20);
    B4(100,200), //new B(100,200);
    B5 ;


    private B(){}

    private B(int i , int j){
        this.i = i ;
        this.j = j ;
    }

    int i ;
    int j ;
}
  • 枚举不能继承

  • 枚举中可以定义抽象方法

enum C{
    c1(){
        public void t1(){
            System.out.println("----------------------------");
        }
    } ,
    c2(){
        public void t1(){
            System.out.println("=============================");
        }
    } ;

    public abstract void t1() ;
}

 

2 枚举的使用

获得枚举对象

  • B b = B.B1;

  • 枚举对象可以作为switch的判断条件

public void test(B b){
    switch(b){
        case B1:break ;
        case B2:break ;
        case B3:break ;
        case B4:break ;
	}
}

使用枚举对象

  • 就是调用枚举对象的属性和方法。 包括两部分

    1. 定义枚举时,我们根据需求自定义的属性和方法

    2. 所有的枚举类都默认继承Enum父类。 类似于所有的注解都继承Annotation。 所以枚举 对象中还包含一些Enum父类中提供的方法

e.getName();//获得枚举对象的名字,也就是变量名
e.ordinal();//获得当前枚举对象在所有枚举对象列表中的位置(下标 0开始)
e.compareTo(Enum e1); //默认比较两个枚举对象的索引位置
Enum.valueOf(B.class,"B2"); //获得指定名字的枚举对象
B.values(); //获得B这个枚举类的所有枚举对象,以数组的形式返回

 

3 什么Stream流

  • jdk1.8提供的一个新特性

  • 与IO没有任何关系。

  • 是对集合数据操作的一个增强。 一般指的是数组, Set , List , Collection

  • Stream的使用需要配合lambda

4 Stream流分类

  • Stream中提供了很多流操作(一个一个的方法)

  • 流中的数据每经过一个方法(每经过一个流),就会对数据进行一些处理(过滤,排序,分组等)

  • 根据流的作用不同,分成2大类

    • 终端流 : 流数据经过终端流的处理,就完成了最终的处理,就不会再经过其他流处理了。

      在众多终端流中,流数据只会经过一个终端流

    • 过程流:流数据可以经过多个过程流,依次进行处理。

      每个过程流处理的都是上一个过程流处理后的结果

      在程序运行时,遇见过程流,不会立刻执行,只会提前做好准备

      直到遇见终端流,整个流操作才会开启。

  • 在数据流操作的过程中,不会对集合中的原始数据造成影响。

5 产生Stream流

通过集合直接获得对应的流

Stream<String> stream = list.stream();
Stream<String> stream = set.stream();

 通过数组获得对应的流

Stream<String> stream = Arrays.stream(names);

直接使用Streams工具产生流

Stream<String> stream2 = Stream.of("dongmingyu", "cuijunhe", "luzhipeng", "panshuai");
Stream<Integer> stream3 = Stream.iterate(1, (i) -> i += 2).limit(10);    

6 流的使用

6.1 终端流

foreach()

  • 循环遍历流中的每一个元素,对其进行消费,一般会配合输出打印

Stream<String> s = list.stream();
s.forEach( (name)->{
    System.out.println(name);
} );

s.forEach(System.out::println);

 

count()

  • 获得流中数据的数量

### count()

* 获得流中数据的数量

 

max() & min()

  • 获得流管道中最大或最小的数据。

  • 由于流中是对象数据,也就需要对象比较大小

  • 对象如何比较大小? 自身比较 或 比较器比较

Stream<String> s = list.stream();
Optional<String> max = s.max((name1, name2) -> name1.compareTo(name2) );
String name = max.get();
System.out.println(name);

 

  • 注意:返回的不直接是最终的结果,而是将其包装成了Optional对象

    可以通过调用Optional.get()获得最终的结果

collect()

  • 会将数据收集到一起,再做一些综合性的整理

  • 需要配合Collectors类,完成具体的收集操作

s.collect(Collectors.toSet());
s.collect(Collectors.toList());
s.collect(Collectors.toMap((v)->key? , (v)->value? ));
//使用流中数据的某一个属性进行求和统计
Integer r = s.collect(Collectors.summingInt((user) ->user.getSalary() ));
Double r = s.collect(Collectors.averagingInt((user) -> user.getSalary()));

 

//使用流中数据的某一个属性进行求和统计
Integer r = s.collect(Collectors.summingInt((user) ->user.getSalary() ));
Double r = s.collect(Collectors.averagingInt((user) -> user.getSalary()));

 

6.2 过程流

filter()

  • 对流中的数据进行过滤,复合条件的保留,不符合条件的被筛掉

  • filter中需要提供一个Predicted断言

Stream<Car> s = cars.stream();
s = s.filter(  car->car.getPrice() > 350000  ) ;
s.forEach(System.out::println);

 

map()

  • 重新处理流中的每一个数据,在原结构的基础上,构建新的结构

    对有n个属性的数据,可以重新设置其具有的属性(可以增加属性,可以减少属性,可以更换属性)

public static void main(String[] args) {
    String[] colors = new String[]{"red","green","blue","yellow","pink"};
    List< Map<String,String> > list = new ArrayList<>() ;
    for(int i=1;i<=10;i++){
        Map<String,String> car = new LinkedHashMap<>();
        car.put("cno",1000+i+"");
        car.put("cname","bmw"+i);
        int index = (int)(Math.random() * colors.length);
        car.put("color",colors[index]);
        car.put("price",150000 + (int)(Math.random()*300000) + "");

        list.add(car);
    }

    Stream<Map<String, String>> s = list.stream();
    //old代表流中的原始数据,当前是一个Map
    //对old数据处理后,返回一个新的结构的数据。不一定还是Map,可能是Car
    s = s.map( (old)->{
        String price = old.get("price");
        int _price = Integer.parseInt(price);
        if(_price < 200000){
            old.put("flag","便宜");
        }else if(_price < 400000){
            old.put("flag","一般");
        }else{
            old.put("flag","昂贵");
        }
        return old ;
    } ) ;

    s.forEach(System.out::println);

}

sorted()

  • 对容器中的元素进行排序。排序需要对象大小比较。比较需要自身比较或比较器

java
s = s.sorted( (car1,car2)-> {
    int price1 = Integer.parseInt(car1.get("price")) ;
    int price2 = Integer.parseInt( car2.get("price")) ;
    return price2 - price1 ;
});


 

skip() & limit()

  • 可以实现数据的分页处理

  • 假设有105条件,准备每页显示10条记录,请问需要多少页?11页

  • 第1页,显示哪10条? 前10条 ,从0开始,显示10条,也就是0~9条

  • 第2页,显示哪10条?从10开始,显示10条,也就是10~19条

  • 第3页,显示哪10条?从20开始,显示10条,也就是20~29条

  • 第n页,显示哪10条?从10n-10开始,显示10条,也就是10n-10~(10n-1)

//跳过6个数据,从下标为6的第7个数据开始,找3条记录。
s = s.skip(6).limit(3);

 

7 串行流和并行流

  • 串行流,就是使用单线程,一个数据一个数据的处理

    默认使用的就是串行流

  • 并行流,就是使用多线程,同时对各自的数据进行处理

    如何获得并行流?

public static void main(String[] args) {
    Stream<Integer> s = Stream.iterate(1, i -> ++i).limit(10);
    s = s.parallel();
    s.forEach(System.out::println);
}

 

标签:10,stream,Stream,对象,int,枚举,详解
From: https://blog.csdn.net/weixin_53755148/article/details/141804292

相关文章

  • 力扣237题详解:删除链表中的节点的模拟面试问答
    在本篇文章中,我们将详细解读力扣第237题“删除链表中的节点”。通过学习本篇文章,读者将掌握如何在单链表中删除给定的节点,并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释,以便于理解。问题描述力扣第237题“删除链表中的节点”描述如下:请编写一个函......
  • 力扣230题详解:二叉搜索树中第K小的元素的多种解法与模拟面试问答
    在本篇文章中,我们将详细解读力扣第230题“二叉搜索树中第K小的元素”。通过学习本篇文章,读者将掌握如何在二叉搜索树中高效地查找第K小的元素,并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释,以便于理解。问题描述力扣第230题“二叉搜索树中第K小的元素......
  • HelloWorld详解
    1:随便建立一个文件夹,用于存放代码2:新建一个java文件文件后缀名为.java文件为Hello.java【注意点】系统可能没有显示文件后缀名,需要手动打开3:用notepad++打开,并编写代码publicclassHello{ publicstaticvoidmain(String[]args){ System.out.print("Hello,World!")......
  • Transformer面试真题详解——覆盖99%的Transformer面试问题(建议收藏)
    文章目录1.请简述一下Transformer的基本结构和原理2.Transformer为什么使用多头注意力机制3.Transformer计算attention为什么选择点乘而不是加法?两个计算复杂度和效果上有什么区别?4.为什么在softmax之后要对attention进行scaled(为什么除以d_k的平方根)5.在计算attent......
  • 地平线—征程2(Journey 2-J2)芯片详解(32)—I2S+JTAG Interface Timing
    写在前面本系列文章主要讲解地平线征程2(Journey2-J2)芯片的相关知识,希望能帮助更多的同学认识和了解征程2(Journey2-J2)芯片。若有相关问题,欢迎评论沟通,共同进步。(*^▽^*)错过其他章节的同学可以电梯直达目录↓↓↓地平线—征程2(Journey2-J2)芯片详解——目录-CSDN博客1......
  • Linux目录详解
     一.树状目录结构图:二.树状目录结构介绍: 1./bin目录 /bin目录包含了引导启动所需的命令或普通用户可能用的命令(可能在引导启动后)。这些命令都是二进制文件的可执行程序(bin是binary--二进制的简称),多是系统中重要的系统文件。2./sbin目录 /sbin目......
  • 【Qt 事件】—— 详解Qt事件处理
    目录 (一)事件介绍 (二)事件的处理(三)按键事件 3.1 单个按键3.2组合按键(四)鼠标事件4.1鼠标单击事件4.2鼠标释放事件 4.3鼠标双击事件4.4鼠标移动事件 4.5滚轮事件 (五) 定时器5.1QTimerEvent类5.2QTimer类(六)事件分发器 6.1概述6.2事件分发器工作......
  • MVCC详解,深入浅出简单易懂
    转载自https://blog.csdn.net/lans_g/article/details/124232192一、什么是MVCC?mvcc,也就是多版本并发控制,是为了在读取数据时不加锁来提高读取效率和并发性的一种手段。数据库并发有以下几种场景:读-读:不存在任何问题。读-写:有线程安全问题,可能出现脏读、幻读、不可重复读......
  • 基于yolov10的学生课堂行为检测系统,支持图像检测,也支持视频和摄像实时检测(pytorch框架
       更多目标检测和图像分类识别项目可看我主页其他文章功能演示:基于yolov10的学生课堂行为检测系统,支持图像、视频和摄像实时检测【pytorch框架、python】_哔哩哔哩_bilibili(一)简介基于yolov10的学生课堂行为检测系统是在pytorch框架下实现的,这是一个完整的项目,包括代码......
  • nginx的location详解
    nginx的location详解属于nginx核心模块中的功能,nginx核心功能.location用于匹配用户请求中的uri的.root/app/code/www/www.oldboylinux.cn         uri:/        /app/code/www/首页文件.www.oldboylinux.cn/index.html   ......