Java的8流列表<美孚>地图<日期,地图<字符串,龙>>有条件groupingBy

XtremeBaumer:

下面的类:

public class Foo {
    private Date date;
    private String name;
    private Long number;
}

我现在有一个List<Foo>,我要转换为Map<Date, Map<String,Long>>Long应为的总和numbers)。是什么让这个艰难的是,我想在内部地图,其中26日被称为“其他”,这概括了具有数量比其他25下一切正好26项。

我想出了下面的代码:

data.stream().collect(Collectors.groupingBy(e -> e.getDate(), Collectors.groupingBy(e -> {
    if (/*get current size of inner map*/>= 25) {
        return e.getName();
    } else {
        return "Other";
    }

}, Collectors.summingLong(e -> e.getNumber()))));

正如你所看到的,我不知道如何来检查它们已经在内部地图元素的数量。我怎样才能获得内心地图的当前大小或有另一种方式来实现我想要什么?

我的Java 7的代码:

Map<Date, Map<String, Long>> result = new LinkedHashMap<Date, Map<String, Long>>();
for (Foo fr : data) {
    if (result.get(fr.getDate()) == null) {
        result.put(fr.getDate(), new LinkedHashMap<String, Long>());
    }
    if (result.get(fr.getDate()) != null) {
        if (result.get(fr.getDate()).size() >= 25) {
            if (result.get(fr.getDate()).get("Other") == null) {
                result.get(fr.getDate()).put("Other", 0l);
            }
            if (result.get(fr.getDate()).get("Other") != null) {
                long numbers= result.get(fr.getDate()).get("Other");
                result.get(fr.getDate()).replace("Other", numbers+ fr.getNumbers());
            }
        } else {
            result.get(fr.getDate()).put(fr.getName(), fr.getNumbers());
        }
    }
}

编辑:

该图应该帮助我实现这样一个表:

在这里输入图像描述

但我需要总结的“其他”之首。


如果您需要更多的相关信息随意问

霍尔格:

我不认为这个操作会从使用Stream API中获益。不过,你可以改善与Java 8的功能操作:

Map<Date, Map<String, Long>> result = new LinkedHashMap<>();
for(Foo fr : data) {
    Map<String, Long> inner
      = result.computeIfAbsent(fr.getDate(), date -> new LinkedHashMap<>());
    inner.merge(inner.size()>=25?"Other":fr.getAirlineName(), fr.getNumbers(), Long::sum);
}

此代码假定该航空公司的名字已经为每个日期是唯一的。否则,你将不得不代码扩展到

Map<Date, Map<String, Long>> result = new LinkedHashMap<>();
for(Foo fr : data) {
    Map<String, Long> inner
      = result.computeIfAbsent(fr.getDate(), date -> new LinkedHashMap<>());
    inner.merge(inner.size() >= 25 && !inner.containsKey(fr.getAirlineName())?
      "Other": fr.getAirlineName(), fr.getNumbers(), Long::sum);
}

正确地积累了航空公司的值。


为了完整起见,这里是如何实现它的流操作。

由于定义采集有一定的复杂性,这是值得书写它作为可重用的代码:

public static <T,K,V> Collector<T,?,Map<K,V>> toMapWithLimit(
    Function<? super T, ? extends K> key, Function<? super T, ? extends V> value,
    int limit, K fallBack, BinaryOperator<V> merger) {

    return Collector.of(LinkedHashMap::new, (map, t) ->
            mergeWithLimit(map, key.apply(t), value.apply(t), limit, fallBack, merger),
            (map1,map2) -> {
                if(map1.isEmpty()) return map2;
                if(map1.size()+map2.size() < limit)
                    map2.forEach((k,v) -> map1.merge(k, v, merger));
                else
                    map2.forEach((k,v) ->
                        mergeWithLimit(map1, k, v, limit, fallBack, merger));
                return map1;
            });
}
private static <T,K,V> void mergeWithLimit(Map<K,V> map, K key, V value,
    int limit, K fallBack, BinaryOperator<V> merger) {
    map.merge(map.size() >= limit && !map.containsKey(key)? fallBack: key, value, merger);
}

这就好比Collectors.toMap,但支持的限制和其它条目回退键。你可能认识的Map.merge呼叫,类似环溶液作为关键因素。

然后,你可以使用收集器作为

Map<Date, Map<String, Long>> result = data.stream().collect(
    Collectors.groupingBy(Foo::getDate, LinkedHashMap::new,
        toMapWithLimit(Foo::getAirlineName, Foo::getNumbers, 25, "Other", Long::sum)));

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Java8流列表<地图<字符串,对象>> groupingBy和计数值

使用流有条件地填充地图-Java 8

Java的8流,对象的转换列表地图<字符串,将<字符串>>

收集列表<对象>地图<字符串,列表<对象>>中的Java 8中使用流

Java的8个流 - 查找最大计数值地图<字符串,列表<对象>>

创建使用Java 8流API字符串和排序列表中的地图

减少地图(地图(地图(列表(字符串))))地形

地图<字符串,地图<字符串,租车>>到列表<汽车>使用Java 8

Java的8个流地图<字符串,列表<字符串值>>为每个关键总和

Java的8 STREM过滤图在地图 - 地图<字符串,地图<字符串,员工>>

Java的8炼油LAMBDA地图<字符串,列表<字符串>>将字符串地图关键要求

Java流列表<地图<字符串,双>>基于字符串需要平均

指定所有值在集<字符串>的地图<String,字符串>与流

Java的8个流API:如何将列表转换为列表中的某个地图<龙,集>具有重复键?

Java 8流收集项目列表的地图

Java 8流-合并地图列表

如何将一个POJO的列表转换地图<字符串,列表>在Java流?

使用Java 8流迭代地图的地图内的列表

如何创建列表<T>地图<字符串,T>而不是地图<字符串,列表<T >>?

拼合一个地图<整数,列表<字符串>>地图<字符串,整数>用流和lambda

Java的游戏 - 绑定对象的列表,并附有地图<字符串,AnotherObject>内

有条件渲染的地图功能

有条件地添加到地图

具有条件的GAS地图数组

有条件地在地图内渲染输入

在地图Java流列表中查找地图

以列表添加值内地图<字符串,列表> Java中8

转换地图<字符串,对象>地图<字符串,请设置<对象>>带有过滤器和流

地图返回列表而不是日期