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

Java 8流/收集器按地图分组

喻增
2023-03-14

我有两张地图

  1. scoreMap

其逻辑是简单地从scoresMap中获取分数,并将其与阈值Map中的阈值进行比较。根据其位置(即高、中、高之间或中以下),从阈值Map中选择相关的注释。

可能是这样的:

BiFunction<Map<String,Float>, Map<Float,String>, Map<String,String>> or
BiFunction<Map<String,Float>, Map<Float,String>, Map<String,List<String>>>

我还没有弄清楚如何进行分组通过使用检查3个条件的谓词,所以对于没有其他示例Stream代码表示歉意!非流代码看起来像这样(不使用Maps):

if(orgScorePct >= HI_THRESHOLD) 
    return "ORG_HI_SCORE_COMMENT";
if(orgScorePct < HI_THRESHOLD && orgScorePct > MED_THRESHOLD) 
    return "ORG_MED_SCORE_COMMENT";
return "ORG_LOW_SCORE_COMMENT";

共有2个答案

步炯
2023-03-14
    List<BeanClass> list1 = new ArrayList<BeanClass>();
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
    list1.add(new BeanClass(123,abc,99.0,formatter.parse("2018-02-01")));
    list1.add(new BeanClass(456,xyz,99.0,formatter.parse("2014-01-01")));
    list1.add(new BeanClass(789,pqr,95.0,formatter.parse("2014-01-01")));
    list1.add(new BeanClass(1011,def,99.0,formatter.parse("2014-01-01")));
    Map<Object, Optional<Double>> byDate = list1.stream()
   .collect(Collectors.groupingBy(p -> formatter.format(p.getCurrentDate()),
    Collectors.mapping(BeanClass::getAmount, Collectors.maxBy(Double::compare))));
冯德宇
2023-03-14

首先,使用TreeMap作为阈值要容易得多:因为它是键上的排序映射,所以为给定值确定正确的阈值注释只需获取该值的FloorEntry。天花板条目对应于具有紧邻给定项的键的条目。类似地,有ceilingEntry来检索具有紧邻给定项的键的条目。

考虑到这一点,我们可以有以下(带样本数据):

Map<String,Float> scoreMap = new HashMap<>();
TreeMap<Float,String> thresholdMap = new TreeMap<>();

scoreMap.put("name1", 1.0f);
scoreMap.put("name2", 2.0f);
scoreMap.put("name3", 3.0f);
scoreMap.put("name4", 5.0f);

thresholdMap.put(0.5f, "comment0");
thresholdMap.put(1.5f, "comment1");
thresholdMap.put(4.5f, "comment2");

Map<String,List<String>> result =
    scoreMap.entrySet()
            .stream()
            .collect(Collectors.groupingBy(
                e -> thresholdMap.floorEntry(e.getValue()).getValue(),
                Collectors.mapping(Map.Entry::getKey, Collectors.toList())
            ));

这导致了{comment2=[name4],comment1=[name3,name2],comment0=[name1]}这是正确的:“comment2”的阈值是4.5,只有“name4”的分数大于4;“comment1”的阈值为1.5,“name2”“name3”的得分都在1.5到4.5之间,以此类推。

如果没有楼层入口,请小心:可能是分数没有相应的阈值;例如,在上面的数据中,分数为0会导致问题。要处理这种情况,需要检查floorEntry是否返回null,并通过返回默认值来相应地处理它。

 类似资料:
  • 我对这两种方法的不同感到困惑,但我肯定我做错了什么。 下面我有一个工作示例和一个非工作示例。在工作示例中,我将变量测试器指定为“映射”,在非工作示例中,我尝试将其指定为映射。在第二个示例中,错误如下所示: 我没有看到tester变量的类型与myMap变量的类型之间的联系。 虽然Eran发布了对我的原始版本的解释,但它表明我应该使用收藏家。托马普而不是收藏家。groupBy,因为我的目标是为从“pr

  • 我试图对对象中的每个条目执行映射操作。 我需要从键中去掉前缀,并将值从一种类型转换为另一种类型。我的代码从 映射实例并使用,这看起来很难看。 还有更好的选择吗?使用for循环似乎更好: 我应该避免使用流API吗?还是我错过了更好的方式?

  • 我有这样的代码: 我写了它,但我想知道。是否可以在不创建新地图的情况下编写它。类似这样的东西(不正确的代码):

  • 问题内容: Java 8中有什么方法可以将一个元素分组而不收集它们?我希望结果再次出现。因为我必须处理大量数据甚至是无限流,所以我无法先收集数据并再次流处理结果。 所有需要分组的元素在第一流中都是连续的。因此,我喜欢使流评估保持懒惰。 问题答案: 无法使用标准Stream API做到这一点。通常,您无法执行此操作,因为将来总是有可能出现属于任何已创建组的新项目,因此,在处理所有输入之前,您无法将组

  • 在Java8中有什么方法可以在中分组元素而不收集它们吗?我希望结果再次成为。因为我必须处理大量的数据,甚至是无限的流,所以我不能首先收集数据,然后再次流化结果。 所有需要分组的元素在第一个流中是连续的。因此,我喜欢保持流评估懒惰。

  • 我有一个person对象,它有一个名称和一个地址列表作为参数。地址有一个街道,类型,城市,和个人我想获得一个按城市分组的地图。我卡住了