我有3个对象。 Foo由Bars组和Bar由Baz组组成。鉴于Foo,我应该如何迭代并使用distinct()来获得不同的baz和不同的柱线?
我有以下代码:
//Updated
class Foo{
Integer fooId;
Set<Integer> barSetOfIds ;
//getter&setter
}
and FooRepo{
Mono<Foo> find(Integer fooId);
}
class Bar{
Integer barId;
Set<Integer> bazSetOfIds ;
//getter&setter
}
and BarRepo{
Mono<Bar> find(Integer barId);
}
class Baz{
Integer bazId;
}
and BazRepo{
Flux<Baz> find(Integer bazid);
}
所以我实际上尝试过
呼叫代码: ///某些方法
Mono<Boolean> monoPresent = fooRepo
.find(fooId)
.filter(i -> i.getFooId() != null)
.hasElement();
return monoPresent.flatMap(isPresent -> {
if (isPresent) {
return fooRepo.find(fooId)
.map(fooFromDB -> {//fooFromDB is instance of Foo returned
fooRepo.update(fooFromDB);
return processDistinct(fooFromDB);
})
.then();
} else {//
return Mono.error(new SomeException("foo")
.then();
}
}
);
//below method gets called
Flux<Integer> processDistinct(Foo pkg) {
System.out.println("INSIDE ");
Flux<Integer> cids = Flux.fromIterable(pkg.getBarListIds())
.flatMap(p ->
{
System.out.println("barInteger=" + p.intValue());
return barRepo.find(p);
}
).flatMapIterable(
x -> {
System.out.println("cids=" + x.getBazListIds().size());
return x.getBazListIds();
}
)
.distinct()
.doOnNext(x -> System.out.println("Inside doOnNext=" + x));
//So here only on block do I see distinct values printed else code just passes
List<Integer> list2 = cids.collectSortedList().block();
list2.forEach(cidints -> System.out.println("cids=" + cidints));
return cids;
}
仅当我阻止()时,我才能看到cids(变量)值
更新: 使用Michael的建议(进行一些更改)processDistinct中的以下方法也可以使用,但仍然需要阻止,这导致我怀疑调用代码而不是processDistict [?]。
processDistinct(Foo foo){
Flux<Integer> distinctBazzFluxIds = fooRepo
.find(foo.getFooId())
.flatMapIterable(Foo::getBarSetOfIds)
.flatMap(barId -> {
return barRepo.find(barId);
}).flatMapIterable(bar-> bar.getBazSetOdIds()).distinct()
.doOnNext(bazId -> {
System.out.println("Inside doOnNext"+cid);
new SomeService().sendDistinct(cid);
});
更新(固定): 因此,我很愚蠢地从调用流的doOnNext内部调用此processDistinct,并且我认为流正在丢失(我需要一些更好的解释)。我解决了这个问题,现在可以了。但是不确定为什么会丢失流的原因以及正确的解释。
Mono<Boolean> monoPresent = fooRepo
.find(fooId)
.filter(i -> i.getFooId() != null)
.hasElement();
return monoPresent.flatMap(isPresent -> {
if (isPresent) {
return fooRepo
.find(foo.getFooId())
.flatMapIterable(Foo::getBarSetOfIds)
.flatMap(barId -> {
return barRepo.find(barId);
}).flatMapIterable(bar -> bar.getBazSetOdIds()).distinct()
.doOnNext(bazId -> {
System.out.println("Inside doOnNext" + cid);
new SomeService().sendDistinct(cid);
}).then();
} else {//SAVE
return Mono.error(new SomeException("foo")
.then();
}
});
答案 0 :(得分:0)
您的班级结构和您的问题不匹配-目前Foo
和Bar
都包含Integer
的集合,而不分别包含Bar
和Baz
的集合,并且您的Repo
类已经返回Flux
,不可迭代。
假设问题文本正确,您将具有类似于以下内容的类结构:
class Foo {
Integer fooId;
Set<Bar> barSet;
}
class Bar {
Integer barId;
Set<Baz> bazSet;
}
class Baz {
Integer bazId;
}
interface FooRepo {
Iterable<Foo> findAll();
}
...然后,您可以使用以下内容来获取(例如)所有不同的Baz
对象:
Flux<Baz> distinctBazzFlux = Flux.fromIterable(fooRepoInstance.findAll())
.flatMapIterable(Foo::getBars)
.flatMapIterable(Bar::getBazs)
.distinct();
如果只希望使用不同的Bar
对象,请删除第二个flatMapIterable()
调用。
具体来说,您需要flatMapIterable()
方法,因为flatMap()
方法只能展平Publisher
(例如另一个Flux
或Mono
)。当然,您可以先将迭代器包装在Flux
中,但是flatMapIterable()
是获得相同结果的更简洁,更简洁的方法。
如果根据您的评论,这些类包含整数集而不是对象本身,那么您可以采用类似的方法:
Flux<Baz> distinctBazzFlux = fooRepo.find(blah)
.flatMapIterable(Foo::getBars)
.map(BarRepo::find)
.flatMapIterable(Bar::getBazs)
.map(BazRepo::find)
.distinct();
在任何情况下,阻塞都是错误的解决方案,因为从本质上讲,这种方法无法解决使用反应堆的问题。