首页 > 解决方案 > JAVA:使用 Stream API 对条件下的用户对象进行分区列表并转换为 Map

问题描述

我有一个类代理,它有以下成员:

class Agent{ 
   String name;
   long funds;
   //... getters and setters, parameterized constructor
}

现在,我有一个 Agent 类对象的列表。

ArrayList<Agent> listAgents=new ArrayList<Agent>();

我想给表现最好的人打星星,比如资金超过 100000 的人给 5 星,资金超过 80000 的人给 4 星,依此类推。

我想将此记录存储在 Map<String,String> 中,例如 <ABC,*****> <PQR,****>

我尝试了以下代码:

Map<String,String> star=listAgents
    .stream()
    .collect(Collectors.groupingBy(agn->giveStars(agn.getGeneratedFund())));

这里的 giveStars 函数定义如下:

public static String giveStars(long generatedFund) {
        if(generatedFund>=100000)
            return "*****";
        else if(generatedFund<100000&& generatedFund>=80000)
            return "****";
        else if(generatedFund<80000 && generatedFund>=60000)
            return "***";
        return "";
}

这没有用。另外,我认为这不是正确的方法。如何使用 Stream API 的函数来做到这一点?任何帮助,将不胜感激。提前致谢。

标签: javacollectionsjava-streamcollectors

解决方案


首先,方法中存在一个问题giveStars,应该重写:

public static String giveStars(long generatedFund) {
    if (generatedFund >= 1_000_000)
        return "*****";
    else if (generatedFund >=800_000)
        return "****";
    else if (generatedFund >= 600_000)
        return "***";
    return "";
}

接下来,代码与创建Collectors.groupingBy(agn->giveStars(agn.getGeneratedFund()))地图的意图相矛盾Map<String, String>——它将创建Map<String, List<Agent>>关键是星级的位置。所以也许你的真正意图是改变地图的类型。

Map<String, List<Agent>> groupByStars = listAgents.stream()
        .collect(Collectors.groupingBy(agent -> giveStars(agent.getGeneratedFund())));

这样的地图将让您立即获得顶级代理商。

如果Map<String, String>需要 (agent name to stars rating),toMap可以按照前面的建议使用收集器,但这只有在 agent 名称唯一的情况下才有效。如果可能出现一些重复值,则需要合并功能(例如,以保持代理具有更好的评级):

Map<String, String> groupByAgentName = listAgents.stream()
        .collect(Collectors.toMap(
            Agent::getName, 
            agent -> giveStars(agent.getGeneratedFund()),
            (rating1, rating2) -> rating1.length() > rating2.length() ? rating1 : rating2,
            LinkedHashMap::new // keep insertion order
        ));

推荐阅读