AddressQueryEngine.java 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. package com.skyversation.poiaddr.addquery;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.skyversation.poiaddr.bean.AddressResult;
  5. import com.skyversation.poiaddr.bean.GeoJsonBean;
  6. import com.skyversation.poiaddr.bean.YyskDmdzAddressStandardization;
  7. import com.skyversation.poiaddr.entity.AddrBean;
  8. import com.skyversation.poiaddr.service.AreaService;
  9. import com.skyversation.poiaddr.util.AddrSplitLmrMap;
  10. import com.skyversation.poiaddr.util.ShanghaiAddressSplitUtil;
  11. import com.skyversation.poiaddr.util.SplitAddress;
  12. import com.skyversation.poiaddr.util.net.AddressNetTools;
  13. import com.skyversation.poiaddr.util.status.AddressLevel;
  14. import com.skyversation.poiaddr.util.status.AddressResultEnum;
  15. import org.springframework.http.HttpMethod;
  16. import org.springframework.http.ResponseEntity;
  17. import org.springframework.util.StringUtils;
  18. import org.apache.commons.codec.binary.Base64;
  19. import javax.crypto.Mac;
  20. import javax.crypto.spec.SecretKeySpec;
  21. import java.util.*;
  22. public class AddressQueryEngine {
  23. private static AddressQueryEngine instance = new AddressQueryEngine();
  24. private AddressQueryEngine() {
  25. }
  26. public synchronized static AddressQueryEngine getInstance() {
  27. if (instance == null) {
  28. instance = new AddressQueryEngine();
  29. }
  30. return instance;
  31. }
  32. /***
  33. * 单条地名搜索通用方法,搜索顺序 1. 武大吉奥; 2. 市四中心; 3. 高德搜索; 4. 高德高级搜索;
  34. * @param addrs
  35. * @return
  36. */
  37. public AddressResult commonSearchByName(List<String> addrs) {
  38. if (addrs == null || addrs.size() < 1) {
  39. return null;
  40. }
  41. AddressResult addressResult = new AddressResult();
  42. for (String addr : addrs) {
  43. // 创建请求
  44. addressResult = sj_szxSearchByName(addr, 3);
  45. if (addressResult != null) {
  46. addressResult.setCode(AddressResultEnum.SZX_SUCCESS);
  47. addressResult.setMessage("成功");
  48. SplitAddress splitAddress = ShanghaiAddressSplitUtil.splitBestAddress(addr);
  49. return getCjWgWgwByLoc(addressResult, splitAddress);
  50. }
  51. }
  52. addressResult.setCode(AddressResultEnum.RESULT_NULL);
  53. addressResult.setMessage("失败");
  54. return addressResult;
  55. }
  56. /***
  57. * 单条地名搜索通用方法
  58. * @param addr
  59. * @return
  60. */
  61. public AddressResult commonSearchByName_nw(String addr) {
  62. if (!StringUtils.hasText(addr) || addr.length() <= 3) {
  63. return null;
  64. }
  65. AddressResult addressResult = new AddressResult();
  66. AddrBean lmrAddrBean = AddrSplitLmrMap.outAddrMapInAddr(addr);
  67. if (lmrAddrBean.getRule() == null || Integer.parseInt(lmrAddrBean.getRule()) <= 0) {
  68. addressResult.setMessage("非上海数据");
  69. AddressResult.ContentBean content = new AddressResult.ContentBean();
  70. content.setSearchAddress(addr);
  71. content.setPname(lmrAddrBean.getProvinces());
  72. content.setCityname(lmrAddrBean.getMarket());
  73. content.setAdname(lmrAddrBean.getStreetTown());
  74. content.setCommunity(lmrAddrBean.getResidentialCommittee());
  75. content.setScore("rule_0");
  76. addressResult.setData(new ArrayList<>());
  77. addressResult.getData().add(content);
  78. return addressResult;
  79. }
  80. SplitAddress splitAddress = ShanghaiAddressSplitUtil.splitBestAddress(addr);
  81. if (splitAddress.getStatus() == 3) {// 不是地址
  82. addressResult.setMessage("非地址数据");
  83. return addressResult;
  84. } else {
  85. AddressResult.ContentBean addrBean = new AddressResult.ContentBean();
  86. addrBean.setSearchAddress(addr);
  87. addrBean.setPname(splitAddress.getProvince());
  88. addrBean.setCityname(splitAddress.getCity());
  89. addrBean.setDistance(splitAddress.getDistrict());
  90. addrBean.setAdname(splitAddress.getStreet());
  91. addrBean.setCommunity(splitAddress.getCommunity());
  92. addrBean.setStandAddr(splitAddress.getCity() + splitAddress.getDistrict() + splitAddress.getStreet()
  93. + splitAddress.getCommunity() + splitAddress.getAddr());
  94. addressResult.setAddrBean(addrBean);
  95. // 优先进行数据库查询
  96. List<YyskDmdzAddressStandardization> dbPois = AreaService.getInstance().getAddressPoisByAddr(splitAddress);
  97. if (dbPois != null && dbPois.size() > 0) {
  98. JSONArray pois = new JSONArray();
  99. pois.addAll(dbPois);
  100. SplitAddress splitAddress1 = ShanghaiAddressSplitUtil.splitBestAddress(addr);
  101. addressResult = new TransfromDataTool().dbResultToResult(splitAddress1, addr, pois);
  102. addressResult.setAddrBean(addrBean);
  103. if (addressResult.getData() != null && addressResult.getData().size() > 0) {
  104. getCjWgWgwByLoc(addressResult, splitAddress);
  105. addressResult.setCode(AddressResultEnum.DB_SUCCESS);
  106. addressResult.setMessage("成功");
  107. AddressResult.ContentBean content = addressResult.getData().get(0);
  108. addrBean.setPname(content.getPname());
  109. addrBean.setCityname(content.getCityname());
  110. addrBean.setAdname(content.getAdname());
  111. addrBean.setDistance(content.getDistance());
  112. addrBean.setCommunity(content.getCommunity());
  113. addrBean.setStandAddr(content.getStandAddr());
  114. addressResult.setAddrBean(addrBean);
  115. return addressResult;
  116. }
  117. /*} else {
  118. if (splitAddress.getDistrict() != null && !splitAddress.getDistrict().isEmpty()) {
  119. //查询无结果,尝试给出推荐结果
  120. List<YyskDmdzAddressStandardization> recommendPois = AreaService.getInstance().getRecommendAddress(splitAddress);
  121. if (recommendPois != null && recommendPois.size() > 0) {
  122. JSONArray pois = new JSONArray();
  123. pois.addAll(recommendPois);
  124. SplitAddress splitAddress1 = ShanghaiAddressSplitUtil.splitBestAddress(addr);
  125. addressResult = new TransfromDataTool().dbResultToResult(splitAddress1, addr, pois);
  126. addressResult.setAddrBean(addrBean);
  127. if (addressResult != null && addressResult.getData() != null && addressResult.getData().size() > 0) {
  128. getCjWgWgwByLoc(addressResult);
  129. addressResult.setCode(AddressResultEnum.DB_RECOMMEND_SUCCESS);
  130. addressResult.setMessage("成功");
  131. AddressResult.ContentBean content = addressResult.getData().get(0);
  132. addrBean.setPname(content.getPname());
  133. addrBean.setCityname(content.getCityname());
  134. addrBean.setAdname(content.getAdname());
  135. addrBean.setDistance(content.getDistance());
  136. addrBean.setCommunity(content.getCommunity());
  137. addrBean.setStandAddr(content.getStandAddr());
  138. addressResult.setAddrBean(addrBean);
  139. return addressResult;
  140. }
  141. }
  142. }*/
  143. }
  144. }
  145. addressResult.setMessage("失败");
  146. return addressResult;
  147. }
  148. public static Map<String, String> initSigns() {
  149. Map<String, String> headerMap = new HashMap<>();
  150. String timestamp = System.currentTimeMillis() + "";
  151. String appCode = "7unv4vbwqxnq4a7m9h";
  152. String UUid = UUID.randomUUID().toString();
  153. String appSecret = "w6tawvf4k3ck4ikij9";
  154. headerMap.put("x-timestamp", timestamp);
  155. headerMap.put("x-appcode", appCode);
  156. headerMap.put("x-uuid", UUid);
  157. // 签名
  158. headerMap.put("x-sign", AddressQueryEngine.getSigns(timestamp, appCode, UUid, appSecret));
  159. return headerMap;
  160. }
  161. public static String getSigns(String timestamp, String appCode, String UUid, String appSecret) {
  162. // 先拼接
  163. String signData = timestamp + appCode + UUid;
  164. // 生成sign
  165. String sign = "";
  166. try {
  167. Mac sha256 = Mac.getInstance("HmacSHA256");
  168. sha256.init(new SecretKeySpec(appSecret.getBytes(), "HmacSHA256"));
  169. byte[] result = sha256.doFinal(signData.getBytes());
  170. sign = Base64.encodeBase64String(result);
  171. } catch (Exception e) {
  172. System.err.println("sign 生成异常:" + e);
  173. }
  174. return sign;
  175. }
  176. public AddressResult sj_szxSearchByName(String address, Integer level) {
  177. // 鉴权
  178. JSONObject params = new JSONObject();
  179. JSONArray requestJson = new JSONArray();
  180. JSONObject paramObject = new JSONObject();
  181. paramObject.put("name", "query");
  182. paramObject.put("position", "QUERY");
  183. switch (level) {
  184. case 3:
  185. paramObject.put("value", address);
  186. break;
  187. case 2:
  188. if (address.contains("号")) {
  189. paramObject.put("value", address.substring(0, address.lastIndexOf("号") + 1));
  190. } else {
  191. level--;
  192. return sj_szxSearchByName(address, level);
  193. }
  194. break;
  195. case 1:
  196. if (address.contains("弄")) {
  197. paramObject.put("value", address.substring(0, address.lastIndexOf("弄") + 1));
  198. } else {
  199. paramObject.put("value", address);
  200. }
  201. break;
  202. }
  203. if (address.startsWith("中山")) {
  204. if (!address.startsWith("中山街道")) {
  205. paramObject.put("value", "中山街道" + paramObject.get("value").toString().substring(2));
  206. }
  207. }
  208. if (!address.startsWith("上海")) {
  209. paramObject.put("value", "上海市" + paramObject.get("value"));
  210. }
  211. requestJson.add(paramObject);
  212. // 判断是否是关键字版搜索服务
  213. if (Constant.SJ_SZX_SEARCH_BY_NAME.contains("1742459783686")) {
  214. JSONObject paramObject2 = new JSONObject();
  215. paramObject2.put("name", "region");
  216. paramObject2.put("position", "QUERY");
  217. paramObject2.put("value", Constant.getAMAP_CITY_CODE());
  218. requestJson.add(paramObject2);
  219. JSONObject paramObject3 = new JSONObject();
  220. paramObject3.put("name", "page_size");
  221. paramObject3.put("position", "QUERY");
  222. paramObject3.put("value", "10");
  223. requestJson.add(paramObject3);
  224. }
  225. params.put("requestJson", requestJson);
  226. // 发起请求
  227. ResponseEntity response = AddressNetTools.getInstance().requestGetOrPost(HttpMethod.POST, Constant.SJ_SZX_SEARCH_BY_NAME, params, initSigns(), 5);
  228. if (response != null && response.hasBody()) {
  229. String body = response.getBody() + "";
  230. if (!StringUtils.hasText(body)) {
  231. if (level > 0) {
  232. level--;
  233. return sj_szxSearchByName(address, level);
  234. }
  235. return new AddressResult(AddressResultEnum.RESULT_NULL, "搜索无结果");
  236. }
  237. try {
  238. AddressResult addressResult = TransfromDataTool.szxResultToResult(JSONObject.parseObject(body), address);
  239. if (addressResult.getCode().equals(AddressResultEnum.RESULT_NULL) && level > 0) {
  240. level--;
  241. return sj_szxSearchByName(address, level);
  242. }
  243. return addressResult;
  244. } catch (Exception e) {
  245. System.err.println("请求地址:" + address + ";返回结果:" + body + ";处理异常:" + e);
  246. return new AddressResult(AddressResultEnum.DATA_FROMAT_FAILD, "格式化失败");
  247. }
  248. } else {
  249. if (level > 0) {
  250. level--;
  251. return sj_szxSearchByName(address, level);
  252. }
  253. System.out.println("地址[" + address + "]未查询到数据!");
  254. return null;
  255. }
  256. }
  257. /***
  258. * 根据搜索地址,赋值村居、网格、微格网信息
  259. * @param result
  260. * @return
  261. */
  262. public AddressResult getCjWgWgwByLoc(AddressResult result, SplitAddress splitAddress) {
  263. if (result == null || result.getData() == null || result.getData().size() < 1) {
  264. return result;
  265. } else {
  266. AreaService areaService = AreaService.getInstance();
  267. for (AddressResult.ContentBean content : result.getData()) {
  268. if (content.getLat() != null && content.getLon() != null) {
  269. // 判断是否存在村居数据
  270. if (content.getCommunity() == null || content.getCommunity().isEmpty()) {
  271. GeoJsonBean cjBean = areaService.isInResidentialCommitteePolygon(content.getLon(), content.getLat());
  272. if (cjBean != null && cjBean.getProperties() != null) {
  273. content.setPname("上海市");
  274. content.setCityname(cjBean.getProperties().getString("所属区"));
  275. content.setAdname(cjBean.getProperties().getString("所属街"));
  276. content.setCommunityCode(cjBean.getProperties().getString("居委会"));
  277. content.setCommunity(cjBean.getProperties().getString("居委_1"));
  278. }
  279. }
  280. // 判断是否存在街镇数据
  281. if (content.getAdname() == null || content.getAdname().isEmpty()) {
  282. GeoJsonBean townBean = areaService.isInTownPolygon(content.getLon(), content.getLat());
  283. if (townBean != null && townBean.getProperties() != null) {
  284. content.setPname("上海市");
  285. content.setAdnameCode(townBean.getProperties().getString("area_code"));
  286. content.setAdname(townBean.getProperties().getString("name"));
  287. }
  288. }
  289. if ((content.getAdname() == null || content.getAdname().isEmpty() || content.getCityname() == null || content.getCityname().isEmpty() || content.getCommunity() == null || content.getCommunity().isEmpty())) {
  290. // 判断是否存在行政区划数据
  291. if (content.getCityname() == null || content.getCityname().isEmpty()) {
  292. GeoJsonBean adBean = areaService.isInadPolygon(content.getLon(), content.getLat());
  293. if (adBean != null && adBean.getProperties() != null) {
  294. content.setPname("上海市");
  295. content.setCityname(adBean.getProperties().getString("name"));
  296. }
  297. }
  298. }
  299. content.setStandAddr(content.getPname() + content.getCityname() + content.getAdname() + splitAddress.getAddr());
  300. } else {
  301. System.err.println("没有经纬度参数,不能根据经纬度落点补充街镇等信息!");
  302. }
  303. }
  304. return result;
  305. }
  306. }
  307. public AddressResult.ContentBean addContentWGWGrid(AddressResult.ContentBean content) {
  308. AreaService areaService = AreaService.getInstance();
  309. if (content != null && content.getLat() != null && content.getLon() != null) {
  310. if (!StringUtils.hasText(content.getWgName())) {
  311. GeoJsonBean geoJsonBean = areaService.isInWGPolygon(content.getLon(), content.getLat());
  312. if (geoJsonBean != null && geoJsonBean.getProperties() != null) {
  313. content.setWgName(geoJsonBean.getProperties().getString("网格名称"));
  314. content.setWgCode(geoJsonBean.getProperties().getString("网格编码"));
  315. }
  316. }
  317. if (!StringUtils.hasText(content.getWgwCode())) {
  318. GeoJsonBean geoJsonBean = areaService.isInWGWPolygon(content.getLon(), content.getLat());
  319. if (geoJsonBean != null && geoJsonBean.getProperties() != null) {
  320. content.setWgwName(geoJsonBean.getProperties().getString("å¾®ç½\u0091_1"));
  321. content.setWgwCode(geoJsonBean.getProperties().getString("å¾®ç½\u0091æ ¼"));
  322. }
  323. }
  324. if (!StringUtils.hasText(content.getZhwgName())) {
  325. GeoJsonBean geoJsonBean = areaService.isInZHGWPolygon(content.getLon(), content.getLat());
  326. if (geoJsonBean != null && geoJsonBean.getProperties() != null) {
  327. content.setZhwgName(geoJsonBean.getProperties().getString("网格名称"));
  328. content.setZhwgCode(geoJsonBean.getProperties().getString("网格编码"));
  329. }
  330. }
  331. }
  332. return content;
  333. }
  334. //
  335. public static boolean isNotEmptyOrBlank(String str) {
  336. return str != null && !str.trim().isEmpty();
  337. }
  338. /**
  339. * 1. 搜索到结果就返回第一个;
  340. * 2. 搜索到结果去除行政区划后,存在包含关系,则使用;
  341. * 3. 搜索到结果,数字进行分词,数字匹配则使用;
  342. * 4. 搜索到结果,数字与文本均匹配,则使用;
  343. * 5. 结果与基准数据完全一致,则使用。
  344. *
  345. * @param result
  346. * @param level
  347. * @return
  348. */
  349. public AddressResult.ContentBean verificaData(AddressResult result, AddressLevel level, String addr) {
  350. switch (level) {
  351. case LEVEL_1: {
  352. if (result != null && result.getData() != null && result.getData().size() > 0) {
  353. return result.getData().get(0);
  354. } else {
  355. return null;
  356. }
  357. }
  358. // 2. 搜索到结果去除行政区划后,存在包含关系,则使用;
  359. case LEVEL_CONTAINS_2: {
  360. if (result != null && result.getData() != null && result.getData().size() > 0) {
  361. List<AddressResult.ContentBean> contentBean = result.getData();
  362. for (AddressResult.ContentBean contentBean1 : contentBean) {
  363. if (contentBean1.getAddress() != null) {
  364. String address = townReplaceAll(addressReplaceAll(contentBean1.getAddress()));
  365. String address2 = townReplaceAll(addressReplaceAll(addr));
  366. if (isNotEmptyOrBlank(address) && address.contains(address2)) {
  367. return contentBean1;
  368. }
  369. }
  370. }
  371. } else {
  372. return null;
  373. }
  374. }
  375. // 3. 搜索到结果,数字进行分词,数字匹配则使用;
  376. case LEVLE_NUMBER_3: {
  377. if (result != null && result.getData() != null && result.getData().size() > 0) {
  378. List<AddressResult.ContentBean> contentBean = result.getData();
  379. for (AddressResult.ContentBean contentBean1 : contentBean) {
  380. if (contentBean1.getAddress() != null) {
  381. Set<String> address = tokenizeString(contentBean1.getAddress()).get(1);
  382. if (address != null && address.size() > 1) {
  383. Set<String> address2 = tokenizeString(addr).get(1);
  384. int addressSize = address.size();
  385. for (String addr2 : address2) {
  386. if (address.contains(addr2)) {
  387. addressSize--;
  388. if (addressSize == 0) {
  389. return contentBean1;
  390. }
  391. }
  392. }
  393. }
  394. }
  395. }
  396. } else {
  397. return null;
  398. }
  399. }
  400. // 4. 搜索到结果,数字与文本均匹配,则使用;
  401. case LEVEL_NUMBER_TEXT_4: {
  402. if (result != null && result.getData() != null && result.getData().size() > 0) {
  403. List<AddressResult.ContentBean> contentBean = result.getData();
  404. for (AddressResult.ContentBean contentBean1 : contentBean) {
  405. if (contentBean1.getAddress() != null) {
  406. Set<String> addressString = tokenizeString(contentBean1.getAddress()).get(0);
  407. Set<String> addressNumber = tokenizeString(contentBean1.getAddress()).get(1);
  408. Set<String> address2String = tokenizeString(addr).get(0);
  409. Set<String> address2Number = tokenizeString(addr).get(1);
  410. if (addressString != null && addressString.size() > 1) {
  411. int addressStrSize = addressString.size();
  412. for (String addr2str : address2String) {
  413. if (addressString.contains(addr2str)) {
  414. addressStrSize--;
  415. if (addressStrSize == 0) {
  416. int addressNumSize = addressNumber.size();
  417. for (String addr2Num : address2Number) {
  418. if (addressNumber.contains(addr2Num)) {
  419. addressNumSize--;
  420. if (addressNumSize == 0) {
  421. return contentBean1;
  422. }
  423. }
  424. }
  425. }
  426. }
  427. }
  428. }
  429. }
  430. }
  431. } else {
  432. return null;
  433. }
  434. }
  435. // 结果与基准数据完全一致,则使用。
  436. case LEVEL_TOTAL_CONTAINS_5: {
  437. if (result != null && result.getData() != null && result.getData().size() > 0) {
  438. List<AddressResult.ContentBean> contentBean = result.getData();
  439. for (AddressResult.ContentBean contentBean1 : contentBean) {
  440. if (contentBean1.getAddress() != null) {
  441. String address = addressReplaceAll(contentBean1.getAddress());
  442. String address2 = addressReplaceAll(addr);
  443. if (isNotEmptyOrBlank(address) && address.equals(address2)) {
  444. return contentBean1;
  445. }
  446. }
  447. }
  448. } else {
  449. return null;
  450. }
  451. }
  452. default: {
  453. return null;
  454. }
  455. }
  456. }
  457. public static String addressReplaceAll(String address) {
  458. return address.replaceAll("上海市", "").replaceAll(Constant.getArea() + "区", "").replaceAll("-", "").replaceAll("_", "").replaceAll("/", "").replaceAll(" ", "").replaceAll(",", "").replaceAll("\\.", "").replaceAll(",", "").replaceAll("。", "").replaceAll("\\+", "").replaceAll("\\*", "");
  459. }
  460. public static String townReplace_ct(String address) {
  461. address = address.replaceAll(" ", "");
  462. // 替换市
  463. address = address.replaceAll("上海市", "");
  464. String[] towns = Constant.getTowns();
  465. for (String town : towns) {
  466. if (address.contains(town)) {
  467. address = address.substring(address.indexOf(town) + town.length());
  468. }
  469. }
  470. // TODO 强行去除居委
  471. if (address.contains("居委会")) {
  472. address = address.substring(address.indexOf("居委会") + 3);
  473. }
  474. if (address.contains("委员会")) {
  475. address = address.substring(address.indexOf("委员会") + 3);
  476. }
  477. return address;
  478. }
  479. public static String townReplaceAll(String address) {
  480. address = townReplace_ct(address);
  481. return address.replaceAll("小区", "0").replaceAll("号", "0").replaceAll("弄", "0").replaceAll("室", "0").replaceAll("户", "0").replaceAll("单元", "0").replaceAll("幢", "0");
  482. }
  483. /**
  484. * 数字和文字分词返回List<Set<String>>
  485. *
  486. * @param input
  487. * @return
  488. */
  489. public static List<Set<String>> tokenizeString(String input) {
  490. // 初始化两个集合,一个用于存储非数字字符串,一个用于存储数字字符串
  491. Set<String> nonNumberSet = new HashSet<>();
  492. Set<String> numberSet = new HashSet<>();
  493. StringBuilder currentToken = new StringBuilder();
  494. for (int i = 0; i < input.length(); i++) {
  495. char c = input.charAt(i);
  496. if (Character.isDigit(c)) {
  497. // 如果当前字符是数字
  498. if (currentToken.length() > 0 && !Character.isDigit(currentToken.charAt(0))) {
  499. // 如果之前的 token 是非数字,将其添加到非数字集合中
  500. nonNumberSet.add(currentToken.toString());
  501. currentToken.setLength(0);
  502. }
  503. currentToken.append(c);
  504. } else {
  505. // 如果当前字符不是数字
  506. if (currentToken.length() > 0 && Character.isDigit(currentToken.charAt(0))) {
  507. // 如果之前的 token 是数字,将其添加到数字集合中
  508. numberSet.add(currentToken.toString());
  509. currentToken.setLength(0);
  510. }
  511. if (!Character.isWhitespace(c)) {
  512. currentToken.append(c);
  513. }
  514. }
  515. }
  516. // 处理最后一个 token
  517. if (currentToken.length() > 0) {
  518. if (Character.isDigit(currentToken.charAt(0))) {
  519. numberSet.add(currentToken.toString());
  520. } else {
  521. nonNumberSet.add(currentToken.toString());
  522. }
  523. }
  524. // 将两个集合添加到列表中
  525. List<Set<String>> result = new ArrayList<>();
  526. result.add(nonNumberSet);
  527. result.add(numberSet);
  528. return result;
  529. }
  530. }