JAVA: 使用 Stream API 条件下用户对象的分区列表并转换为 Map<String,String>

JAVA: Partitioning list of user objects on a condition using Stream API and convert to Map<String,String>

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

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

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

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

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

I want to store this record in Map<String,String> like <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 的函数来做到这一点? 任何帮助,将不胜感激。提前致谢。

假设 表示您有代理名称与其星级的映射,您不需要分组,您想要映射现有项目到不同的。

这是一种方法:

Map<String,String> star = listAgents.stream()
   .collect(Collectors.toMap(Agent::getName, agn->giveStars(agn.getGeneratedFund())));

如果您对项目进行分组,则不会更改它们而是分配给不同的组 (doh)。映射是一个将对象更改为不同对象的过程。

首先,方法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>(代理名称到星级),可以按照之前的建议使用 toMap 收集器,但这只有在代理名称是唯一的情况下才有效。如果可能出现某些重复值,则需要合并功能(例如,让代理保持更好的评级):

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
        ));