为了账号安全,请及时绑定邮箱和手机立即绑定

分类器和下游和只使用分类器有什么区别

分类器和下游和只使用分类器有什么区别

森栏 2022-06-04 15:00:29
我是 Java 8 的新手,流式收集器试图了解两者之间的基本区别是什么?因为这两个代码都产生了相同的结果。一个使用return groupingBy(classifier, toList());并返回 groupingBy(classifier, HashMap::new,downstream);这是代码public class Grouping {    enum CaloricLevel { DIET, NORMAL, FAT };    public static void main(String[] args) {        System.out.println("Dishes grouped by type: " + groupDishesByType());        System.out.println("Dish names grouped by type: " + groupDishNamesByType());    }    private static Map<Type, List<Dish>> groupDishesByType() {        return Dish.menu.stream().collect(groupingBy(Dish::getType));    }    private static Map<Type, List<String>> groupDishNamesByType() {        return Dish.menu.stream().collect(groupingBy(Dish::getType, mapping(Dish::getName, toList())));    }}输出:Dishes grouped by type: {MEAT=[pork, beef, chicken], OTHER=[french fries, rice, season fruit, pizza], FISH=[prawns, salmon]}Dish names grouped by type: {MEAT=[pork, beef, chicken], OTHER=[french fries, rice, season fruit, pizza], FISH=[prawns, salmon]}菜.javapublic class Dish {    private final String name;    private final boolean vegetarian;    private final int calories;    private final Type type;    public Dish(String name, boolean vegetarian, int calories, Type type) {        this.name = name;        this.vegetarian = vegetarian;        this.calories = calories;        this.type = type;    }    public String getName() {        return name;    }    public boolean isVegetarian() {        return vegetarian;    }    public int getCalories() {        return calories;    }    public Type getType() {        return type;    }    public enum Type {        MEAT, FISH, OTHER    }    @Override    public String toString() {        return name;    }}
查看完整描述

3 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

在你的两个例子中

.collect(groupingBy(Dish::getType));
.collect(groupingBy(Dish::getType, mapping(Dish::getName, toList())));

返回值相同,因为您toString()Dish类中的方法name仅返回。尝试向toString()mehtod 添加更多信息,您会看到不同之处。

通常,groupingBy仅使用分类器允许对对象进行分组,就像在您的第一个示例中一样。但是goupingBy与分类器和下游一起使用可以让您对更多的对象进行分组,而不仅仅是您的对象。例如,您可以按类型对平均卡路里进行分组:

.collect(groupingBy(Dish::getType, averagingInt(Dish::getCalories));  // Map<Type, Double>

或者找到每种类型热量最高的菜肴

.collect(groupingBy(Dish::getType, maxBy(Comparator.comparingInt(Dish::getCalories)));  // Map<Type, Optional<Dish>>

通常groupingBy用作双重分组的下游本身(按类型和是否是素食主义者):

.collect(groupingBy(Dish::getType, groupingBy(Dish::isVegetarian)); // Map<Type, Map<Boolean, List<Dish>>>


查看完整回答
反对 回复 2022-06-04
?
阿晨1998

TA贡献2037条经验 获得超6个赞

如果这是问题

因为这两个代码都产生了相同的结果。一种使用 return groupingBy(classifier, toList()); 并返回 groupingBy(classifier, HashMap::new, 下游); ?

groupingBy(函数分类器,下游收集器)

不保证返回的 Map 的类型、可变性、可序列化性或线程安全性。

groupingBy(功能分类器,供应商mapFactory,下游收集器)

Collector 生成的 Map 是使用提供的工厂函数创建的。

唯一的区别是当您使用groupingBy时创建mapFactoryMap是基于您的供应商逻辑(可能是自定义的、不可变的、同步的等。)


查看完整回答
反对 回复 2022-06-04
?
炎炎设计

TA贡献1808条经验 获得超4个赞

两者的基本区别是什么?


主要区别在于您在完成收集器之前的中间步骤中完成的映射。不过,您使用它们的方式不同的是.groupingBy


一方面,您已将mapperanddownstream共同指定为:


.collect(Collectors.groupingBy(Dish::getType,  // classifier

             Collectors.mapping(Dish::getName,  // mapper <<<< difference here

                 Collectors.toList()))) // downstream

另一方面,的默认实现groupingBy用于


.collect(Collectors.groupingBy(Dish::getType)) 

可以扩展为类似于以下的某种格式:


.collect(Collectors.groupingBy(Dish::getType, // classifier

             Collectors.mapping(Function.identity(),  // mapper

                 Collectors.toList()))); // downstream


查看完整回答
反对 回复 2022-06-04
  • 3 回答
  • 0 关注
  • 138 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信