2016-03-22 25 views
4

Collectors.groupingBy() kullanarak gruplamak için myClass nesnesinin bir koleksiyonunda akış yapmak istiyorum. Ancak, Map<String, List<myClass>>'u geri almak yerine, onu myOutput nesnesinde gruplamak ve Map<String, myOutput>'u almak istiyorum. Özel bir kollektörü oluşturmaya çalıştınız:Java 8 GruplandırmaBy Nesnede KoleksiyoncularBy

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:

Collectors.of(myOutput::new, myOutput::accept, myOutput::combine) 
: toplayıcı ile ilgili bir sorun
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; 
} 

Ama bu kodla

var

Bu durumda biliyorum bir Azaltma çok daha kolay olacak, ancak myOutput nesnesinde yapılacak çok fazla işlem olduğunu varsayalım.

Bu toplayıcıda neyin var?

cevap

6

Koleksiyoneriniz düzgün. Sadece Collector.of statik fabrikaya sahip olmanız gerekir (Collectors.of değil).

Bu ince derler ve çıkışı Eğer böyle bir kollektörü gerekmez, ancak,

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

Not istiyorum. Mevcut olanı tekrar kullanabilirsiniz. Bu durumda, a değerine göre gruplandırmak ve aynı a grubuna gruplandırılmış her öğe için b değerini belirtmek istersiniz.

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

Teşekkür: mapper b değerini verir nerede Collectors.summingInt(mapper) yerleşik kullanabilirsiniz. Oldukça yakınım :(Elbette, yerleşik toplayıcı koleksiyoncu bu durumda daha iyi bir seçenek olacaktı ama benim anlaşılır bir örnekle benim meselemi anlatmak istedim.İhtiyaçlarım daha karmaşık olan myClass ve myOutput nesnelerini gerektirdi. –