美文网首页
jdk8 list stream的使用

jdk8 list stream的使用

作者: zycisbg | 来源:发表于2018-12-18 17:53 被阅读0次

平时写代码的时候,经常会对list进行操作,自从1.8之后有了stream 。能使用的话,就经常使用了,现在在这归总一下经常使用的几个stream的API。

为了方便下边理解,创建两个实体类和一个list

/**
 * 交易实体类
 */
public class Transaction {
    //id
    private Integer id;
    //货币
    private Currency currency;
    //金额
    private Double money;
    //-------省略  getter和setter--------
}

/**
 * 货币
 */
public class Currency {
    private Integer id;
    private String name;
  //-------省略  getter和setter--------
}


//----------------------init-----------------------
 List<Transaction> transactions = Arrays.asList(new Transaction(1,new Currency(1,"人民币"),22.22),
            new Transaction(2,new Currency(2,"美元"),30.21),
            new Transaction(3,new Currency(2,"美元"),29.22),
            new Transaction(4,new Currency(2,"美元"),18.22),
            new Transaction(5,new Currency(1,"人民币"),15.5));
  • stream filter
    • filter 过滤 筛选
    • filter 中传参的是 Predicate
    • Predicate这个接口是一个函数型接口,
    • 该接口通俗理解的话,是为了支持lambda而生的,1.8之后才有。
    • jdk提供的简单来说只有三个函数型接口:
    • Predicate:返回boolean
    • Consumer:没有返回值
    • Function:返回一个对象类型
    • 玩lambda,一定要记住这三个接口。
    @Test
    public void test1(){
        //转换成一个新的list
        List<Transaction> filterList = transactions.stream().filter(t -> t.getMoney() > 20).collect(Collectors.toList());
        //满足条件的循环处理
        transactions.stream().filter(t -> t.getMoney() > 20).forEach(System.out::println);
    }
  • stream groupingBy
    • groupingBy 分组
    • groupingBy 中无论是传 Transaction::getCurrency 还是 t->t.getCurrency() 都是根据currency来分组的意思, 这样能得到一个
    • key为currency value 为 transaction 的map。(分组需要 equals和hashCode 都相等才能分为一组)
    @Test
    public void test2(){
        Map<Currency, List<Transaction>> currencyListMap = transactions.stream().collect(Collectors.groupingBy(Transaction::getCurrency));
        Map<Currency, List<Transaction>> currencyListMap1 = transactions.stream().collect(Collectors.groupingBy(t->t.getCurrency()));
    }
  • stream distinct
    • distinct:去重,
    • 同理 只有引用对象的 equals&&hashCode 都相等时 才去重。
    @Test
    public void test3(){
        transactions.stream().filter(t -> t.getMoney()>20)
                .distinct()
                .forEach(System.out::println);
    }
  • stream limit和skip

    • limit 与 skip 互补,一个是从前截断,一个是跳过前边
    @Test
    public void test4(){
        transactions.stream()
                .limit(2)
                .forEach(System.out::println);
        transactions.stream()
                .skip(2)
                .forEach(System.out::println);

    }
  • stream map
    • map 方法,改变一个类型
   @Test
   public void test5(){
       List<Currency> collect = transactions.stream()
               .map(Transaction::getCurrency)
               .collect(toList());

       collect.forEach(System.out::println);

       transactions.stream()
               .map(Transaction::getMoney)
               .forEach(System.out::println);
   }
  • stream match

    • allMatch:是否全部匹配
    • anyMatch:是否最少有一个匹配
    • noneMatch:是否全部都不匹配
    @Test
    public void test6(){
        boolean b = transactions.stream()
                .allMatch(t -> t.getMoney()<20);
        System.out.println(b);

        boolean b1 = transactions.stream()
                .anyMatch(t -> t.getMoney() < 20);
        System.out.println(b1);

        boolean b2 = transactions.stream()
                .noneMatch(t -> t.getMoney() < 20);

        System.out.println(b2);
    }
  • stream findFirst

    • findFirst:返回第一个元素 optional类型
    • findAny:返回一个元素
    • 区别在于 findAny在并行上做的更好。
    @Test
    public void test7(){
        transactions.stream()
                .findFirst()
                .ifPresent(System.out::println);
        transactions.stream()
                .findAny()
                .ifPresent(System.out::println);
    }
  • stream reduce

    • 归纳,
    • 算和或者算积,最大值,最小值 等等。。
    • 如果没有初始值, 则返回Optional对象
    @Test
    public void test8(){
        //求和
        transactions.stream()
                .map(Transaction::getMoney)
                .reduce(Double::sum)
                .ifPresent(System.out::println);
        //求积
        transactions.stream()
                .map(Transaction::getMoney)
                .reduce( (a, b) -> a * b)
                .ifPresent(System.out::println);
    }
  • stream count
    • 一共有多少个元素
    @Test
    public void test9(){

        long count = transactions.stream()
                .count();
        System.out.println(count);
    }
  • stream collect
  • 以,分隔 连接字符串
    @Test
    public void test10(){
        String collect = transactions.stream().map(t -> t.getCurrency().getName()).distinct().collect(joining(","));
        System.out.println(collect);
    }
  • 查询平均值,求和
   @Test
   public void test11(){
       Double avg = transactions.stream().collect(Collectors.averagingDouble(Transaction::getMoney));
       System.out.println(avg);
       Double sum = transactions.stream().collect(Collectors.summingDouble(Transaction::getMoney));
       System.out.println(sum);
   } 
  • list 转为 map
  • key为id。value为原对象
    @Test
    public void test12(){
        Map<Integer, Transaction> collect = transactions.stream().collect(Collectors.toMap(Transaction::getId, t -> t));
        System.out.println(collect);
    }

相关文章

网友评论

      本文标题:jdk8 list stream的使用

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