You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java嵌套Stream跳出循环及区域查找Map构建的优化方案

三级对象区域查找优化方案

编辑说明

  • 已将伪代码替换为可运行代码示例。
  • SonarLint认为嵌套流可降低认知复杂度,已补充优化结果,感谢@Unmitigated。

需求描述

现有Country、City、District三级对象,Country包含City列表,City包含District列表。需根据名称查找District,并将对应国家、城市、区域信息存入嵌套Map结构。

示例:查找名为"Bastille"的区域,遍历所有国家的所有城市的所有区域,实现逻辑代码如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        System.out.println("Hello, World!");

        List<Country> countries = new ArrayList<>();

        Country co1 = new Country();
        co1.setName("USA");

        City cit1 = new City();
        cit1.setName("New York");

        District d1 = new District();
        d1.setName("Manhattan");

        District d2 = new District();
        d2.setName("Queens");

        cit1.setDistricts(Arrays.asList(d1, d2));
        co1.setCities(Arrays.asList(cit1));

        countries.add(co1);


        Country co2 = new Country();
        co2.setName("France");

        City cit2 = new City();
        cit2.setName("Paris");

        District d3 = new District();
        d3.setName("Bastille");

        District d4 = new District();
        d4.setName("Montmarte");

        cit2.setDistricts(Arrays.asList(d3, d4));
        co2.setCities(Arrays.asList(cit2));

        countries.add(co1);
        countries.add(co2);


        HashMap<String, HashMap<String, HashMap<String, String>>> foundMap = new HashMap<>();

        boolean isFound = method1(countries, foundMap, "Bastille");

        System.out.println(foundMap);

    }

    public static boolean method1(List<Country> countries, HashMap<String, HashMap<String, HashMap<String, String>>> foundMap, String search) {
        for(Country country : countries){
            for(City city : country.getCities()){
                for(District district : city.getDistricts()){
                    if(district.getName().equals(search)){

                        if(!foundMap.containsKey(country.getName())){
                            foundMap.put(country.getName(), new HashMap<>());
                        }

                        if(!foundMap.get(country.getName()).containsKey(city.getName())){
                            foundMap.get(country.getName()).put(city.getName(), new HashMap<>());
                        }

                        foundMap.get(country.getName()).get(city.getName()).put(district.getName(), "Hello from " + district.getName());

                        return true;
                    }
                }
            }
        }

        return false;
    }
}

实体类定义

以下是Country、City、District示例类:

Country类

import java.util.List;

public class Country {

    String name;
    List<City> cities;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<City> getCities() {
        return cities;
    }

    public void setCities(List<City> cities) {
        this.cities = cities;
    }
}

City类

import java.util.List;

public class City {

    String name;
    List<District> districts;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<District> getDistricts() {
        return districts;
    }

    public void setDistricts(List<District> districts) {
        this.districts = districts;
    }
}

District类

public class District {

    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

运行结果

该示例生成目标Map:{France={Paris={Bastille=Hello from Bastille}}}

实际场景要求

实际场景中,需根据method1的返回值判断,若未找到区域则抛出异常(系统应包含所有区域,未找到视为错误)。同时需要获取国家、城市、区域名称来构建Map条目。

现有问题与困惑

当前代码可实现需求,但SonarLint提示认知复杂度较高,需优化。尝试改用嵌套Stream时,无法实现跳出循环并直接从方法返回结果:

countries.getCities().forEach(city->{
...
...
//若区域名为Bastille
return true; //此处返回值无效,仅跳出当前forEach,无法从方法返回
}

寻求更优雅的方式实现区域存在性检查与Map构建逻辑,或确认是否需要调整算法。

优化结论

采用@Unmitigated提供的方案重构代码:
实际场景中原有代码包含4层for循环+判断逻辑,SonarLint检测认知复杂度为30;改用嵌套Stream结合anyMatch,通过内部布尔变量判断并执行Map构建后,认知复杂度降至20。推测SonarLint未统计stream().anyMatch()的复杂度,仅统计for循环,重构后满足公司代码规范要求。


内容的提问来源于stack exchange,提问作者count_campeador

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:12:54