使用SpringBoot 2和Poi类(兴趣点):
public class Poi {
public Poi(String poidId, Double price, Double latitude, Double longitude) {...}
private String poidId;
private Double latitude;
private Double longitude;
private Double price;
//And Getters and Setters
}
我有2个Poi通量:
Flux<Poi> availablePoisFlux;
Flux<Poi> poiFlux;
第一个元素 availablePoisFlux 包含具有以下内容的Pois:
第二个元素 poiFlux 包含Pois,且具有:
(poidId是Poi的标识符)。
我想从两个通量(poiFlux和availablePoisFlux)中使用Pois(具有poidId,价格,经度和纬度)创建一个新的Flux resultPoisFlux 。
poidId属性是两个Flux(poiFlux和availablePoisFlux)之间的键。
示例实现:
我想我可以使用zipWith运算符来做到这一点,但是我需要有关反应式运算符(和filter吗?)的一些信息和建议
我想使用poidId标识符从第一个通量进行迭代,并从第二个通量获取信息(价格),并使用正确的值更新price属性。
样本输入值:
poiFlux = Poi(poidId=poiId0, price=null, name=name0, latitude=2.2222, longitude=14.222)
poiFlux = Poi(poidId=poiId1, price=null, name=name1, latitude=3.2222, longitude=15.222)
poiFlux = Poi(poidId=poiId2, price=null, name=name2, latitude=4.2222, longitude=16.222)
poiFlux = Poi(poidId=poiId3, price=null, name=name3, latitude=5.2222, longitude=17.222)
poiFlux = Poi(poidId=poiId4, price=null, name=name4, latitude=6.2222, longitude=18.222)
poiFlux = Poi(poidId=poiId5, price=null, name=name5, latitude=7.2222, longitude=19.222)
poiFlux = Poi(poidId=poiId6, price=null, name=name6, latitude=8.2222, longitude=20.222)
poiFlux = Poi(poidId=poiId7, price=null, name=name7, latitude=9.2222, longitude=21.222)
poiFlux = Poi(poidId=poiId8, price=null, name=name8, latitude=10.2222, longitude=22.222)
poiFlux = Poi(poidId=poiId9, price=null, name=name9, latitude=11.2222, longitude=23.222)
availablePoisFlux = Poi(poidId=poiId0, price=120.0, name=name0, latitude=null, longitude=null)
availablePoisFlux = Poi(poidId=poiId1, price=120.0, name=name1, latitude=null, longitude=null)
availablePoisFlux = Poi(poidId=poiId2, price=120.0, name=name2, latitude=null, longitude=null)
availablePoisFlux = Poi(poidId=poiId3, price=120.0, name=name3, latitude=null, longitude=null)
availablePoisFlux = Poi(poidId=poiId4, price=120.0, name=name4, latitude=null, longitude=null)
预期结果:
resultPoisFlux = Poi(poidId=poiId0, price=120.0, name=name0, latitude=2.2222, longitude=14.222)
resultPoisFlux = Poi(poidId=poiId1, price=120.0, name=name1, latitude=3.2222, longitude=15.222)
resultPoisFlux = Poi(poidId=poiId2, price=120.0, name=name2, latitude=4.2222, longitude=16.222)
resultPoisFlux = Poi(poidId=poiId3, price=120.0, name=name3, latitude=5.2222, longitude=17.222)
resultPoisFlux = Poi(poidId=poiId4, price=120.0, name=name4, latitude=6.2222, longitude=18.222)
类似的东西:
Flux<Poi> resultPoisFlux = availablePoisFlux.zipWith(poiFlux, (a, b) -> new Poi(a.getPoidId(), a.getPrice(), getLatitudeFromPoiFluxByPoidId(a.getPoidId()), getLongitudeFromPoiFluxByPoidId(a.getPoidId())))....
感谢您的帮助。
答案 0 :(得分:1)
zip/zipWith
,但它只能成对组合两个来源... ...只要它具有足够的元素来配对。因此,只有在保证两个元素中的元素顺序相同并且两边poiIds
中没有差异的情况下,这才有用。在您的示例中,之所以如此,是因为即使第二个源仅包含4个元素,这些元素也与第一个源的开头相同。
poiFlux.zipWith(availablePoisFlux, (a, b) -> new Poi(a.getPoiId(),
b.getPrice(),
a.getLatitude(),
a.getLongitude(),
a.getName()));
如果没有这样的保证,则需要以某种方式组合两个无序和不相交的序列。如果不收集一个源中的所有元素(最好是availablePoisFlux
),就无法做到这一点,这意味着它将延迟另一个源的处理,直到所述源完成为止。
一种组合方式是将所有值收集到以poiId
为键的映射中,然后在第二个源上“迭代”。由于在地图中可能找不到某些元素,因此您需要handle
才能“跳过”这些元素:
availablePoisFlux.collectMap(Poi::getId, Poi::getPrice)
.flatMapMany(knownPrices -> poiFlux.handle((poi, sink) -> {
String poiId = poi.getPoiId();
if (knownPrices.containsKey(poiId) {
Double price = knownPrices.get(poiId);
Poi complete = new Poi(poiId, price, poi.getLatitude(),
poi.getLongitude(), poi.getName());
sink.next(complete);
} //else do nothing and let handle skip that poi
}));