优化解析Google Geocoding API格式化地址的Java代码咨询
地址解析代码优化方案
原代码存在的核心问题
- 硬编码严重:直接通过字符串末尾判断是否为瑞典地址,新增其他国家地址解析时需大量修改代码
- 语义模糊:用数组返回解析结果,调用时依赖索引,易出错且可读性差
- 拆分逻辑粗糙:
splitString仅简单拆分数字和字母,无法处理带特殊字符或复杂格式的地址 - 冗余调用:重复调用
splitAddress,降低执行效率且代码冗余
优化后的实现方案
1. 定义地址实体类
用Java Record(Java 16+)封装地址字段,明确语义,避免索引依赖:
public record Address(String street, String postalCode, String city, String country) {}
2. 抽象解析器接口(策略模式)
针对不同国家的地址格式,抽象统一解析接口,便于后续扩展其他国家的解析逻辑:
public interface AddressParser { Address parseFormattedAddress(String formattedAddress); }
3. 实现瑞典地址解析器
利用瑞典地址的格式规则(邮编为5位数字,格式XXX XX,后跟城市),用正则匹配替代硬编码拆分,逻辑更精准:
import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SwedishAddressParser implements AddressParser { private static final String SWEDEN = "Sweden"; // 匹配瑞典邮编+城市的正则:数字部分(允许空格)+ 城市名称 private static final Pattern POSTAL_CITY_PATTERN = Pattern.compile("^(\\d{3}\\s?\\d{2})\\s+(.*)$"); @Override public Address parseFormattedAddress(String formattedAddress) { // 按逗号分割并去除每个部分的首尾空格 String[] addressParts = Arrays.stream(formattedAddress.split(",")) .map(String::trim) .toArray(String[]::new); String street = null; String postalCode = null; String city = null; String country = null; // 识别国家(通常为最后一个部分) if (addressParts.length >= 1) { String lastPart = addressParts[addressParts.length - 1]; if (SWEDEN.equalsIgnoreCase(lastPart)) { country = SWEDEN; } } // 解析瑞典地址的街道、邮编和城市 if (SWEDEN.equals(country) && addressParts.length >= 2) { // 处理邮编+城市部分 Matcher postalMatcher = POSTAL_CITY_PATTERN.matcher(addressParts[addressParts.length - 2]); if (postalMatcher.matches()) { postalCode = postalMatcher.group(1).replaceAll("\\s", ""); // 移除邮编中的空格 city = postalMatcher.group(2); } // 合并前面所有部分为街道(支持多段街道地址) if (addressParts.length > 2) { street = String.join(", ", Arrays.copyOfRange(addressParts, 0, addressParts.length - 2)); } } else { // 非瑞典地址的基础解析逻辑(可扩展其他国家解析器) if (addressParts.length >= 1) street = addressParts[0]; if (addressParts.length >= 2) { Matcher matcher = POSTAL_CITY_PATTERN.matcher(addressParts[1]); if (matcher.matches()) { postalCode = matcher.group(1).replaceAll("\\s", ""); city = matcher.group(2); } } } return new Address(street, postalCode, city, country); } }
4. 调用示例
public class AddressParsingDemo { public static void main(String[] args) { String swedishAddress = "vårbergvägrn 6, 145 67 Norsborg, Sweden"; AddressParser parser = new SwedishAddressParser(); Address address = parser.parseFormattedAddress(swedishAddress); System.out.println("Street : " + address.street()); System.out.println("PostalCode : " + address.postalCode()); System.out.println("City : " + address.city()); System.out.println("Country : " + address.country()); } }
运行结果:
Street : vårbergvägrn 6 PostalCode : 14567 City : Norsborg Country : Sweden
优化亮点
- 扩展性强:新增其他国家地址解析时,只需实现
AddressParser接口,无需修改现有代码 - 语义清晰:用实体类封装结果,避免索引依赖,代码可读性大幅提升
- 规则精准:利用正则匹配符合地址格式规则,比简单拆分更可靠
- 结构整洁:拆分职责,解析逻辑与业务调用分离,便于维护
内容的提问来源于stack exchange,提问作者Arifullah khan
相关产品推荐
相关产品推荐

