javaspring-bootspring-webflux

How to implement nested loops using spring webflux


have implemented below logic in spring webflux application and fetchResult(resultKeys) is invoking before even generating resultKeys, which is required to call the fetchResult method. so how to convert below nested loops to spring webflux so that fetchResult() would be called after generating resultKeys.

    Map<MKey, Match> matchesByCom = intermediateObject.getMatchDetails();
        Set<String> resultKeys = new HashSet<>();
        intermediateObject.getNames().forEach(name -> {
            final Set<String> distinctIdsFinal = intermediateObject.getNameToIdMapping().get(name);

            matchesByCom.keySet().parallelStream().filter(mKey -> mKey.getName().equals(name))
                    .forEach(mKey -> {
                        if (CollectionUtils.isEmpty(distinctIdsFinal)
                                || (CollectionUtils.isEmpty(requestDTO.getLIds()))) {
                            resultKeys.add(name + mKey.getCom());

                        }

                        if (CollectionUtils.isNotEmpty(distinctIdsFinal)) {
                            distinctIdsFinal.forEach(Id -> {
                                resultKeys.add(name + mKey.getCom() + "_" +Id);

                            });
                        }

                    });
        });

            resultIdSetMono = fetchResult(resultKeys)


Solution

  • You could try something like this to achieve what you want

    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    public Mono<Result> processIntermediateObject(IntermediateObject intermediateObject, RequestDTO requestDTO) {
        // Start with a Flux from the names
        return Flux.fromIterable(intermediateObject.getNames())
            .flatMap(name -> {
                // Fetch distinct IDs for the name
                Set<String> distinctIdsFinal = intermediateObject.getNameToIdMapping().getOrDefault(name, Collections.emptySet());
    
                // Filter matches by name and process them
                return Flux.fromIterable(intermediateObject.getMatchDetails().keySet())
                    .filter(mKey -> mKey.getName().equals(name))
                    .flatMap(mKey -> {
                        // Add keys based on conditions
                        if (CollectionUtils.isEmpty(distinctIdsFinal) || CollectionUtils.isEmpty(requestDTO.getLIds())) {
                            return Mono.just(name + mKey.getCom());
                        }
    
                        if (CollectionUtils.isNotEmpty(distinctIdsFinal)) {
                            return Flux.fromIterable(distinctIdsFinal)
                                .map(Id -> name + mKey.getCom() + "_" + Id);
                        }
    
                        return Mono.empty(); // No keys to add
                    });
            })
            .collect(Collectors.toSet()) // Collect all generated keys into a Set
            .flatMap(resultKeys -> {
                // Call fetchResult with the fully populated set of keys
                return fetchResult(resultKeys);
            });
    }