Stream流

本文详细介绍了Java 8中的新特性Stream流,包括如何获取Stream流、中间操作和终止操作的使用,以及并行流与串行流的区别。通过实例展示了filter、distinct、limit、skip、map、sorted等方法的应用,以及reduce、collect等规约操作,还有查找、匹配、计数等常见操作。

JDK1.8新特性

Stream流

  1. 操作的是集合或者数组(容器中的元素)。

  2. 它的出现为了我们更方便的对集合的元素操作。

  3. 使用步骤

    • 获取stream流

      1. 创建集合,通过集合中的方法获取stream流。
      2. 创建数组,通过数组来获取流
      3. 通过Steram流中的静态方法of()获取.
    • 中间环节操作

      • 不会对原有集合改变,会得到新的流。

      • 对集合操作的方法

        1. 过滤方法:Filter(),
        2. 去掉重复:distinck()方法。此类需要重写hashcode()和equals()方法.
        3. 截取部分元素:Limit()
        4. 跳过几个元素:Skip()
        5. 提取集合中的元素,应用到一个方法上:
          • map(Function f)接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。【也就给定一个逻辑,每个元素应用这个逻辑,最后形成新的流存放这些元素】。
          • flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
          • mapToDouble(ToDoubleFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
          • mapToInt(ToIntFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。
          • mapToLong(ToLongFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。
        6. 排序:
          • sorted()产生一个新流,其中按自然顺序排序 元素实现Compareble接口
          • sorted(Comparator comp)产生一个新流,其中按比较器顺序排序 传入一个比较器
      • 注意: 终止操作不执行,中间环节就不会执行。体现的就是延迟加载的思想。

    • 终止操作

      1. 概念:就是将中间操作过程的流,进行终极操作,例如遍历,查找等等

      2. 查找与匹配:

        • allMatch(Predicate p)检查是否匹配所有元素 比如判断 所有员工的年龄都是17岁 如果有一个不是,就返回false
        • anyMatch(Predicate p)检查是否至少匹配一个元素 比如判断是否有姓王的员工,如果至少有一个就返回true
        • noneMatch(Predicate p)检查是否没有匹配所有元素 employee.getSalary() < 3000; 每个员工的工资如果都高于3000就返回true 如果有一个低于3000 就返回false
        • findFirst()返回第一个元素 比如获取工资最高的人 或者 获取工资最高的值是
        • findAny()返回当前流中的任意元素 比如随便获取一个姓王的员工
        • count()返回流中元素总数
        • max(Comparator c)返回流中最大值 比如:获取最大年龄值
        • min(Comparator c)返回流中最小值 比如:获取最小年龄的值
        • forEach(Consumer c)内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭代——它帮你把迭代做了)
      3. 规约:

        • reduce(T iden, BinaryOperator b) 参1 是起始值, 参2 二元运算,可以将流中元素累计结合起来,得到一个值。返回 T 。 比如: 求集合中元素的累加总和
        • reduce(BinaryOperator b) 这个方法没有起始值 可以将流中元素累计结合起来,得到一个值。返回 Optional , 比如你可以算所有员工工资的总和
      4. 收集:

        1. collect(Collector c)将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法

        2. Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。

          • List toList()把流中元素收集到List 比如把所有员工的名字通过map()方法提取出来之后,在放到List集合中去
            例子:List emps= list.stream().map(提取名字).collect(Collectors.toList());
          • Set toSet()把流中元素收集到Set 比如把所有员工的名字通过map()方法提取出来之后,在放到Set集合中去
            例子:Set emps= list.stream().collect(Collectors.toSet());
          • Collection toCollection()把流中元素收集到创建的集合 比如把所有员工的名字通过map()方法提取出来之后,在放到自己指定的集合中去
            例子:Collectionemps=list.stream().map(提取名字).collect(Collectors.toCollection(ArrayList::new));
          • Long counting()计算流中元素的个数
            例子:long count = list.stream().collect(Collectors.counting());
          • Integer summingInt()对流中元素的整数属性求和
            例子:inttotal=list.stream().collect(Collectors.summingInt(Employee::getSalary));
          • Double averagingInt()计算流中元素Integer属性的平均值
            例子:doubleavg=list.stream().collect(Collectors.averagingInt(Employee::getSalary));
          • String joining() 连接流中每个字符串 比如把所有人的名字提取出来,在通过"-“横杠拼接起来
            例子:String str= list.stream().map(Employee::getName).collect(Collectors.joining(”-"));
          • Optional maxBy() 根据比较器选择最大值 比如求最大工资
            例子:Optionalmax= list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary)));
          • Optional minBy() 根据比较器选择最小值 比如求最小工资
            例子:Optional min = list.stream().collect(Collectors.minBy(comparingInt(Employee::getSalary)));
          • 归约产生的类型 reducing() 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值
            例子:inttotal=list.stream().collect(Collectors.reducing(0, Employee::getSalar, Integer::sum));
          • 转换函数返回的类型 collectingAndThen() 包裹另一个收集器,对其结果转换函数
            例子:inthow= list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));
          • Map<K, List> groupingBy() 根据某属性值对流分组,属性为K,结果为V 比如按照 状态分组
            例子:Map<Emp.Status, List> map= list.stream().collect(Collectors.groupingBy(Employee::getStatus));
          • Map<Boolean, List> partitioningBy() 根据true或false进行分区 比如 工资大于等于6000的一个区,小于6000的一个区
            例子:Map<Boolean,List>vd= list.stream().collect(Collectors.partitioningBy(Employee::getSalary));
  4. 并行流与串行流
    并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
    Java 8 中将并行进行了优化,我们可以很容易的对数据进行并行操作。
    Stream API 可以声明性地通过 parallel() 与sequential() 在并行流与顺序流之间进行切换。

代码

package StreamAPI; 
 
/*Author:LH
CreatTime:2020.06.25.9:23*/

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

//给定一个数字列表,如何返回一个由每个数的平方构成的列表呢?,给定【1,2,3,4,5】, 应该返回【1,4,9,16,25】。

public class Test {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        Stream<Integer> stream = list.stream();

        IntStream intStream= stream.mapToInt(num -> (int) Math.pow(num, 2));
        intStream.forEach(num-> System.out.println(num));
    }
}
package StreamAPI;

public class Trader  {

   public Trader(String name, String city) {

      this.name = name;
      this.city = city;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getCity() {
      return city;
   }

   public void setCity(String city) {
      this.city = city;
   }

   private String name;  //交易员的姓名
   private String city;    //交易员工作的城市

   @Override
   public String toString() {
      return "Trader{" +
            "name='" + name + '\'' +
            ", city='" + city + '\'' +
            '}';
   }

}  //get set 方法省略了,自己补上
 class Transaction {

    private Trader trader;//交易员
    private int year;//年份
    private int value;//交易额

    public Transaction(Trader trader, int year, int value) {

       this.trader = trader;
       this.year = year;
       this.value = value;
    }

    public Trader getTrader() {
       return trader;
    }

    public void setTrader(Trader trader) {
       this.trader = trader;
    }

    public int getYear() {
       return year;
    }

    public void setYear(int year) {
       this.year = year;
    }

    public int getValue() {
       return value;
    }

    public void setValue(int value) {
       this.value = value;
    }

    @Override
    public String toString() {
       return "Transaction{" +
             "trader=" + trader +
             ", year=" + year +
             ", value=" + value +
             '}';
    }
     package StreamAPI; 
 
/*Author:LH
CreatTime:2020.06.25.15:18*/

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

/*
        1. 找出2011年发生的所有交易, 并按交易额排序(从低到高)
        2. 交易员都在哪些不同的城市工作过?
        3. 查找所有来自剑桥的交易员,并按姓名排序
        4. 返回所有交易员的姓名字符串,按字母顺序排序
        5. 有没有交易员是在米兰工作的?
        6. 打印生活在剑桥的交易员的所有交易额
        7. 所有交易中,最高的交易额是多少
        8. 找到交易额最小的交易*/
public class TraderTest {
    public static void main(String[] args) {
        Trader raoul = new Trader("Raoul", "Cambridge");
        Trader mario = new Trader("Mario", "Milan");
        Trader alan = new Trader("Alan", "Cambridge");
        Trader brian = new Trader("Brian", "Cambridge");

        List<Transaction> transactions = Arrays.asList(
                new Transaction(brian, 2011, 300),
                new Transaction(raoul, 2012, 1000),
                new Transaction(raoul, 2011, 400),
                new Transaction(mario, 2012, 710),
                new Transaction(mario, 2012, 700),
                new Transaction(alan, 2012, 950)
        );
//        找出2011年发生的所有交易, 并按交易额排序(从低到高)
        transactions.stream().filter(member -> member.getYear() == 2011).sorted(Comparator.comparingInt(Transaction::getValue)).forEach(System.out::println);
        System.out.println("===========");

//        交易员都在哪些不同的城市工作过?
        transactions.stream().map(member -> member.getTrader().getCity()).distinct().forEach(System.out::println);
        System.out.println("===========");

//        查找所有来自剑桥的交易员,并按姓名排序
        transactions.stream().filter(member -> member.getTrader().getCity().equals("Cambridge")).forEach(System.out::println);
        System.out.println("===========");
//        有没有交易员是在米兰工作的?
        long milan = transactions.stream().map(member -> member.getTrader().getCity().equals("Milan")).count();
        if (milan == 0) {
            System.out.println("没有在米兰工作的");
        } else {
            System.out.println("有在米兰工作的");
        }
        System.out.println("===========");
//        打印生活在剑桥的交易员的所有交易额
        Integer cambridge = transactions.stream().filter(member -> member.getTrader().getCity().equals("Cambridge")).map(num->num.getValue()).reduce(0, (a, b) -> a + b);
        System.out.println(cambridge);
        System.out.println("===========");
//        所有交易中,最高的交易额是多少
        Optional<Integer> first = transactions.stream().map(num -> num.getValue()).sorted((a, b) -> b - a).findFirst();
        System.out.println(first);

//        找到交易额最小的交易
        Optional<Transaction> first1 = transactions.stream().sorted((a, b) -> a.getValue() - b.getValue()).findFirst();
        System.out.println(first1);


    }

}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值