java 8 新特性(二) stream API

java 8 新特性(二) stream API

 

stram的三个操作 :

  1. 创建stram

  2. 中间操作

  3. 终止操作(终端操作)

 

一、创建stream的几种方式:

// 第一种: 可以通过Collection 系列集合提供的 stream() 或 parallelStream()
        Map<String,Object> map = new HashMap<>();
        employees.stream(); // 串行流
        employees.parallelStream(); // 并行流
        System.out.println("--------------------------------------------------------------");
​
        // 第二种. 通过 Arrays 中静态方法 stream() 获取数组流
        Integer[] array = new Integer[10];
        Stream<Integer> stream = Arrays.stream(array);
​
        System.out.println("--------------------------------------------------------------");
​
        // 第三种: 通过stream() 类中的静态方法 of()
        Stream<String> stream3 = Stream.of("aa","bb","cc");
​
        // 第四种: 创建无限流(无穷尽) 迭代
        /**
         *  iterate:
         *   该方法实现了 函数式接口
         *   @FunctionalInterface
         *   public interface UnaryOperator<T> extends Function<T, T> {}
         *
         *   三个步骤的体现:(基本上stream的操作都会存在该三步)
         *   Stream.iterate(9,x->x+2).limit(10).forEach(System.out::println);
         *   Stream.iterate(9,x->x+2) : 开始
         *   .limit(10): 中间操作
         *   .forEach(System.out::println): 终止操作
         */
//        Stream.iterate(9,x->x+2).forEach(System.out::println);
​
        Stream.iterate(9,x->x+2).limit(10).forEach(System.out::println);
​
​
​
结果:
--------------------------------------------------------------
--------------------------------------------------------------
9
11
13
15
17
19
21
23
25
27

二、stream 的中间操作的方法API:

 

测试数据:

 public static List<Employee> employees = Arrays.asList(
            new Employee("张三",18,1111.00),
            new Employee("李四",28,2222.00),
            new Employee("王五",38,3333.00),
            new Employee("赵六",48,4444.00),
            new Employee("候七",58,5555.00)
    );

 

(筛选与切片)

  • filter 在流中排除某些元素

  • distinct 筛选 通过 hashCode 与 equals 去重

  • limit 截断 使元素不超过给定的数量

    System.out.println("--------------------------------------------------------------");
    // 中间操作 filter  中间操作后面必须要有终止操作,若没有终止操作  中间操作的流没有任何结果的
    employees.stream().filter(x -> x.getAge() >35).forEach(System.out::println);
    System.out.println("--------------------------------------------------------------");
    /**
     * 惰性求值:
     *      就是多个中间操作可以连接起来行成一个流水线,除非流水线上触发了终止操作,
     *      否则中间操作不会执行任务的处理,而在终止操作时一次性全部执行
     * 内部迭代: 迭代操作时有stream api完成
     * 外部迭代: 自己通过迭代语句执行
     */
    ​
    结果: 
    --------------------------------------------------------------
    Employee{name='王五', age=38, salary=3333.0}
    Employee{name='赵六', age=48, salary=4444.0}
    Employee{name='候七', age=58, salary=5555.0}
    --------------------------------------------------------------

     

  • skip 跳过元素 返回一个扔掉了钱n个元素的流 若流中元素不足n个, 则返回一个空流 与limit() 互补

    // .skip(2) 跳过两条数据 取第三条数据
    employees.stream().filter(x->x.getAge()>35).skip(2).forEach(System.out::println);    
    结果: 
    Employee{name='候七', age=58, salary=5555.0}

     

(映射)

  • map 接收一个函数为参数 该函数会被应用到每个元素上,并将其映射成新的一个元素

    List<String> strings = Arrays.asList("aa", "bb", "cc", "dd");
    strings.stream().map(str->str.toUpperCase()).forEach(System.out::println);
    ​
    结果:
    AA
    BB
    CC
    DD      

     

    采用语法糖的方式:

    // 类名::方法名  这是java的语法糖
    strings.stream().map(StramAPI01::filterCharacter)
    .forEach(x->x.forEach(System.out::println));
    ​
    private static Stream<Character> filterCharacter(String str){
        List<Character> list = new ArrayList<>();
        for (Character ch: str.toCharArray()){
            list.add(ch);
        }
        return list.stream();
    }
    ​
    ​
    结果:
    a
    a
    b
    b
    c
    c
    d
    d

     

  • mpaToDouble 接收一个函数为参数 该函数会被应用到每个元素上,并将其映射成新的一个DoubleStream

  • mapTOInt 接收一个函数为参数 该函数会被应用到每个元素上,并将其映射成新的一个intStream

  • mapToLong 接收一个函数为参数 该函数会被应用到每个元素上,并将其映射成新的一个longStream

  • flatMap 接收一个函数为参数 将流中的每个值都换成另一流 然后把所有的流连成一个流程

    以上采用  采用语法糖的方式 的简化 采用 flatMap 可以实现
    ​
    strings.stream().flatMap(StramAPI01::filterCharacter).forEach(System.out::println);
    ​
    结果:
    a
    a
    b
    b
    c
    c
    d
    d

    flatMap 与 map的区别

    举例说明:

    有二箱鸡蛋,每箱5个,现在要把鸡蛋加工成煎蛋,然后分给学生。

    map做的事情:把二箱鸡蛋分别加工成煎蛋,还是放成原来的两箱,分给2组学生;

    flatMap做的事情:把二箱鸡蛋分别加工成煎蛋,然后放到一起【10个煎蛋】,分给10个学生;

     

 

(排序)

  • sorted() 产生一个新流 其中按自然顺序排序

  • sorted(Comparator comp) 产生一个新流 其中按比较器顺序排序

    List<String> strings = Arrays.asList("ee","aa", "bb", "cc", "dd");
    strings.stream().sorted().forEach(System.out::println);
    ​
    结果:
    aa
    bb
    cc
    dd
    ee
    ​
    -- 带参数的排序  按照年龄来排序
    employees.stream().sorted((x1,x2)-> x1.getAge().compareTo(x2.getAge())).forEach(System.out::println);
    ​
    结果:
    Employee{name='张三', age=18, salary=1111.0}
    Employee{name='李四', age=28, salary=2222.0}
    Employee{name='李四1', age=29, salary=2233.0}
    Employee{name='王五', age=38, salary=3333.0}
    Employee{name='赵六', age=48, salary=4444.0}
    Employee{name='候七', age=58, salary=5555.0}

     

三 、stream 的终止操作的方法API:

(查找与匹配)

  • allMath 检查是否匹配所有元素

boolean b1 = empLists.stream().allMatch(x->x.getAge().equals(18));
System.out.println("b1=="+ b1);

结果:
b1==false
  • anyMath 检查是否至少匹配一个元素

boolean b2 = empLists.stream().anyMath(x->x.getAge().equals(18));
System.out.println("b2=="+ b2);
结果:
b2==true
  • noneMath 检查是否有匹配的所有与元素

boolean b3 = empLists.stream().noneMath(x->x.getAge().equals(18));
System.out.println("noneMath b3=="+ b3);
结果:
noneMath b3==false
  • findFirst 返回第一个元素

Optional<Employee> em1 = empLists.stream().findFirst();
System.out.println("findFirst em1=="+ em1);

结果:
findFirst em1==Optional[Employee{name='张三', age=18, salary=1111.0}]

 

  • findAny 返回当前流中的任意元素

Optional<Employee> o1 = empLists.stream().findAny();
System.out.println("findAny 01=="+ o1);

结果:
findAny 01==Optional[Employee{name='张三', age=18, salary=1111.0}]
  • count

long count = empLists.stream().count();
System.out.println("count == "+ count);

结果:
count == 6

 

  • max min

Optional<Employee> max = empLists.stream()
					.max((x1,x2)->Integer.compare(x1.getAge(),x2.getAge()));
System.out.println("max==="+ max);
Optional<Employee> min = empLists.stream()
 							.min((x1,x2)->Integer.compare(x1.getAge(),x2.getAge()));
System.out.println("min==="+ min);


结果:
max===Optional[Employee{name='候七', age=58, salary=5555.0}]
min===Optional[Employee{name='张三', age=18, salary=1111.0}]

 

四、归约与收集 reduce 与 collect

  • reduce

System.out.println("--------------------------------------------------------------");

List<Integer> list = Arrays.asList(1, 2, 4, 5, 6, 7, 3, 56, 10);
Integer sum = list.stream().reduce(0,(x,y)->x+y);  // sum==94
System.out.println("sum=="+ sum);

System.out.println("--------------------------------------------------------------");
Integer sum1 = list.stream().reduce(1,(x,y)->x+y);  // sum==95
System.out.println("sum1=="+ sum1);

System.out.println("--------------------------------------------------------------");
// 计算员工的工资总和
Optional<Double> sum2 = employees.stream().map(Employee::getSalary)
						.reduce(Double::sum); // sum2===18898.0
System.out.println("sum2==="+ sum2.get());

备注:map 和 reduce 的连接通常称为 map-reduce 模式 ,因 Google 用它来进行网络搜索而出名

 

  • collect

// collect 收集器
// 案例1: 收集集合中的名字 
List<String> nameList1 = employees.stream()
    .map(Employee::getName)  // 取出Employee中的员工名字
    // Collectors : 计算集合的工具类
    .collect(Collectors.toList());
System.out.println("nameList1 == "+ nameList1); 
// nameList1 == [张三, 李四, 王五, 李四1, 赵六, 候七]


// 案例2:获取员工工资的平均值
Double d = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
 System.out.println("d ===="+ d); // d ====3149.6666666666665
 
 
 //案例3:  分组  将集合List<Map>转换成map<key,List<Map>>类型
 
Map<Employee.Status,List<Employee>> map =
         empLists.stream().collect(Collectors.groupingBy(Employee::getStatus));
System.out.println("map =="+ map);

// map =={
// VOCATION=[Employee{name='李四', age=28, salary=2222.0}, 
// Employee{name='候七', age=58, salary=5555.0}], 
// BUSY=[Employee{name='张三', age=18, salary=1111.0}, Employee{name='李四1', age=29, salary=2233.0}], 
// FREE=[Employee{name='王五', age=38, salary=3333.0}, Employee{name='赵六', age=48, salary=4444.0}]}


// Map<String,Map<String,List<Employee>> 类型
Map<Employee.Status, Map<String, List<Employee>>> map1 = empLists.stream()
    .collect((
        Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(
            e -> {
                if (((Employee) e).getAge() <= 35) {
                    return "青年";
                } else if (((Employee) e).getAge() <= 50) {
                    return "中年";
                } else {
                    return "老年";
                }
            }
        ))
    ));

// 结果: 
map1 == {VOCATION={青年=[Employee{name='李四', age=28, salary=2222.0}], 老年=[Employee{name='候七', age=58, salary=5555.0}]}, BUSY={青年=[Employee{name='张三', age=18, salary=1111.0}, Employee{name='李四1', age=29, salary=2233.0}]}, FREE={中年=[Employee{name='王五', age=38, salary=3333.0}, Employee{name='赵六', age=48, salary=4444.0}]}}

五、并行流 与 串行流

 

 

 

Optional

Optional 容器类的常用方法

  • Optional .of(T t) 创建一个一个Optional

  • Optional.empty() 创建一个空的Optional 实例

  • Optional.ofNullable(T t) 若t为null 创建Optional实例,否则创建空实例

  • Optional.isPresent() 判断是否包含值

  • Optional.orElse(T t) 如果调用对象包含值,返回该值,否则返回t

  • Optional.orElseGet(Supplier s) 如果调用对象包含值,返回改值,否则返回s 获取的值

  • Optional.,map(Function f) 如果值对其处理,并返回处理后的Optional 否则返回Optional.empty()

  • Optional.flatMap(Function mapper) 与map类似,要求返回值必须是Optional

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值