当前位置: 首页 > 知识库问答 >
问题:

使用collect()而不是filter()筛选流

文德曜
2023-03-14
game_id | user_id | status
   1         1       STARTED
   2         1       FINISHED
   1         2       STARTED
   2         2       FINISHED

我想把这个列表收集到两张地图中(如果可能的话,也可以在一张地图中)

一个映射应该将user_id映射到用户玩过的游戏数量--基本上是具有finished状态的游戏

user_id | finished_games
   1            1
   2            1

另一个映射应该将user_id存储到所有游戏计数。它看起来像这样

user_id  | all_games
   1            2
   2            2
import java.util.*;
import java.util.stream.*;

public class MyClass {
    public static void main(String args[]) {
        List<Game> games = Arrays.asList(
            create("user-1", "STARTED"),
            create("user-2", "STARTED"),
            create("user-1", "FINISHED"),
            create("user-2", "FINISHED"),
            create("user-1", "FINISHED"),
            create("user-2", "FINISHED")
        );

        // expect user-1: all_games (3), finished_games (2)

        Map<String, Long> allGames = games
            .stream()
            .collect(Collectors.groupingBy(Game::getUserId, Collectors.counting()));
        System.out.println(allGames);

        Map<String, Long> finishedGames = games
            .stream()
            .filter(game -> game.battleStatus.equals("FINISHED"))
            .collect(Collectors.groupingBy(Game::getUserId, Collectors.counting()));
        System.out.println(finishedGames);

    }

    private static Game create(String id, String status) {
        Game game = new Game();
        game.userId = id;
        game.battleStatus = status;
        return game;
    }

    private static class Game {
        String userId;
        String battleStatus;

        public String getUserId() {
            return userId;
        }
    }
}
Map<String, Long> finishedGames = games
    .stream()
    .filter(game -> game.battleStatus.equals("FINISHED"))
    .collect(Collectors.groupingBy(Game::getUserId, Collectors.counting()));

有没有一种方法可以在collection块内实现,而不是使用filter

共有1个答案

柯河
2023-03-14

如果您需要同时计算已完成和未完成的游戏,那么另一个groupingby可以帮助您:

Function<Game, Boolean> isFinished = game -> "FINISHED".equals(game.battleStatus);

Map<String, Map<Boolean, Long>> groupedGames = 
    games.stream()
         .collect(groupingBy(Game::getUserId, 
                      groupingBy(isFinished, counting())));

或者您可能希望按battle status本身分组:

Map<String, Map<String, Long>> groupedGames = 
    games.stream()
         .collect(groupingBy(Game::getUserId, 
                      groupingBy(game -> game.battleStatus, counting())));

我甚至会创建一个gettergetBattleStatus(),然后将game->game.battleStatus替换为方法引用game::getBattleStatus:

Map<String, Map<String, Long>> groupedGames = 
    games.stream()
         .collect(groupingBy(Game::getUserId, 
                      groupingBy(Game::getBattleStatus, counting())));
 类似资料:
  • 使用指南 引入方式 import { filter } from 'feart'; components: { 'fe-filter': filter, } 代码演示 基础用法 <fe-filter :list="list" :condition="condition" :isFoot="true" confirmText="确认" resetText="重

  • 我从对象和对象数组中更改了一个对象两次,这样在第一次迭代中,我过滤掉了几个对象,在第二次迭代中,我使用map更改了每个过滤后的对象。我能用减速机或更好的吗?

  • 本文向大家介绍Python如何用filter函数筛选数据,包括了Python如何用filter函数筛选数据的使用技巧和注意事项,需要的朋友参考一下 一.filter函数简介 filter函数主要用来筛选数据,过滤掉不符合条件的元素,并返回一个迭代器对象,如果要转换为列表list或者元祖tuple,可以使用内置函数list() 或者内置函数tuple()来转换; filter函数接收两个参数,第一个

  • 我如何使用java流以相同的性能过滤一个对象? HashSet包含: 现在,我要筛选来生成一个新的,它具有唯一的-属性。 所有具有相同名称的对象都应被视为平等的对象: 我可以通过创建一个新的列表并使用2个for循环来解决这个问题,方法是索引下一个元素并查找(如果它已经放入列表中)。然而,也许有一个班轮这样的问题?可能使用?

  • 我需要过滤一个列表