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

如何使用Java流API收集数据以映射

严开宇
2023-03-14

我有一个问题,希望有人能帮助我提高Java流API的知识。

我的服务通过RabbitMQ以如下数组的形式从另一个服务接收数据:

[ {"deviceId":1,"userId":1},
{"deviceId":2,"userId":1},
{"deviceId":3,"userId":2},
{"deviceId":4,"userId":2},
{"deviceId":5,"userId":1},
{"deviceId":6,"userId":2},
... ]

我需要对这些数据做的是将其收集到用户具有userId的列表和设备id的列表中。因此,从上面的数据来看,它应该是:

User {userId: 1, List<deviceId>: 1,2,5} & User {userId: 2, List<deviceId>: 3,4,6}

我确实有一个可行的解决方案,但它很笨拙

解决方案是:

    private List<User> parseDeviceData(JsonNode jsonNode) {
    List<JsonNode> list = StreamSupport.stream(jsonNode.spliterator(), false)
            .filter(this::validDeviceRecord) // checking for presence of deviceId & userId
            .collect(Collectors.toList());

    Map<Integer, ArrayList<Integer>> map = new HashMap<>();
    for (JsonNode j : list) {
        Integer id = j.get("deviceId").asInt();
        Integer userId = j.get("userId").asInt();
        ArrayList<Integer> l;
        if (map.containsKey(userId)) {
            l = map.get(userId);
        } else {
            l = new ArrayList<>();
        }
        l.add(id);
        map.put(userId, l);
    }

    return map.entrySet().parallelStream()
            .map(entry -> new User(entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());
}

如何对流执行相同的操作?谢谢

共有1个答案

卢开济
2023-03-14

您可以将下面的代码作为示例。

List<MyObject> list = new ArrayList<>();
        list.add(new MyObject("1", "1"));
        list.add(new MyObject("2", "2"));
        list.add(new MyObject("3", "1"));
        list.add(new MyObject("4", "2"));
        list.add(new MyObject("5", "3"));
        list.add(new MyObject("6", "1"));
        Map<String, List<String>> items = list.stream().collect(Collectors.groupingBy(MyObject::getUserId, Collectors.mapping(MyObject::getDeviceId,Collectors.toList())));
        System.out.println(items);
 类似资料:
  • 假设你有一张这样的物体地图(尽管想象它更大): rtype=133,有两个! 我想对Streams做的是这样的: 我在理解Collectors&groupBy的工作原理时遇到了一些麻烦,但我想这可能会用于本例。 在Java streams API中进行编码的正确方法是什么? 我很难找到类似的地图例子(人们在他们的例子中更多地使用列表)

  • 我有以下形式的地图: 让INNER成为内部地图,即。 例如,我想在一个新的中减少START映射 它们具有相同的键,但值不同。特别是,对于每个键,我希望新的Double值是相应键的INNER映射中值的SUM。 如何使用JAVA 8的流API来实现这一点? 谢谢大家。 编辑:样例地图为 我想要一张像下面这样的新地图:

  • 为了更好地理解新的流API,我试图转换一些旧代码,但我被困在这一个。 我似乎无法为它创建有效的收集器:

  • 我有一个地图列表,并希望对某些列进行分组和求和。 地图列表:

  • 我正在使用预定义的MyComparator对流中填充的MyObject(该对象有一个getName()getter)进行排序。 那么一旦排序,是否有一种方法将MyObject的名称和排序后对象的顺序/位置收集到映射中? 下面是我认为应该是的样子: 例如,如果集合包含三个对象(名称为name1的object1,名称为name2的object2,名称为name3的object3),并且在对它们进行排序

  • 问题内容: 我想要初始化a,并希望始终从流外部输入相同的值。 但是Java抱怨如下: 收集器类型中的toMap(Function,Function)方法不适用于参数(Function,BigDecimal) 为什么不能从外部使用BigDecimal?如果我写: 它会起作用,但这当然不是我想要的。 问题答案: 的第二个参数(如第一个参数)是一个函数,它接受流元素并返回映射的值。 在这种情况下,您想忽