Crie uma lista de valores máximos a partir de um conjunto de listas aninhadas dentro de mapas aninhadas com lambda

Stefano:

Eu sou novo em java 8 e eu preciso reescrever um velho pedaço de código para implementar uma nova alghoritm. A tarefa é a de filtrar o objeto que tem velocidade máxima para cada lista. As listas são mapas dentro aninhados: um mapa raiz de estradas, que contém mapas de segmentos de estrada e cada mapa de segmentos de estrada contém uma lista de objetos, cada um decribing velocidade medida em um intervalo de tempo. Eu preciso encontrar todas as velocidades máximas para cada lista.

Eu encontrei os seguintes links que se parece com o meu problema, mas eu não posso adaptá-los, e eu não tenho certeza minhas tentativas resolver o meu problema corretamente.

Como você filtrar loops aninhados usando Java 8 córregos e filtros?

Java 8 Filtro Map <String, List <Employee >>

Filtro no mapa de mapa

este é o código que usei como exemplo para o meu write


Map<String, Map<String, Employee>> employeeMap =
                            employeeMap.entrySet()
                                       .stream()
                                       .collect(toMap(Map.Entry::getKey,
                                                      e -> e.getValue().entrySet().stream()
                                                      .filter(emp -> !emp.getValue().getState().equals("MI"))
                                                      .collect(toMap(Map.Entry::getKey, Map.Entry::getValue))));


for(Car car : cars) {
                        for (Engine engine : car.getEngines()) {
                            for (Part part : engine.getParts()) {
                                // ...
                            }
                        }
                    }


                    cars.stream()
                        .flatMap(car -> car.getEngines().stream())
                        .flatMap(engine -> engine.getParts().stream())
                        .forEach(part -> {  ... });


este é o meu código resultante



Map<Integer, Map<Integer, List<PartialSpeed>>> speedsPerRoadPerSegment; 


ArrayList<PartialSpeed> maxSpeedPerSegment = new ArrayList<PartialSpeed>();
                    speedsPerRoadPerSegment.entrySet().stream()
                            .forEach(road-> road.getValue().entrySet()
                            .stream()
                            .forEach(segment ->
                            {
                                Optional<PartialSpeed> result = segment.getValue().stream()
                                .max(Comparator.comparing(PartialSpeed::getnVelFfs));
                                maxSpeedPerSegment.add(result.get());
                            }));


Toda a minha tentativa de aderir ao exemplo teve problemas sobre os tipos de resultados não ser reconhecido. Esta é a melhor (não funciona) eu estou sido capaz de alcançar:

speedsPerRoadPerSegment.entrySet().stream()
                            .flatMap(road-> road.getValue().entrySet()
                            .stream().flatMap(
                                    segment -> segment .getValue()
                                    .stream()
                                    .max(Comparator.comparing(PartialSpeed::getnVelFfs))
                                    ));

Como você pode ver eu apenas substituiu o antigo para loops com foreaches. Eu gostaria de entender como obter a lista de elementos máximas diretamente a partir da expressão lambda.

Holger:

Geralmente, se você usar um loop ou riacho, ao processar uma Map, você deve escolher o ponto de vista coleção direita, keySet(), entrySet(), ou values(), dependendo de quais elementos você realmente precisa. Desde que você está interessado apenas nos valores, não use entrySet().

Em seguida, aplique a operação terminal direito ao fluxo, para obter o resultado final:

List<PartialSpeed> maxSpeedPerSegment =
    speedsPerRoadPerSegment.values().stream()
        .flatMap(m -> m.values().stream())
        .map(list -> Collections.max(list, Comparator.comparing(PartialSpeed::getnVelFfs)))
        .collect(Collectors.toList());

Isto usa Collections.max, em vez de uma operação de Fluxo aninhada, que irá lançar uma exceção se a coleção está vazia (como chamar get()em um Optionalincondicionalmente vai fazer).

Se pode ocorrer listas vazias, você pode filtrá-los antes de mão:

List<PartialSpeed> maxSpeedPerSegment =
    speedsPerRoadPerSegment.values().stream()
        .flatMap(m -> m.values().stream())
        .filter(list -> ! list.isEmpty())
        .map(list -> Collections.max(list, Comparator.comparing(PartialSpeed::getnVelFfs)))
        .collect(Collectors.toList());

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=223901&siteId=1
Recomendado
Clasificación