Stream API的收集器,按零计数字段分组

huangapple 未分类评论43阅读模式
英文:

Stream api collectors grouping by zero counted fileds

问题

我有一个对象,有一个字段 type1 用于创建第一组,还有两个字段用于创建第二组。但第二组始终会得到这三个值中的一个 (X、Y、Z)。此时我编写了如下的代码:

Map<String, Map<String, Long>> result = objList.stream()
    .collect(Collectors.groupingBy(Obj::type1,
        Collectors.groupingBy(Obj::useTwoFieldToGetSecondGroup, Collectors.counting())))

这段代码的结果如下:

{
  "A":{
     "Y":5,
     "Z":3
  },
  "B":{
     "Y":2,
     "Z":1
  },
  "C":{
     "X":2
  },
  "D":{
     "X":6,
     "Z":2
  }
}

但我知道第二类型始终有三种类型的值,我希望看到类似以下的结果:

{
  "A":{
     "X":0,
     "Y":5,
     "Z":3
  },
  "B":{
     "X":0,
     "Y":2,
     "Z":1
  },
  "C":{
     "X":2,
     "Y":0,
     "Z":0
  },
  "D":{
     "X":6,
     "Y":0,
     "Z":2
  }
}

是否有方法可以轻松地获得这样的结果?

public class Obj {
   
   private String type1; // 第一个映射的键

   private String field1; // 通过这两个字段计算出的第二个键
   private String field2;

   public String useTwoFieldToGetSecondGroup(){
       // 使用 field1 和 field2 来获取 X、Y 或 Z
   }

}

并且 useTwoFieldToGetSecondGroup 方法如下

```java
private String useTwoFieldToGetSecondGroup() {
    if (field1 && field2) {
        return "X";
    } else if (!field1 && field2) {
        return "Y";
    } else {
        return "Z";
    }
}
英文:

I have an object has a filed type1 used to create first group and i have two fields are used to create second group. But second group always get one of theese three values (X,Y,Z). At this point i wrote a code like this :

Map&lt;String, Map&lt;String, Long&gt;&gt; result = objList.stream()
			.collect(Collectors.groupingBy(Obj::type1,
					 Collectors.groupingBy(Obj::useTwoFieldToGetSecondGroup, Collectors.counting())))

As result of this code i get this :

{
  &quot;A&quot;:{
     &quot;Y&quot;:5,
     &quot;Z&quot;:3
  },
  &quot;B&quot;:{
     &quot;Y&quot;:2,
     &quot;Z&quot;:1
  },
  &quot;C&quot;:{
     &quot;X&quot;:2
  },
  &quot;D&quot;:{
     &quot;X&quot;:6,
     &quot;Z&quot;:2
  }

}

But i know second type has always three types of values and i want to see sth like this :

{
  &quot;A&quot;:{
     &quot;X&quot;:0,
     &quot;Y&quot;:5,
     &quot;Z&quot;:3
  },
  &quot;B&quot;:{
     &quot;X&quot;:0,
     &quot;Y&quot;:2,
     &quot;Z&quot;:1
  },
  &quot;C&quot;:{
     &quot;X&quot;:2,
     &quot;Y&quot;:0,
     &quot;Z&quot;:0
  },
  &quot;D&quot;:{
     &quot;X&quot;:6,
     &quot;Y&quot;:0,
     &quot;Z&quot;:2
  }

}

are there any vay to get this result easily?

public classObj {
   
   private String type1; //key of first map

   private String field1; //second key calculated with this two fields
   private String field2;

   public String useTwoFieldToGetSecondGroup(){
       //use field1 and field2 to get X or Y or Z
   }

}

and useTwoFieldToGetSecondGroup method like this:

private String useTwoFieldToGetSecondGroup() {
	if(field1 &amp;&amp; field2){
		return &quot;X&quot;;
	} else if(!field1 &amp;&amp; field2){
		return &quot;Y&quot;;
	} else {
		return &quot;Z&quot;;
	}
}

huangapple
  • 本文由 发表于 2020年4月4日 21:44:39
  • 转载请务必保留本文链接:https://java.coder-hub.com/61029026.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定