比较自我满足的带首字母的城市二级排序

363 阅读2分钟

       有个朋友需要实现一个功能,数据库查出经销商信息,并根据省,市排序,并提供首个省市的首字母,鉴于他觉得代码实现实在太长,想要优化下,于是我闪亮登场。

       首先,有个问题是要提一下的,PinYinHelper对于城市的多音字支持不友好,更换了TinyPinyin,然后有个拿空间换时间的想法,逻辑上看起来O(n)

       主逻辑代码如下:

   

List<Dealer> dealerList = 根据条件查询数据库拿到经销商信息
//数据展示,后面提供代码
TreeSet<CityDealerResp.Province> parent = new TreeSet<>();
if (CollectionUtils.isNotEmpty(dealerList)){  
     Map<Long, CityDealerResp.Province> provinceMap = new HashMap<>(26/3*4+1);   
     Map<String,CityDealerResp.CityDealer> cityDealerMap = new HashMap<>(dealerList.size()/3*4+1);   
     dealerList.forEach(e->{        
         if (StringUtils.isNotBlank(e.getDealerPrvnceNm()) && StringUtils.isNotBlank(e.getDealerLandCityNm()) && StringUtils.isNotBlank(e.getSaleCode())){       
             CityDealerResp.Province province = provinceMap.get(e.getDealerPrvnceId());            
             if (Objects.nonNull(province)){                
                 TreeSet<CityDealerResp.CityDealer> cityDealers = province.getCities();               
                 if (CollectionUtils.isNotEmpty(cityDealers)){                    
                     CityDealerResp.CityDealer cityDealer = cityDealerMap.get(String.valueOf(e.getDealerPrvnceId())+e.getDealerLandCityId());                  
                         if (Objects.nonNull(cityDealer)) {                        
                             cityDealer.getDealers().add(new CityDealerResp.Dealer(e.getSaleCode(), e.getName()));    
                         }else {                      
                             cityDealer = CityDealerResp.buildCityDealerFromDealerBo(e);      
                             cityDealers.add(cityDealer);                      
                             cityDealerMap.put(String.valueOf(e.getDealerPrvnceId())+e.getDealerLandCityId(),cityDealer);       
                         }              
                 }else {                  
                     CityDealerResp.CityDealer cityDealer = CityDealerResp.buildCityDealerFromDealerBo(e);    
                     cityDealerMap.put(String.valueOf(e.getDealerPrvnceId())+e.getDealerLandCityId(),cityDealer);    
                     province.setCities(new TreeSet<CityDealerResp.CityDealer>(){{                       
                         add(cityDealer);}});                
                 }           
         }else{             
             CityDealerResp.CityDealer cityDealer = CityDealerResp.buildCityDealerFromDealerBo(e);                
             cityDealerMap.put(String.valueOf(e.getDealerPrvnceId())+e.getDealerLandCityId(),cityDealer);       
             province = new CityDealerResp.Province(){{                    
                 setName(e.getDealerPrvnceNm());                  
                 Pinyin.init(Pinyin.newConfig().with(CnCityDict.getInstance()));             
                 setPinYin(Pinyin.toPinyin(e.getDealerPrvnceNm(),""));  
                 setInitial(getPinYin().substring(0,1).toUpperCase());     
                 setCities(new TreeSet<CityDealerResp.CityDealer>(){{                       
                               add(cityDealer);                    }});              
              }};                
              parent.add(province);                
              provinceMap.put(e.getDealerPrvnceId(),province);          
        }       
      }  
  });}

 

public class CityDealerResp {   
    TreeSet<Province> cityDealers;   
    @Data    
    public static class Province implements Comparable<Province> {        
        private String name;        
        private String pinYin;       
        private String initial;       
        private TreeSet<CityDealer> cities;        
        @Override       
        public int compareTo(Province o) {           
            int i = Optional.ofNullable(pinYin).orElse("Z").compareTo(Optional.ofNullable(o.getPinYin()).orElse("Z"));        
            if (this != o && i==0){             
                i = Collator.getInstance(Locale.CHINA).compare(name, o.getName());              
                if (i==0){                    
                     i = -1;              
                }         
            }          
         //在比较的同时,确定首字母赋值
         if (this != o && Optional.ofNullable(initial).orElse("Z").equalsIgnoreCase(Optional.ofNullable(o.getPinYin()).orElse("Z").substring(0,1))) {             
             if (i < 0) {              
                 o.setInitial(null);               
             } else {                   
                  initial = null;               
             }          
         }          
       return i;     
     }        
     @Override        public boolean equals(Object o) {            if (this == o) {                return true;            }            if (o == null || getClass() != o.getClass()) {                return false;            }            Province province = (Province) o;            return Objects.equals(name, province.name) &&                    Objects.equals(pinYin, province.pinYin) &&                    Objects.equals(initial, province.initial);        }        @Override        public int hashCode() {            return Objects.hash(name, pinYin, initial);        }    }    @Data    public static class CityDealer implements Comparable<CityDealer> {        private String cityCode;        private String cityName;        private String pinYin;        private String initial;        private TreeSet<Dealer> dealers;        @Override        public int compareTo(CityDealer o) {            int i = Optional.ofNullable(pinYin).orElse("Z").compareTo(Optional.ofNullable(o.getPinYin()).orElse("Z"));            if (this != o && i==0){                i = Collator.getInstance(Locale.CHINA).compare(cityName, o.getCityName());                if (i==0){                    i = -1;                }            }            if (this != o && Optional.ofNullable(initial).orElse("Z").equalsIgnoreCase(Optional.ofNullable(o.getPinYin()).orElse("Z").substring(0,1))) {                if (i < 0) {                    o.setInitial(null);                } else {                    initial = null;                }            }            return i;        }        @Override        public boolean equals(Object o) {            if (this == o) {                return true;            }            if (o == null || getClass() != o.getClass()) {                return false;            }            CityDealer that = (CityDealer) o;            return Objects.equals(cityCode, that.cityCode) &&                    Objects.equals(cityName, that.cityName);        }        @Override        public int hashCode() {            return Objects.hash(cityCode, cityName);        }    }    public static CityDealer buildCityDealerFromDealerBo(com.sgm.ossp.dealer.mapper.db1.entity.Dealer dealer) {        return new CityDealer() {{            setCityCode(String.valueOf(dealer.getDealerLandCityId()));            setCityName(dealer.getDealerLandCityNm());            Pinyin.init(Pinyin.newConfig().with(CnCityDict.getInstance()));            setPinYin(Pinyin.toPinyin(dealer.getDealerLandCityNm(),""));            setInitial(getPinYin().substring(0,1).toUpperCase());            setDealers(new TreeSet<Dealer>() {{                add(new Dealer(dealer.getSaleCode(), dealer.getName()));            }});        }};    }    @Data    @NoArgsConstructor    @AllArgsConstructor    public static class Dealer implements Comparable<Dealer> {        private String dealerCode;        private String dealerName;        @Override        public int compareTo(Dealer o) {            return Collator.getInstance(Locale.CHINA).compare(dealerName, o.getDealerName());        }        @Override        public boolean equals(Object o) {            if (this == o) {                return true;            }            if (o == null || getClass() != o.getClass()) {                return false;            }            Dealer dealer = (Dealer) o;            return dealerCode.equals(dealer.dealerCode) &&                    dealerName.equals(dealer.dealerName);        }        @Override        public int hashCode() {            return Objects.hash(dealerCode, dealerName);        }    }}