首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分类器和下游分类器有什么区别,只使用分类器

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

Stack Overflow用户
提问于 2019-02-03 16:55:44
回答 3查看 431关注 0票数 2

我刚接触过Java 8和streams收集器,试图了解两者之间的基本区别是什么?

因为这两段代码的结果都是一样的。一个使用return groupingBy(classifier, toList());并返回groupingBy(分类器,HashMap::new,下游);

这是代码

代码语言:javascript
复制
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())));
    }
}

产出:

代码语言:javascript
复制
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]}

Dish.java

代码语言:javascript
复制
public 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;
    }

    public static final List<Dish> menu = asList(
            new Dish("pork", false, 800, Dish.Type.MEAT),
            new Dish("beef", false, 700, Dish.Type.MEAT), 
            new Dish("chicken", false, 400, Dish.Type.MEAT),
            new Dish("french fries", true, 530, Dish.Type.OTHER), 
            new Dish("rice", true, 350, Dish.Type.OTHER),
            new Dish("season fruit", true, 120, Dish.Type.OTHER), 
            new Dish("pizza", true, 550, Dish.Type.OTHER),
            new Dish("prawns", false, 400, Dish.Type.FISH), 
            new Dish("salmon", false, 450, Dish.Type.FISH));

    public static final Map<String, List<String>> dishTags = new HashMap<>();

    static {
        dishTags.put("pork", asList("greasy", "salty"));
        dishTags.put("beef", asList("salty", "roasted"));
        dishTags.put("chicken", asList("fried", "crisp"));
        dishTags.put("french fries", asList("greasy", "fried"));
        dishTags.put("rice", asList("light", "natural"));
        dishTags.put("season fruit", asList("fresh", "natural"));
        dishTags.put("pizza", asList("tasty", "salty"));
        dishTags.put("prawns", asList("tasty", "roasted"));
        dishTags.put("salmon", asList("delicious", "fresh"));
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-02-04 14:21:33

在你的两个例子中

代码语言:javascript
复制
.collect(groupingBy(Dish::getType));
.collect(groupingBy(Dish::getType, mapping(Dish::getName, toList())));

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

通常,使用groupingBy只使用分类器可以对对象进行分组,如第一个示例所示。但是,将goupingBy与分类器和下游结合使用,可以对对象进行分组,而不仅仅是对对象进行分组。例如,您可以将平均卡路里按类型分组。

代码语言:javascript
复制
.collect(groupingBy(Dish::getType, averagingInt(Dish::getCalories));  // Map<Type, Double>

或者找到最热的菜,每种类型的

代码语言:javascript
复制
.collect(groupingBy(Dish::getType, maxBy(Comparator.comparingInt(Dish::getCalories)));  // Map<Type, Optional<Dish>>

通常,groupingBy作为一个下游本身用于双重分组(按类型和如果它是植物人):

代码语言:javascript
复制
.collect(groupingBy(Dish::getType, groupingBy(Dish::isVegetarian)); // Map<Type, Map<Boolean, List<Dish>>>
票数 1
EN

Stack Overflow用户

发布于 2019-02-03 17:28:08

如果这就是问题所在

因为这两段代码的结果都是一样的。一个使用返回groupingBy(分类器,toList());返回groupingBy(分类器,HashMap::new,下游);?

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

对于返回的Map的类型、可更改性、可序列化性或线程安全性没有任何保证。

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

收集器生成的Map是用提供的工厂函数创建的。

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

票数 1
EN

Stack Overflow用户

发布于 2019-02-03 17:32:13

两者之间的基本区别是什么?

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

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

代码语言:javascript
复制
.collect(Collectors.groupingBy(Dish::getType,  // classifier
             Collectors.mapping(Dish::getName,  // mapper <<<< difference here
                 Collectors.toList()))) // downstream

另一方面,groupingBy

代码语言:javascript
复制
.collect(Collectors.groupingBy(Dish::getType)) 

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

代码语言:javascript
复制
.collect(Collectors.groupingBy(Dish::getType, // classifier
             Collectors.mapping(Function.identity(),  // mapper
                 Collectors.toList()))); // downstream
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54505258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档