i have an api that returns CompletableFuture
where CardItem{
cardType
cardStatus
cardDetails
}
but i'd like to iterate through the CompletableFuture and build a parent children object class where if cardType = Header is the parent. and the rest of the CardItems are children.
like Mono
where CardItemRO {
cardType= header
cardStatus
cardDetails
List
}
You have map the list of completableFuture to List of Mono. then use Flux.fromIterable to iterate the list of Mono's
Mono<List<CardItem>> mapCompletableFutureToMono=listOfCompletableFuture.map { Mono.fromFuture(it) }.toList()
Flux.fromIterable(mapCompletableFutureToMono).flatMap { it }.collectList().map{cardItem-> // do something}
Related
My DB is returning Flux
I need to convert it to Mono<List> of DTO and return it to caller method. My Fruit class already has a builder method to convert Fruit to FruitDto.
If the return type of the caller method had only Mono, I could have easily mapped it as follows but since its Mono<List> I'm facing difficulty
public Mono<List<FruitDto>> findAllBySearchKeys(String id){
//expecting to convert Flux of Fruit to Mono of List of FruitDto and return to caller
return fruitRepo.findAllById(bol, status)
.flatMap(document -> {
return Mono.just(document.get(0).dto());
});
}
Seems like you are looking for Flux.collectList()
For example:
Flux<String> response = Flux.just("a", "b", "c");
Mono<List<String>> listMono = response.collectList();
Check the documentation.
I have the list of beans autowired by an interface in my application with Kotlin and Spring-boot.
#Autowired
private var pages: List<Paging>
In post construct i sort beans by class simple name
#PostConstruct
fun setUp(){
pages.sortedBy { it.javaClass.simpleName }
pages.forEach { log.info("{}", it::class.simpleName) }
}
I see next results
page.month.Page19M#69cf9dd
page.month.Page04#43be5d62
page.month.Page03#5d34e3b3
page.month.Page13#151b7c03
page.month.Page16#6e71c9dc
page.month.Page17#7fe14f94
page.month.Page12#1f502e65
page.month.Page18#7d4d32a7
page.month.Page07#65c29c4c
page.month.Page06#5387e079
page.month.Page15#249dd7e6
page.month.Page11#56f13088
page.month.Page14#29ef49a1
page.month.Page10#76dc4e
page.month.Page09#c59b505
page.month.Page01#30c6e2e
page.month.Page02w#46bde78e
page.month.Page05#7500f8f0
page.month.Page08#7c5810e4
Beans weren't sorted by simple name.
But when i use stream style
pages.stream()
.sorted { o1, o2 -> o1.javaClass.simpleName.compareTo(o2.javaClass.simpleName) }
.forEach { i -> log.info("{}", i.javaClass.simpleName) }
I see sorted results
page.month.Page01#30c6e2e
page.month.Page02w#46bde78e
page.month.Page03#5d34e3b3
page.month.Page04#43be5d62
page.month.Page05#7500f8f0
page.month.Page06#5387e079
page.month.Page07#65c29c4c
page.month.Page08#7c5810e4
page.month.Page09#c59b505
page.month.Page10#76dc4e
page.month.Page11#56f13088
page.month.Page12#1f502e65
page.month.Page13#151b7c03
page.month.Page14#29ef49a1
page.month.Page15#249dd7e6
page.month.Page16#6e71c9dc
page.month.Page17#7fe14f94
page.month.Page18#7d4d32a7
page.month.Page19M#69cf9dd
I don't understand why results are different.
I tried use just a class with a field - works ok.
What do i miss?
The sortedBy method in the Kotlin Standard Library does not perform in-place sorting. Instead, it returns a new sorted list.
In the code you have shared, you sort the list using pages.sortedBy{ ... } but ignore the result of this operation. The pages variable therefore remains unmodified, and you get the same list as before when you iterate over it using forEach.
If you instead iterate over the sorted list, you'll get the desired result:
val sortedPages = pages.sortedBy { page -> page.javaClass.simpleName }
sortedPages.forEach { sortedPage -> println(sortedPage) }
You can shorten this further by iterating directly over the result returned after sorting the list:
pages.sortedBy { page -> page.javaClass.simpleName }
.forEach { sortedPage -> println(sortedPage) }
You can try out this sample code to verify.
I have a class with properties that have their getter and setter each.
I load a list of this class with values from a DB, and I need to create a function that can make a filter over this stream calling different method from the class.
Example:
listActionfilter.stream()
.filter(u -> u.getAccion().toUpperCase().trim().contains(accion))
.collect(Collectors.toList());
I need to do is this:
function xxx('**methodtosearch**', '**valuetosearch**') {
listActionfilter.stream()
.filter(u -> u.('**methodtosearch**')
.toUpperCase().trim().contains('**valuetosearch**'))
.collect(Collectors.toList());
}
Is this possible?
Your function could have the following signature (assuming the object is an ListAction object...
public List<ListAction> function(Predicate<ListAction> predicate) {
return listActionfilter.stream()
.filter(predicate)
.collect(Collectors.toList());
}
And call it the following way
function(u -> u.getAccion().toUpperCase().trim().contains(accion));
Assuming that all your target methods returns String, you can use this :
public List<Action> xxx(Function<Action, String> methodSelector, String valueToMatch) {
return listActionfilter.stream()
.filter(t -> methodSelector.apply(t).toUpperCase().trim(). contains(valueToMatch))
.collect(Collectors.toList());
}
You can invoke the method like this :
List<Action> list1 = xxx(Accion::method1, "value1")
List<Action> list2 = xxx(Accion::method2, "value2")
Edited:
I'm querying some XML into objects recursively. Each object has a list of sub objects, and should refer to it's parent if it has one.
Example XML:
<object attribute1="text" attribute2="text"/>
<object attribute1="text" attribute2="text">
<object attribute1="text" attribute2="text">
<object attribute1="text" attribute2="text">
</object>
Example Linq:
private static List<MyObject> ParseMyObjects(XElement node, MyObject p)
{
List<MyObject> myobjs = (from x in node.Elements("object")
select new MyObject {
attribute1 = x.Attribute("attribute1 ").Value,
attribute2 = x.Attribute("attribute2 ").Value,
subObjects = ParseMyObjects(x, this), // the "this" key word can't refer to the MyObject being created in the query, but is there some other way of doing this?
parent= p
}).ToList();
return myobjs;
}
To accomplish this currently, I am recursively traversing the MyObjects list AFTER it has been queried and setting each parent (the "parent" line above is excluded).
I would simply prefer a more elegant solution of using the newly instantiated object within the Linq query if possible. Any ideas?
Edit:
To clarify (as BrokenGlass did in a comment), the this that the code comment is referring to is the instance of MyObject that is being created within the query
this can't work in a method marked static ever. There is no instance because the method is static.
I would simply prefer a more elegant solution of using the newly instantiated object within the Linq query if possible. Any ideas?
Just use XObject.Parent as in
parent = x.Parent
If you want the Parent member of the created MyObject instance to point to the instance itself, there are two ways to achieve this without adding code that iterates over the list after the Linq query:
1) Add a constructor that sets it up for you, e.g. the default constructor
public MyObject() {
this.Parent = this;
}
2) Add a fluent-interface style method for setting the parent, and invoke it in the query:
/* in class MyObject */
public MyObject WithSelfAsParent() {
this.Parent = this;
return this;
}
/* updated linq query */
List<MyObject> myobjs = (from x in node.Elements("object")
select new MyObject {
attribute1 = x.Attribute("attribute1 ").Value,
attribute2 = x.Attribute("attribute2 ").Value,
subObjects = ParseMyObjects(x),
}.WithSelfAsParent()).ToList();
Whether these are better than explicitly looping over the list is of course a matter of taste. I would probably just keep it simple and choose the loop, unless the assumption that the parent pointer is equal to this by default is obvious in the context of your MyObject class, which makes setting it in the default constructor the natural choice.
The solution for me was to harness the set of the subObjects property on MyObject.
class MyObject {
....
private List<MyObject> _subObjects = new List<MyObject>();
public List<MyObject> subObjects
{
get { return _subObjects ; }
set
{
_subObjects = value;
if(_subObjects != null)
{
foreach(MyObject o in _subObjects )
{
o.parent = this;
}
}
}
}
....
}
If anyone does know of a way to reference the newly created/selected object within the Linq syntax, I will mark your answer as the corrrect one.
The GDK docs indicate that Collection.sort(Comparator comparator) does not change the collection it is called on, but the code below indicates otherwise. Is this a bug in the implementation, error in the docs, or a misunderstanding on my part?
class ISO3LangComparator implements Comparator<Locale> {
int compare(Locale locale1, Locale locale2) {
locale1.ISO3Language <=> locale2.ISO3Language
}
}
List<Locale> locales = [Locale.FRENCH, Locale.ENGLISH]
def sortedLocales = locales.sort(new ISO3LangComparator())
// This assertion fails
assert locales[0] == frenchLocale
the documentation states:
If the Collection is a List, it is
sorted in place and returned.
Otherwise, the elements are first
placed into a new list which is then
sorted and returned - leaving the
original Collection unchanged.
which is reflected in the implementation of the sort() method
public static <T> List<T> sort(Collection<T> self, Comparator<T> comparator) {
List<T> list = asList(self);
Collections.sort(list, comparator);
return list;
}
the asList method looks whether the given collection is an instanceof java.util.List. If yes, it returns the reference, if not it returns a new java.util.ArrayList instance.
since you are using the [] syntax you are implicitly working with an instance of java.util.List.