TransWikia.com

Como agrupar y filtrar datos de una lista de objetos?

Stack Overflow en español Asked by Diego Caviedes on November 27, 2021

necesito una ayuda, tengo una lista de objetos y necesito poder agruparlos y de ese grupo solo retornar el que tenga el menor precio, el objeto inicial tiene esta estructura:

public class Producto {
  private String name;
  private String code;
  private Precio precio;
  
  // geters...
}

public class Precio {
  private Double neto;
  private Double tax;
  private Double total;
  
  // geters...
}

La lista que tengo tiene varios productos repetidos por la propiedad Producto::code, los estoy agrupando con la siguiente sentencia:

Map<String, List<Producto>> results = productos.stream()
.collect(Collectors.groupingBy(Producto::getCode, Collectors.toList()));

Con esta expresión logro tener un mapa donde agrupo por el código los productos y obtengo una lista List pero no he logrado tomar esa lista y filtrar para que solo me retorne el producto que tiene el menor precio total algo como:

List<Producto> resultReduc = results.entrySet().stream()
                        .filter(e -> e.getValue().stream().min(Comparator.comparingDouble(Precio::getTotal)))
                        .collect(Collectors.toList());

Yo sé que esto último no funciona, pero es algo por este estilo, al final lo que necesito es tener la lista de productos donde solo estén los productos con menor precio sin tener códigos repetidos, les agradezco si me dan una ayuda al respecto.

2 Answers

Cuando agrupas tambien puedes filtra los de menor precio. Modifique tu agrupacion de la siguiente forma para conseguirlo:

Map<String, Optional<Producto>> groupedProducts = products.stream().collect(
Collectors.groupingBy(
        Producto::getCode,
        Collectors.minBy(Comparator.comparingDouble((p) -> p.getPrecio().getTotal())))
);

Luego para obtener la lista de los productos mas baratos el filtro quedarias asi:

List<Producto> cheaperProducts = groupedProducts.entrySet().stream()
    .map(e -> e.getValue())
    .filter(Optional::isPresent)
    .map(p -> p.get())
    .collect(Collectors.toList());

Espero te sirva.

Saludos.

Answered by LuisDarioRL on November 27, 2021

tienes el 90% del trabajo hecho. Pero necesitas Map. A ese Map le pasas data vía List u observableList.

private List<claseModelo> listQueQuieresFiltrar;
 //Filtrado y agrupado
    Map<Integer, List<claseModelo>> actualizaConceptoTDTCTRMap = listQueQuieresFiltrar
            .stream()                
            .filter(e -> e.getEstatusVenta().equals( "Activa")) //incluyo solo las ventas activas
            .filter(e->e.getEstatus()== (null) || e.getEstatus()=="Cancelada" || e.getEstatus()== "")//Ingresa solo las que están en estring vacío, null o canceladas.             
            .collect(Collectors.groupingBy(claseModelo::getIdventa));

Si te das cuenta, en el Map filtro según sea el caso

Answered by Sidsi on November 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP