【发布时间】:2020-06-29 04:24:21
【问题描述】:
我有一个像这样的简单客户类
public class Customer {
public int age;
public int discount;
public String name;
public Customer(String name) {
this.name = name;
}
public Customer(String name, int age) {
this.name = name;
this.age = age;
}
public Customer(String name, int age, int discount) {
this.name = name;
this.age = age;
this.discount = discount;
}
@Override
public String toString() {
return "Customer [age=" + age + ", discount=" + discount + ", name=" + name + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Integer getDiscount() {
return discount;
}
public void setDiscount(int discount) {
this.discount = discount;
}
}
我使用这个填充这些对象的列表
List<Customer> customerList = new ArrayList<>(Arrays.asList(
new Customer("John", 2, 15),
new Customer("John", 4, 15),
new Customer("John", 6, 25),
new Customer("Joe", 3, 15),
new Customer("Joe", 3, 15),
new Customer("Joe", 3, 15),
new Customer("Goerge", 6, 25),
new Customer("Goerge", 6, 25),
new Customer("Mary", 7, 25),
new Customer("Jane", 1, 15),
new Customer("Jane", 2, 15),
new Customer("Jane", 8, 25),
new Customer("Jane", 8, 25)
));
现在我想使用这样的收集器对名称和折扣进行分组和计数
Map<Object, Long> collected = customerList
.stream()
.collect(Collectors.groupingBy(x -> Arrays.asList(x.name, x.discount), Collectors.counting()));
我可以使用这个来查看我的输出
collected.entrySet().forEach(c -> {
System.out.println(c);
});
输出如下
[Jane, 15]=2
[Joe, 15]=3
[John, 15]=2
[Mary, 25]=1
[John, 25]=1
[Jane, 25]=2
[Goerge, 25]=2
问题是我如何按名称和折扣排序地图,使其看起来像这样
[Goerge, 25]=2
[Jane, 15]=2
[Jane, 25]=2
[Joe, 15]=3
[John, 15]=2
[John, 25]=1
[Mary, 25]=1
我一直碰到收集器返回的 Object 类型?
我可以转换收集器以便它返回一个类,也许像
private class DiscountCounts
{
public String name;
public Integer discount;
}
是否可以将Map<**Object**, Long>() 转换为Map<DiscountCounts, Long>() 之类的东西,这是否允许使用 lambda 或 Comparator 构造访问 Map 键的字段?
我尝试了类似的方法,遍历地图并手动转换为我想要的地图,但我无法获取原始集合的键?
Map<DiscountCounts, Long> collected2 = new HashMap<>();
collected.entrySet().forEach(o -> {
DiscountCounts key1 = (DiscountCounts)o.getKey(); //--> Fails here
collected2.put((DiscountCounts)o.getKey(), o.getValue());
});
【问题讨论】:
-
您是否考虑过使用
TreeMap而不是HashMap?它会自动对其键进行排序。 -
Dawood,从下面的回复中,我可以看到 TreeMap 在这里会有什么帮助,但我永远无法很好地理解 Collector 对象来自己实现它,感谢您的建议。跨度>
标签: java collections hashmap type-conversion