枚举与stream流详解

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);
}

 

  • 19
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值