Java 8中如何过滤Trimble API返回的对象列表?
问题描述
Trimble API返回的对象列表中存在经纬度相同的重复项:其中一个带有Trimble ID,另一个没有。需求是生成移除经纬度重复且无Trimble ID对象的列表,但当前代码无法生效,返回的列表长度与原列表完全一致。
原代码片段
public Vector<TrimblePlacesData> showModificationList(Vector<TrimblePlacesData> listOfTrimbleApiLocations) { Vector<TrimblePlacesData> customList = new Vector<>(); System.out.println("Initial Size of the List: " + listOfTrimbleApiLocations.size()); for (TrimblePlacesData place : listOfTrimbleApiLocations) { for (final Iterator<TrimblePlacesData> iter = customList.listIterator(); iter.hasNext();) { final TrimblePlacesData next = iter.next(); boolean isLatitudeMatch = place.geometry.lat.equals(next.geometry.lat); boolean isLongitudeMatch = place.geometry.lon.equals(next.geometry.lon); boolean trimbleIDCheck = next.trimblePlaceId == null || next.trimblePlaceId.isEmpty(); if (isLatitudeMatch && isLongitudeMatch && trimbleIDCheck) { iter.remove(); } } System.out.println(place); customList.add(place); } return customList; }
问题根源
原逻辑仅处理了先出现无Trimble ID、后出现有Trimble ID的重复场景:当遍历到有ID的项时,会移除customList中已存在的同经纬度无ID项,再加入有ID项。但如果原列表顺序是先出现有ID项、后出现无ID项,此时customList中已有的同经纬度项是有ID的,trimbleIDCheck条件不成立,不会移除已有项,反而会把无ID项直接加入列表,导致重复项残留。
此外,原逻辑没有从根源阻止无ID重复项被添加,本质是依赖遍历顺序的脆弱逻辑,无法覆盖所有重复场景。
修复方案
改用HashMap以经纬度为唯一标识,优先保留带Trimble ID的项,从根源避免重复:
public Vector<TrimblePlacesData> showModificationList(Vector<TrimblePlacesData> listOfTrimbleApiLocations) { // 用经纬度拼接字符串作为key,确保每个经纬度仅保留一个最优项 Map<String, TrimblePlacesData> locationMap = new HashMap<>(); for (TrimblePlacesData place : listOfTrimbleApiLocations) { String latLonKey = place.geometry.lat + "_" + place.geometry.lon; TrimblePlacesData existingPlace = locationMap.get(latLonKey); if (existingPlace == null) { // 该经纬度无记录,直接存入 locationMap.put(latLonKey, place); } else { // 判断是否需要替换:仅当现有项无ID、当前项有ID时,替换为有ID的项 boolean existingHasNoId = existingPlace.trimblePlaceId == null || existingPlace.trimblePlaceId.isEmpty(); boolean currentHasId = place.trimblePlaceId != null && !place.trimblePlaceId.isEmpty(); if (existingHasNoId && currentHasId) { locationMap.put(latLonKey, place); } // 其他情况:现有项有ID,无论当前项是否有ID,都保留现有项 } } // 将Map中的最优项转为Vector返回 Vector<TrimblePlacesData> customList = new Vector<>(locationMap.values()); System.out.println("Final Size of the List: " + customList.size()); return customList; }
代码说明
- 去重逻辑:通过
HashMap的key唯一性,确保每个经纬度仅存一个对象 - 优先级处理:始终优先保留带有Trimble ID的项,仅当已有记录无ID时,才用有ID的项替换
- 性能优化:时间复杂度从原逻辑的O(n²)降到O(n),遍历一次即可完成处理
内容的提问来源于stack exchange,提问作者Muhammad Shakir
相关产品推荐
相关产品推荐

