Stream API 常用


流只能遍历一次。遍历完之后,我们就说这个流已经被消费掉了,重新生成流

List<String> names = menu.stream()
    .filter(d -> d.getCalories() > 300)
    .map(Dish::getName)
    .limit(3)
    .collect(Collectors.toList());

filter、map和limit可以连成一条流水线(中间操作),collect触发流水线执行并关闭它。(终端操作)

常用中间操作

过滤、切片、查找、匹配、映射和归约

filter,map,limit,sorted,distinct

中间操作目 的
filter过滤数据
distinct去重
skip跳过和limit相对
limit
map映射
sorted排序
常用终端操作
终端操作目 的
forEach消费流中的每个元素并对其应用 Lambda。这一操作返回 void
count返回流中元素的个数。这一操作返回 long
collect把流归约成一个集合,比如 List、Map 甚至是 Integer
reduce计算
count数量

allMatch、anyMatch、noneMatch、findFirst和findAny 返回一个Optional

Optional类(java.util.Optional)是一个容器类,代表一个值存在或不存在。

分组 Collectors.groupingBy
// 根据类型分组
Map<Dish.Type, List<Dish>> dishesByType = 
 menu.stream().collect(groupingBy(Dish::getType)); 

// 根据属性复杂分组
public enum CaloricLevel { DIET, NORMAL, FAT }

@Test
public void fun16() {
    Map<CaloricLevel, List<Dish>> dishesByCaloricLevel = menu.stream().collect(
        Collectors.groupingBy(dish -> {
            if (dish.getCalories() <= 400) return CaloricLevel.DIET;
            else if (dish.getCalories() <= 700) return
                CaloricLevel.NORMAL;
            else return CaloricLevel.FAT;
        }));
}
多级分组
@Test
public void fun17() {
    Map<Dish.Type, Map<CaloricLevel, List<Dish>>> dishesByTypeCaloricLevel =
        menu.stream().collect(
        // 一级分类
        Collectors.groupingBy(Dish::getType,
                              //二级分类
                              Collectors.groupingBy(dish -> {
                                  if (dish.getCalories() <= 400) return CaloricLevel.DIET;
                                  else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
                                  else return CaloricLevel.FAT;
                              }))
    );
}
分组求和(BigDecimal)
Map<String, BigDecimal> collect1 = list.stream().collect(Collectors.groupingBy(Detail::getCategoryName,
                Collectors.reducing(BigDecimal.ZERO, Detail::getConsume, BigDecimal::add)));

Example
public class TransactionTest {

    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<Trader> traders = Arrays.asList(raoul, mario, alan, brian);

    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)
    );

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

    @Test
    public void fun2() {
        //交易员都在哪些不同的城市工作过
        List<String> collect1 = transactions.stream().
                map(i -> i.getTrader().getCity())
                .distinct()
                .collect(Collectors.toList());
        collect1.forEach(System.out::println);
    }

    @Test
    public void fun3() {
        //查找所有来自于剑桥的交易员,并按姓名排序
        List<Trader> cambridge = traders.stream().filter(i -> i.getCity().equals("Cambridge"))
                .distinct()
                .sorted(Comparator.comparing(Trader::getName))
                .collect(Collectors.toList());
        cambridge.forEach(System.out::println);
    }

    @Test
    public void fun4() {
        // 返回所有交易员的姓名字符串,按字母顺序排序
        List<String> collect = traders.stream()
                .sorted(Comparator.comparing(Trader::getName))
                .map(Trader::getName)
                .collect(Collectors.toList());
        collect.forEach(System.out::println);
    }

    @Test
    public void fun5() {
        // 有没有交易员是在米兰工作的
        boolean milan = traders.stream()
                .anyMatch(i -> i.getCity().equals("Milan"));
        System.out.println(milan);
    }

    @Test
    public void fun6() {
        // 打印生活在剑桥的交易员的所有交易额
        transactions.stream()
                .filter(i -> "Cambridge".equals(i.getTrader().getCity()))
                .map(Transaction::getValue)
                .forEach(System.out::println);
    }

    @Test
    public void fun7() {
        // 所有交易中,最高的交易额是多少
        Optional<Integer> reduce = transactions.stream()
                .map(Transaction::getValue)
                .reduce(Integer::max);
        System.out.println(reduce.get());
    }

    @Test
    public void fun8() {
        // 找到交易额最小的交易
        Optional<Transaction> reduce = transactions.stream()
                .reduce((t1, t2) -> t1.getValue() < t2.getValue() ? t1 : t2);
        System.out.println(reduce.get());

        Optional<Transaction> min = transactions.stream()
                .min(Comparator.comparing(Transaction::getValue));
        System.out.println(min);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值