如何修改Java代码实现含Ç、İ等特殊字符的城市名正确排序?
问题原因
你代码报错的核心原因是Collator实例默认实现的是字符串比较逻辑,无法直接比较KeyValueDTO类型对象,传入Collections.sort方法后会抛出类型转换异常,导致程序中断。
解决方案
提供两种可选方案,可根据业务场景选择:
方案1:Controller层自定义Comparator(推荐,灵活适配多语言场景)
不需要修改KeyValueDTO代码,仅调整排序逻辑,指定按key字段做土耳其语排序即可:
public @ResponseBody List<KeyValueDTO> getCities() { logger.trace("getCities begins."); List<City> cityList = cityService.findAll(); List<KeyValueDTO> cityKeyDtoList = new ArrayList<KeyValueDTO>(); Locale turkish = new Locale("tr", "TR"); Collator collator = Collator.getInstance(turkish); // 可根据需要设置排序强度,PRIMARY强度会忽略大小写、重音差异,按需开启 // collator.setStrength(Collator.PRIMARY); for (City city : cityList) { KeyValueDTO cityKeyDto = new KeyValueDTO(); cityKeyDto.setKey(city.getName()); cityKeyDto.setValue(String.valueOf(city.getCode())); cityKeyDtoList.add(cityKeyDto); } // Java 8及以上版本可用如下简洁写法 cityKeyDtoList.sort(Comparator.comparing(KeyValueDTO::getKey, collator)); // 低版本Java可替换为匿名内部类写法 /* Collections.sort(cityKeyDtoList, new Comparator<KeyValueDTO>() { @Override public int compare(KeyValueDTO o1, KeyValueDTO o2) { return collator.compare(o1.getKey(), o2.getKey()); } }); */ logger.trace("CityController: getAllCities ends"); return cityKeyDtoList; }
该方案优势是排序规则和DTO解耦,如果后续需要适配其他语言排序,仅需修改Locale参数即可,不需要改动DTO定义。
方案2:修改KeyValueDTO的默认排序逻辑
如果所有使用KeyValueDTO的场景都需要土耳其语排序,可以直接修改compareTo方法,内置排序规则:
public class KeyValueDTO implements Comparable<KeyValueDTO> { // 做成静态常量避免重复创建实例,提升性能 private static final Collator TURKISH_COLLATOR = Collator.getInstance(new Locale("tr", "TR")); private String key; private String value; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } @Override public String toString() { return "KeyValueDTO [key=" + key + ", value=" + value + "]"; } @Override public int compareTo(KeyValueDTO other) { // 空值判断可根据业务需要增减 if (this.key == null && other.key == null) return 0; if (this.key == null) return -1; if (other.key == null) return 1; return TURKISH_COLLATOR.compare(this.key, other.key); } }
修改完成后Controller层直接使用原有Collections.sort(cityKeyDtoList)即可正常实现土耳其语排序。
内容的提问来源于stack exchange,提问作者user16558847
相关产品推荐
相关产品推荐

