是否有一种简短而优雅的方式来反转映射功能?
问题是这样的:我有一堆类型为A的对象,我需要映射到类型B,对B对象执行过滤,然后返回到相应的A对象。
提供一些细节和示例: 我有一个批量过滤功能
Collection<CarVO> myFilter(Collection<CarVO> originalCollection);
和Collection<Car> cars
,最后是映射方法Car#toVO()
。
我想出了这段代码:
Collection<Car> filtered = cars.stream()
.filter(car -> !myFilter(Collections.singleton(car)).isEmpty())
.collect(toList());
但我怀疑这个效率不高,因为我逐个过滤对象。 其他方式做同样的事情:
Map<Car, CarVO> map = new HashMap<>();
for (Car car : cars) map.put(car, car.toVO());
Collection<CarVO> filteredVOs = myFilter(map.values());
cars = cars.stream.filter(car -> filteredVOs.contains(map.get(car))).collect(toList());
但我不想明确地建造地图。
UPD:谢谢大家, 不知道Map.values()
返回了实时视图。我会坚持使用retainAll()
。
答案 0 :(得分:2)
由于您的方法myFilter(Collection<CarVO>)
必须决定是否应删除每个元素,并且您认为即使对于单元素集合也是如此,因此必须能够将逻辑提取到单个元素中-item Predicate
。使用该提取的谓词将是最有效的解决方案。
但是,如果您不能这样做并且无论出于何种原因使用此现有方法,您可以按如下方式使用它:
Map<Car, CarVO> map = new HashMap<>();
for(Car car: cars) map.put(car, car.toVO());
map.values().retainAll(myFilter(map.values()));
Set<Car> filtered=map.keySet();
如果您确实需要列表,可以用
替换最后一行List<Car> filtered=new ArrayList<>(map.keySet());
请注意,这假设myFilter
返回一个新集合。如果通过从中删除元素将过滤器直接应用于其集合参数,则可以将map.values().retainAll(myFilter(map.values()));
替换为myFilter(map.values());
答案 1 :(得分:0)