我刚接触过Java 8和streams收集器,试图了解两者之间的基本区别是什么?
因为这两段代码的结果都是一样的。一个使用return groupingBy(classifier, toList());并返回groupingBy(分类器,HashMap::new,下游);
这是代码
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]}Dish.java
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"));
}
}发布于 2019-02-04 14:21:33
在你的两个例子中
.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>>>发布于 2019-02-03 17:28:08
如果这就是问题所在
因为这两段代码的结果都是一样的。一个使用返回groupingBy(分类器,toList());返回groupingBy(分类器,HashMap::new,下游);?
groupingBy(函数分类器,收集器下游)
对于返回的Map的类型、可更改性、可序列化性或线程安全性没有任何保证。
groupingBy(功能分类器,供应商mapFactory,收集器下游)
收集器生成的Map是用提供的工厂函数创建的。
唯一的区别是当您将groupingBy与mapFactory一起使用时,创建的Map基于您的供应商逻辑(可能是自定义、不可变、同步等)。
发布于 2019-02-03 17:32:13
两者之间的基本区别是什么?
主要的区别是在完成收集器之前在中间步骤中完成的映射。但是,您使用它们的方式不同,这是groupingBy的签名。
一方面,您将mapper和downstream共同指定为:
.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()))); // downstreamhttps://stackoverflow.com/questions/54505258
复制相似问题