Java8的flatMap()到底该怎么用,什么业务场景下会用到

## 先概括

flatMap()的作用就是将多个集合(List)合并成一个大集合处理

## 什么叫多个集合合并成一个大集合处理呢

别着急,我先弄一个例子,然后等下再列举3个使用场景.

## 代码示例

public class Test {

    public static void main(String args[]) {

        List<String> teamIndia = Arrays.asList("Virat", "Dhoni", "Jadeja");
        List<String> teamAustralia = Arrays.asList("Warner", "Watson", "Smith");
        List<String> teamEngland = Arrays.asList("Alex", "Bell", "Broad");
        List<String> teamNewZeland = Arrays.asList("Kane", "Nathan", "Vettori");
        List<String> teamSouthAfrica = Arrays.asList("AB", "Amla", "Faf");
        List<String> teamWestIndies = Arrays.asList("Sammy", "Gayle", "Narine");
        List<String> teamSriLanka = Arrays.asList("Mahela", "Sanga", "Dilshan");
        List<String> teamPakistan = Arrays.asList("Misbah", "Afridi", "Shehzad");
        
        List<List<String>> playersInWorldCup2016 = new ArrayList<>();
        playersInWorldCup2016.add(teamIndia);
        playersInWorldCup2016.add(teamAustralia);
        playersInWorldCup2016.add(teamEngland);
        playersInWorldCup2016.add(teamNewZeland);
        playersInWorldCup2016.add(teamSouthAfrica);
        playersInWorldCup2016.add(teamWestIndies);
        playersInWorldCup2016.add(teamSriLanka);
        playersInWorldCup2016.add(teamPakistan);
        
        // Let's print all players before Java 8
        // Java8之前我们使用的是下面这种原始的方式
        List<String> listOfAllPlayers = new ArrayList<>();
        //这里由于是集合中的集合,所以要for循环两遍很麻烦,后面flatMap就会解决这种麻烦,把多个小集合当成一个大集合来处理
        for(List<String> team : playersInWorldCup2016){
            for(String name : team){
                listOfAllPlayers.add(name);
            }
        }
        
        System.out.println("Players playing in world cup 2016");
        System.out.println(listOfAllPlayers);
        
        
        // Now let's do this in Java 8 using FlatMap
        // 现在我们来用Java8一行代码搞定
        List<String> flatMapList = playersInWorldCup2016.stream()
                                                        .flatMap(pList -> pList.stream())
                                                        .collect(Collectors.toList());
        
        System.out.println("List of all Players using Java 8");
        System.out.println(flatMapList);
    }

}

Output
run:
Players playing in world cup 2016
[Virat, Dhoni, Jadeja, Warner, Watson, Smith, Alex, Bell, Broad, Kane, Nathan, Vettori, AB, Amla, Faf, Sammy, Gayle, Narine, Mahela, Sanga, Dilshan, Misbah, Afridi, Shehzad]
List of all Players using Java 8
[Virat, Dhoni, Jadeja, Warner, Watson, Smith, Alex, Bell, Broad, Kane, Nathan, Vettori, AB, Amla, Faf, Sammy, Gayle, Narine, Mahela, Sanga, Dilshan, Misbah, Afridi, Shehzad]
BUILD SUCCESSFUL (total time: 0 seconds)

以上代码示例来自:https://www.jianshu.com/p/8d80dcb4e7e0

通过上面的代码示例可以看出,当一个大集合中包含有多个小集合时,你要对这些小集合做出同样的逻辑处理时,就可以选择flatMap把许多零碎的小集合放进一个大的集合流(stream)来进行你的逻辑处理.

##  实际使用的业务场景

这里我举一个订单场景的例子(最近在做订单)

场景描述:  书店商城系统,用户下单买书,每一单可以购买多本书,求用户张三所有的订单里所有书的名字.

代码:

public class TestFlatMap {

    @Data
    //订单类
    static class OrderObj {
        //订单id
        private String id;
        //订单创建时间
        //订单名称
    }

    //书本类
    @Data
    @AllArgsConstructor
    static class BookObj {
        //书本关联的订单id
        private String orderId;
        //书本名称
        private String bookName;
        //书本价格
        private Double bookPrice;
    }

    //业务端
    public static void main(String[] args) {
        //数据准备
        BookObj book1 = new BookObj("1", "<金刚葫芦娃>", 10.5);
        BookObj book2 = new BookObj("1", "<铁臂阿童木>", 32.5);
        BookObj book3 = new BookObj("1", "<阿凡提>", 19.5);

        BookObj book4 = new BookObj("2", "<哈哈>", 19.5);
        BookObj book5 = new BookObj("2", "<呵呵>", 19.5);

        //第一个订单一共买了3本书
        List<BookObj> bookObjs1 = Lists.newArrayList();
        bookObjs1.add(book1);
        bookObjs1.add(book2);
        bookObjs1.add(book3);

        //第二个订单一共买了2本书
        List<BookObj> bookObjs2 = Lists.newArrayList();
        bookObjs2.add(book4);
        bookObjs2.add(book5);

        //假设你从别的小伙伴的接口那里获取到了张三每个订单和订单对应的book List信息Map
        Map<String, List<BookObj>> orderInfoMap = Maps.newHashMap();
        orderInfoMap.put("1", bookObjs1);//第一个订单书的集合
        orderInfoMap.put("2", bookObjs2);//第二个订单书的集合

        //需求1:产品经理让你获取所有书本的名字,用flatMap可以如下
        List<String> bookNameList = orderInfoMap.values()
                .stream()
                //此行代码的作用就把2个小集合合并成了一个大集合的stream
                .flatMap(bookObjLst -> bookObjLst.stream())
                .map(bookObj -> bookObj.getBookName())
                .collect(Collectors.toList());

        System.out.println("书本的名称:" + bookNameList);
        //书本的名称:[<金刚葫芦娃>, <铁臂阿童木>, <阿凡提>, <哈哈>, <呵呵>]

        //需求2: 获取张三买的每一本书的价格,并排序
        List<Double> bookPriceList = orderInfoMap.values()
                .stream()
                .flatMap(Collection::stream)//这里只是另外一种简化的写法
                .map(BookObj::getBookPrice)//这里只是另外一种简化的写法
                .sorted()
                .collect(Collectors.toList());
        System.out.println("书本的价格:" + bookPriceList);
        //书本的价格:[10.5, 19.5, 19.5, 19.5, 32.5]

        //需求3: 张三2个订单一共花了多少钱?
        Optional<Double> sumPrice = orderInfoMap.values()
                .stream()
                .flatMap(Collection::stream)
                .map(bookObj -> bookObj.getBookPrice())
                .reduce((price1, price2) -> price1 + price2);
        System.out.println("总共花了:" + sumPrice.get());
        //总共花了:101.5

    }


}

## OK,业务场景演示完毕

================ 码字不易,如果对你有帮助可以 评论 + 点赞

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值