Java8新特性之Stream

1. Stream

什么是 Stream?
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列
“集合讲的是数据,流讲的是计算!”

注意:
① Stream自己不会存储元素。
② Stream不会改变源对象。相反,他们会返回一个持有结果的新 Stream。
③ Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Stream的操作三个步骤
创建 Stream
一个数据源(如:集合、数组),获取一个流
中间操作
一个中间操作链,对数据源的数据进行处理
终止操作(终端操作)
一个终止操作,执行中间操作链,并产生结果

1.创建 Strean

Java8中的 Collection接口被扩展,提供了两个获取流的方法:
default Stream stream():返回一个顺序流
default Stream〈E〉 parallelstream():返回一个并行流

1.由数组创建流

Java8中的 Arrays的静态方法 stream()可以获取数组流:

  static<T> Stream<T> stream(T[] array):返回一个流

重载形式,能够处理对应基本类型的数组:

 public static IntStream stream(int[] array )
 public static LongStream stream(long[] array)
 public static DoubleStream stream(doublel array)
2.由值创建流

可以使用静态方法 Stream.of(),通过显示值创建一个流。它可以接收任意数量的参数。
public static<T〉 Stream〈T>of(T… values):返回一个流

3.由函数创建流:创建无限流

可以使用静态方法 Stream. Iterate()和Stream. generate(),创建无限流。

//迭代
public static<T> Stream<T> iterate(final T seed, final Unaryoperator<T> f )
//生成
public static<T> Stream<T> generate(Supplier<T> s)

2.Stream的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理! 而在终止操作时一次性全部处理,称为“惰性求值”

[] 内为另一种解释

(一)筛选与切片
1、filter(): 返回结果生成新的流中只包含满足筛选条件的数据。[接收 Lambda,从流中排除某些元素]
// 1、filter,返回大于2的元素集合
    List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
    List<Integer> result = nums.stream().filter(n -> n > 2).collect(Collectors.toList());
    System.out.println(result);

运行结果:[3, 4, 5]

2、 limit():顾名思义,返回指定数量的元素的流。返回的是Stream里前面的n个元素。[截断流,使其元素不超过给定数量。]
//筛选出员工集合中薪资大于5000的前5个人
emps.stream()
      .filter(e -> e.getSalary()>5000)
      .limit(5)
      .forEach(System.out::println);
3、 skip():和limit()相反,将前几个元素跳过(取出)再返回一个流,如果流中的元素小于或者等于n,就会返回一个空的流。[跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补]
emps.parallelStream()
   .filter((e) -> e.getSalary() >= 5000)
   .skip(2)
   .forEach(System.out::println);
4、distinct():顾名思义,将流中的元素去重之后输出。[筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素]
List<String> mzc = Stream.of("ma","zhi","chu","zhi","shuo","ma")
        .distinct()
        .collect(Collectors.toList());
System.out.println(mzc);

运行结果:[ma, zhi, chu, shuo]

(二)映射
1、map():将流中的元素进行再次加工形成一个新流,流中的每一个元素映射为另外的元素。[接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素]
//打印出大写字母
List<String> mzc = Arrays.asList("ma", "zhi", "chu");
mzc.stream().map(e -> e.toUpperCase()).forEach(System.out::println);
伪代码取出员工ID:
List<Employee> emps = employeeService.getAllEmployee();
List<Integer> ids = emps.stream().map(Employee::getId).collect(Collectors.toList());
List<Integer> ids2 = emps.stream().map(e -> e.getId()).collect(Collectors.toList());
System.out.println(ids);
System.out.println(ids2);
2、flatMap():扁平化映射,它具体的操作是将多个stream连接成一个stream,这个操作是针对类似多维数组的,比如集合里面包含集合,相当于降维作用。[接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流]{与map关系类似于List中 add&addAll}
Stream<Character> stream3 = strList.stream()
      .flatMap(TestStreamAPI1::filterCharacter);
stream3.forEach(System.out::println);
(三)排序
1.sorted():这个很简单了,顾名思义,将流中的元素按照自然排序方式进行排序。[产生一个新流,其中按自然顺序排序]
emps.stream()
         .map(Employee::getName)
//          .map(Employee::getSalary)
         .sorted()
         .forEach(System.out::println);
      
      System.out.println("------------------------------------");
      //按年龄排序,年龄相同的按姓名排序
      emps.stream()
         .sorted((x, y) -> {
            if(x.getAge() == y.getAge()){
               return x.getName().compareTo(y.getName());
            }else{
               return Integer.compare(x.getAge(), y.getAge());
            }
         }).forEach(System.out::println);

3.Stream的终止操作

(一) 查找与匹配
1. allMatch ——检查是否匹配所有元素 [Stream 中所有元素都符合传入的断言时返回 true,否则返回false,流为空时总是返回true。]
// allMatch():判断流中元素是否都符合断言条件
List<Integer> ints = Arrays.asList(1,2,3,4,5);
boolean c = ints.stream().allMatch(l -> l > 0);
boolean c1 = ints.stream().allMatch(l -> l > 1);
System.out.println(c);
System.out.println(c1);
// allMatch():判断流中元素是否都符合断言条件,如果流为空,永远返回true
List<Integer> emptyList = new ArrayList<>();
boolean c2 = emptyList.stream().allMatch(e -> e > 1);
System.out.println(c2);

运行结果:true false true

2. anyMatch——检查是否至少匹配一个元素[Stream 中只要有一个元素符合传入的断言,就返回 true,否则返回false。]
//判断流中数据是否有一个复合断言,如果流为空,永远返回false
List<Integer> inss = Arrays.asList();
boolean b2 = inss.stream().anyMatch(l -> l > 2);
System.out.println(b2);
3. noneMatch——检查是否没有匹配的元素[Stream 中所有元素都不满足传入的断言时返回 true,否则返回false。]
// noneMatch():判断流中元素是否都不符合传入的断言条件
List<Integer> numList = Arrays.asList(1,2,3,4,5);
boolean d = numList.stream().noneMatch(l -> l > 6);
boolean d1 = numList.stream().noneMatch(l -> l > 1);
System.out.println(d);
System.out.println(d1);
// noneMatch():判断流中元素是否都不符合传入的断言条件,流为空时永远返回true
List<Integer> numist = Arrays.asList();
boolean d2 = numist.stream().noneMatch(l -> l > 6);
System.out.println(d2);

运行结果:true false true

4. findFirst ——返回第一个元素[总是返回流中的第一个元素,如果流为空,返回一个空的Optional.]
//查询出薪水最高的员工信息
Optional<Employee> op = emps.stream()
   .sorted((e1, e2) -> -Double.compare(e1.getSalary(), e2.getSalary()))
   .findFirst();
System.out.println(op.get());
5. findAny——返回当前流中的任意元素[返回流中的任意一个元素即可,如果流为空,返回一个空的Optional.]
//查询出状态为free的员工
Optional<Employee> op2 = emps.parallelStream()
   .filter((e) -> e.getStatus().equals(Status.FREE))
   .findAny();
System.out.println(op2.get());
6. count——返回流中元素的总个数[返回流中元素的数量]
// count():返回流中元素的数量
List<Integer> ls = Arrays.asList(1,2,3,4,5);
long count = ls.stream().count();
long count1 = ls.stream().filter(l -> l > 2).count();
System.out.println(count);
System.out.println(count1);

运行结果:5 3

7. max——返回流中最大值
//示例一 返回工资最高的员工
Optional<Double> op = emps.stream()
   .map(Employee::getSalary)
   .max(Double::compare);
System.out.println(op.get());

//示例二 
// max():返回流中的最大值
 List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer maxNum = num.stream().max(Integer::compareTo).get();
Integer max = num.stream().max(Comparator.comparing(Function.identity())).get();
System.out.println(maxNum);
System.out.println(max);

运行结果:6 6

8. min——返回流中最小值
// min():返回流中的最小值
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer minNum = nums.stream().min(Integer::compareTo).get();
Integer min = nums.stream().min((x,y) -> x.compareTo(y)).get();
System.out.println(minNum);
System.out.println(min);

运行结果:1 1

(二) 规约
1. reduce(T identity, BinaryOperator) / reduce(BinaryOperator) ——可以将流中元素反复结合起来,得到一个值。[这个方法的主要作用是把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce。]
// reduce():字符串拼接
String reduceStr1 = Stream.of("ma", "zhi", "chu").reduce("", String::concat);
String reduceStr2 = Stream.of("ma", "zhi", "chu").reduce("", (x,y)->x+y);
System.out.println(reduceStr1);
System.out.println(reduceStr2);
// reduce():求和,identity(起始值)为0
Integer total1 = Stream.of(1,2,3,4).reduce(0, Integer::sum);
Integer total2 = Stream.of(1,2,3,4).reduce(0, (x, y) -> x +y);
System.out.println(total1);
System.out.println(total2);
// 求和,sumValue = 10, 无起始值
Integer total3 = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
System.out.println(total3);
// reduce():求最小值
double minValue = Stream.of(-1.1, 8.8, -2.2, -6.6).reduce(Double.MAX_VALUE, Double::min);
System.out.println(minValue);

运行结果:
mazhichu
mazhichu
10
10
10
-6.6

(三)收集
1. collect-将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法.[是Stream的一个函数,负责收集流。前面我们说中间操作是将一个流转换成另一个流,这些操作是不消耗流的,但是终端操作会消耗流,产生一个最终结果,collect()就是一个规约操作,将流中的结果汇总。结果是由传入collect()中的Collector定义的。]
// 从员工集合中,获取名字并打印
emps.stream()
.map(Employee::getName)
.collect(Collectors.toList()).forEach(System.out::println);

java8 Lambda表达式

本文参考
https://www.cnblogs.com/mazhichu/p/11983451.html 等

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值