Stream流

作者: hcq0514 | 来源:发表于2019-01-28 17:56 被阅读0次

几个后面会用到的类

  • 实体类Dish
public class Dish {
    private Integer id;
    private String name;
    private boolean isVegetarian;
//省略get,set等
}

Filter

该操作会接受一个条件作为参数,并返回一个包含所有符合该条件的流.

  • 实体Dish有个属性isVegetarian,筛选出所有素菜,并创建一张素食菜单,并输出
        dishes.stream()
                .filter(Dish::isVegetarian)  //过滤掉所有非素菜的
                .collect(toList()) //把过滤后的Dish转换为数组
                .forEach(System.out::println); //输出
  • distinct()方法,去掉重复的元素
    筛选出列表中所有的偶数,并确保没有重复。
        Stream.of(1, 2, 3, 4, 5, 7, 9, 5, 14, 1, 2, 3, 4, 6)
                .filter(x -> x % 2 == 0) 
                .distinct() //去重
                .forEach(System.out::println);
  • limit限制查询多少个元素 ,skip为跳过多少元素 略过

Sorted 排序

  • int数组排序(Integer1.8后多了一个compare方法可以用来排序,基础类型sorted里面不写也可以排)
       numbers.stream()
             .sorted(Integer::compare)
             .collect(Collectors.toList())
             .forEach(System.out::println);
  • 根据Id来排序(两种方法)
        dishes.stream()
                .sorted((x, y) -> x.getId())
                .collect(toList())
                .forEach(System.out::println);

        dishes.stream()
                .sorted(Comparator.comparing(Dish::getId))
                .collect(toList())
                .forEach(System.out::println);
  • 根据Id逆序排序 (reversed() 函数)
        dishes.stream()
                .sorted(Comparator.comparing(Dish::getId).reversed())
                .collect(toList())
                .forEach(System.out::println);

Map

  • 取到所有菜的名称长度
        dishes.stream()
                .map(Dish::getName) //取到所有菜的名称
                .map(String::length)//这边的map处理的是上一个map输出的值,因为上一个Map返回的是String,所有这边用String,其他类型同理,不一样会报错,
                .forEach(System.out::println);
    

查找和匹配

查看数据集中的某些元素是否匹配一个给定的值。
Stream API通过 allMatch 、 anyMatch 、 noneMatch 、 findFirst 和 findAny 方法提供了这样的工具

  • allMatch 所有值都匹配
  • anyMatch 只要匹配到一个就可以
  • noneMatch 没有匹配到
  • findFirst 找到第一个值
  • findAny 跟findFirst差不多,都是找到就返回
 public void test4() {
        boolean hasVegetarian = dishes.stream()
                .anyMatch(Dish::isVegetarian);
        System.out.println(hasVegetarian);

        Optional<Dish> first = dishes.stream() //optional
                .filter(dish -> !dish.isVegetarian())
                .findFirst();
        System.out.println(first);
    }

Reduce

  • Reduce求和
   public  void  test5(){
        //以前的写法
        int sum = 0;
        for (int x : numbers) {
            sum += x;
        }
        System.out.println(sum);

        //reduce写法
        Integer reduce1 = numbers.stream().reduce(0, (a, b) -> a + b);
        System.out.println(reduce1);

        //Integer等方法已经有现成的sum方法
        Integer reduce2 = numbers.stream().reduce(0, Integer::sum);
        System.out.println(reduce2);

        //无初始值------?
        Optional<Integer> reduce3 = numbers.stream().reduce(Integer::sum);
        System.out.println(reduce3);
    }
  • Reduce求最大值
    public  void test6(){
        Optional<Integer> reduce = numbers.stream().reduce(Integer::max);
        boolean present = reduce.isPresent();
        if (present) {
            System.out.println(reduce.get());
        }
    }

Optional类简单介绍

Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。

  • 构建源码
正常构建
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
空值构建
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
  • 常用方法 isPresent(),get()
    Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
    public boolean isPresent() {
        return value != null;
    }

    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }
  • 上面的isPresent(),get()方法可以用ifPresent代替,后面是个Lamada表达式,当存在值时执行后面的方法
源码
  public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
   }
例子:如果val存在,则输出,为空时不输出
val.ifPresent((value)-> System.out.println("the val is "+value));
相当于
  if (val.isPresent()) {
        System.out.println("the val is " + val.get());
    }

练习

public class TradeTest {
    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)
    );

    //(1) 找出2012年发生的所有交易,并按交易额排序(从低到高)。
    @Test
    public void test1(){
        transactions.stream()
                .filter(transaction -> transaction.getYear() == 2012)
                .sorted(Comparator.comparing(Transaction::getValue))
                .collect(Collectors.toList())
                .forEach(System.out::println);
    }

    //(2) 交易员都在哪些不同的城市工作过?
    @Test
    public void test2(){
        transactions.stream()
                .map(Transaction::getTrader)
                .map(Trader::getCity)
                .distinct()
                .forEach(System.out::println);
    }

    //(3) 查找所有来自于Cambridge的交易员,并按姓名排序。
    @Test
    public void test3(){
        transactions.stream()
                .map(Transaction::getTrader)//获取全部交易员
                .filter(trader -> trader.getCity().equals("Cambridge"))//筛选出是Cambridge的交易员
                .sorted(Comparator.comparing(Trader::getName))//按名字排序
                .forEach(System.out::println);
    }

    //(4) 返回所有交易员的姓名字符串,按字母顺序排序。
    @Test
    public void test4(){
       transactions.stream()
                .map(Transaction::getTrader)//获取全部交易员
                .map(Trader::getName)
                .sorted()
                .forEach(System.out::println);
    }

    //(5) 有没有交易员是在Milan工作的?
    @Test
    public void test5(){
        transactions.stream()
                .map(Transaction::getTrader)//获取全部交易员
                .filter(trader -> trader.getCity().equals("Milan"))
                .distinct()
                .forEach(System.out::println);
    }

    //(6) 打印生活在Cambridge的交易员的所有交易额,。
    @Test
    public void test6(){
        Optional<Integer> cambridgeSumTractionValue = transactions.stream()
                .filter(transaction -> transaction.getTrader().getCity().equals("Cambridge"))
                .map(Transaction::getValue)
                .reduce(Integer::sum);
        cambridgeSumTractionValue.ifPresent(val-> System.out.println("cambridgeSumTractionValue is "+val));
    }

    // (7) 所有交易中,最高的交易额是多少?
    @Test
    public void test7(){
        Optional<Integer> maxTractionValue = transactions.stream()
                .map(Transaction::getValue)
                .max(Integer::compare);
        maxTractionValue.ifPresent((value)-> System.out.println("the maxTractionValue is "+value));
    }

    //(8) 找到交易额最小的交易。
    @Test
    public void test8(){
        Optional<Integer> minTractionValue = transactions.stream()
                .map(Transaction::getValue)
                .min(Integer::compare);
        minTractionValue.ifPresent((value)-> System.out.println("the minTractionValue is "+value));
    }

    //(9) 计算交易总额
    @Test
    public void test9(){
        Optional<Integer> sumTractionValue = transactions.stream()
                .map(Transaction::getValue)
                .reduce(Integer::sum);
        sumTractionValue.ifPresent((value)-> System.out.println("the sumTractionValue is "+value));
    }
}

平时碰到的问题

//1.1需要取得数组实体里面的所有的downbound<0的groupId,并用于sql查询
StringBuffer stringBuffer =new StringBuffer();
        String preGroupIds = null;
        collectionStageService.getCollectionStages().stream()
                .filter(collectionStageDomain -> collectionStageDomain.getDownbound() < 0)
                .map(CollectionStageDomain::getGroupId)
                .forEach(x-> stringBuffer.append(x).append(","));

        preGroupIds= stringBuffer.substring(0,stringBuffer.length()-1);

//1.2如果只是为了记日志,则可以直接转list 然后日志里面直接输出collect数组
   List<Long> collect = collectionStageDomains.stream()
                .filter(collectionStageDomain -> collectionStageDomain.getDownbound() < 0)
                .map(CollectionStageDomain::getGroupId)
                .collect(Collectors.toList());

相关文章

  • JDK8新特性之Stream流

    是什么是Stream流 java.util.stream.Stream Stream流和传统的IO流,它们都叫流,...

  • 2020-07-04【Stream流】

    体验Stream流 Stream流的生成方式 Stream流的常见中间操作 Stream流的常见终结操作 Stre...

  • JavaStream流基础学习

    Stream流 Straem流使用 使用Sream流: 一行搞定 1.2 Stream流生成方式 Stream流的...

  • 2019-02-02——Java8 Stream

    Stream分为两种: 串行流——stream() 并行流——parallelStream() Stream的特性...

  • Stream流

    流式思想 Stream流的简单尝试 传统for循环遍历的方法 Steam流的方式 获取stream流 stream...

  • Stream流

    一、创建流 Arrays.stream Stream.of Collection.stream Stream.it...

  • 13.Stream流、方法引用

    主要内容 Stream流 方法引用 第一章 Stream流 说到Stream便容易想到I/O Stream,而实际...

  • Stream流

    体验Stream Stream流生产方式生成流list.stream()中间操作filter()终结操作forEa...

  • Stream操作

    1、创建Stream流 2、stream和parallelStream的简单区别 stream是顺序流,由主线程按...

  • 2020-07-20Stream流

    Stream流的生成方式 stream流的使用 生成流通过数据源(集合,数组等)生成流list.stream() ...

网友评论

      本文标题:Stream流

      本文链接:https://www.haomeiwen.com/subject/wmoajqtx.html