简体   繁体   English

Java 8 GroupingBy与对象上的收集器

[英]Java 8 GroupingBy with Collectors on an object

I would like to stream on a collection of object myClass in order to grouping it using Collectors.groupingBy() . 我想流式传输对象myClass的集合,以便使用Collectors.groupingBy()对其进行分组。 But, instead of retrieving a Map<String, List<myClass>> , I would like to group it on a object myOutput and retrieve a Map<String, myOutput> . 但是,我不想检索Map<String, List<myClass>> ,而是将其分组到对象myOutput并检索Map<String, myOutput> I tried to create a custom collector : 我试图创建一个自定义收集器:

List<myClass> myList = new ArrayList<myClass>();
myList.add(new myClass("a", 1));
myList.add(new myClass("a", 2));
myList.add(new myClass("b", 3));
myList.add(new myClass("b", 4));

Map<String,myOutput> myMap = myList.stream().collect(Collectors.groupingBy(myClass::getA, Collectors.of(myOutput::new, myOutput::accept, myOutput::combine)));

myClass : 我的课 :

protected String a;
protected int b;

public myClass(String aA, int aB)
{
  a = aA;
  b = aB;
}

public String getA()
{
  return a;
}

public int getB()
{
  return b;
}

myOutput : myOutput:

protected int i;

public myOutput()
{
  i = 0;
}

public void accept(myClass aMyClass)
{
  i += aMyClass.getB();
}

public myOutput combine(myOutput aMyOutput)
{
  i += aMyOutput.getI();
  return this;
}

public int getI()
{
  return i;
}

But with this code, there is a problem with the collector : 但是使用此代码,收集器存在问题:

Collectors.of(myOutput::new, myOutput::accept, myOutput::combine)

I know in this case a reduction will be much easier, but let's assume there are a lot of operation to do in the myOutput object. 我知道在这种情况下减少会更容易,但我们假设在myOutput对象中有很多操作要做。

What's wrong with this collector? 这个收藏家怎么了?

Your collector is fine. 你的收藏家很好。 You just need to have the Collector.of static factory (and not Collectors.of ). 您只需要拥有Collector.of静态工厂(而不是Collectors.of )。

This compiles fine and has the output you want 这编译很好,并具有您想要的输出

    Map<String,myOutput> myMap = 
        myList.stream()
              .collect(Collectors.groupingBy(
                myClass::getA, 
                Collector.of(myOutput::new, myOutput::accept, myOutput::combine)
              ));

Note, however, that you don't need such a collector. 但请注意,您不需要这样的收集器。 You can reuse an existing one. 您可以重复使用现有的。 In this case, you want to group by the a value and for each element grouped to the same a , you want to sum their b value. 在这种情况下,你要组由a值和分组以相同的每个元素a ,你要总结自己的b值。 You can use the built-in Collectors.summingInt(mapper) where the mapper returns the b value: 您可以使用内置的Collectors.summingInt(mapper) ,其中mapper返回b值:

Map<String,Integer> myMap = 
    myList.stream()
          .collect(Collectors.groupingBy(
            myClass::getA, 
            Collectors.summingInt(myClass::getB)
          ));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM