web-dev-qa-db-fra.com

Quelle est la différence entre groupingby et mapping dans Collectors (Java)?

Jetez un oeil à ce morceau de code.

// group by price, uses 'mapping' to convert List<Item> to Set<String>
    Map<BigDecimal, Set<String>> result =
            items.stream().collect(
                    Collectors.groupingBy(Item::getPrice,
                            Collectors.mapping(Item::getName, Collectors.toSet())
                    )
            );

Le groupement By et Mapping sont-ils interchangeables? Quelles sont leurs différences?

Pour le troisième paramètre de collect (), aurais-je le même type de sortie Map si j'utilisais Collectors.toList () au lieu de Collectors.toSet ()? J'ai entendu dire que toList () est une option plus populaire.

15
NoMoreErrors

Le groupement By et Mapping sont-ils interchangeables?

Non, ils sont complètement différents. groupingBy vous permet de créer un Map où la clé est le premier argument passé à groupingBy et la valeur est un List du type d'élément du Stream.

Collectors.groupingBy(Item::getPrice) générerait un Map<BigDecimal, List<Item>> (en supposant que Item::getPrice renvoie un BigDecimal. Passer le mappingCollector comme argument à Collectors.groupingBy() vous permet de modifier la valeur de la carte de sortie (dans votre exemple, vous la changez en Set<String>).

Pour le troisième paramètre de collect (), aurais-je le même type de sortie Map si j'utilisais Collectors.toList () au lieu de Collectors.toSet ()?

Non, vous obtiendrez un Map<BigDecimal, List<String>>.

17
Eran

Non, les deux sont complètement différents.

Collectors.groupingBy Prend une fonction qui crée des clés et renvoie un collecteur qui renvoie une carte des clés aux collections d'objets du flux qui ont cette même clé.

Collectors.mapping, D'autre part, prend une fonction et un autre collecteur, et crée un nouveau collecteur qui applique d'abord la fonction, puis recueille les éléments mappés à l'aide des collecteurs donnés. Ainsi, les éléments suivants sont équivalents:

items.stream().map(f).collect(c);
items.stream().collect(Collectors.mapping(f, c));

Collectors.mapping Est le plus utile dans les situations où vous n'avez pas de flux, mais vous devez passer directement un collecteur. Un exemple d'une telle situation est lors de l'utilisation de Collectors.groupingBy.

items.stream().collect(Collectors.groupingBy(Item::getPrice, Collectors.toSet()))

renvoie un Map<BigDecimal,Set<Item>> (en supposant que getPrice() renvoie un BigDecimal). cependant,

items.stream().collect(Collectors.groupingBy(Item::getPrice,
    Collectors.mapping(Item::getName, Collectors.toSet())))

renvoie un Map<BigDecimal,Set<String>>. Avant de récupérer les articles, il leur applique d'abord Item.getName.

15
Hoopje