2016-07-19 10 views
-1

私はこのクラスのオブジェクトのarraylistを取得します。例:java 8 groupBYまたは一般的な方法を使用

new Foo(1, "P1", 300, 400), 
new Foo(1, "P4", 300, 400), 
new Foo(2, "P2", 600, 400), 
new Foo(3, "P3", 30, 20), 
new Foo(3, "P3", 70, 20), 
new Foo(1, "P1", 360, 40), 
new Foo(4, "P4", 320, 200), 
new Foo(4, "P4", 500, 900) 

合計値がIDと参照の両方でグループ化されたFOOオブジェクトの新しいリストを作成してこれらの値を変換します。 それのようになります。それは、新しいリスト内に存在する場合、それはそれだけに項目を追加していない場合は、最初のリストからすべてのアイテムを取得します。このような方法で、小切手を使用し

new Foo(1, "P1", 660, 440), 
new Foo(1, "P4", 300, 400), 
new Foo(2, "P2", 600, 400), 
new Foo(3, "P3", 100, 40) 
+1

私はhttp://stackoverflow.com/help/how-to-askをお読みください。それは、私たちがあなたを助けてくれる方法で質問を書くのに役立ちます。 – jbrown

+0

@jbrown彼は、 'Foo'sの' ArrayList'を受け入れ、その 'ArrayList'のグループ化されたバージョンを返すメソッドを望んでいます。たとえば、リストのすべての項目を繰り返し処理し、リストに項目がすでに存在するかどうかをチェックします。 –

+0

@nickzoum - リンクされた文書で説明されているように「他の人が問題を再現できるだけのコードを含める」という考え方を導入しています – jbrown

答えて

-1

新しいリストが存在する場合は、リスト内に存在する最初の2つのフィールドと同じ項目の最後の2つのフィールドをアイテムに追加します。

public ArrayList<Foo> groupList(ArrayList<Foo> list){ 
    ArrayList<Foo> foos = new ArrayList<Foo>(); 
    for(Foo foo: list){ 
     Foo temp = getFoo(foos, foo); 
     if(temp != null){ 
      temp.merge(foo); 
     }else{ 
      foos.add(foo); 
     } 
    } 
} 

public Foo getFoo(ArrayList<Foo> foos, Foo foo){ 
    for(Foo temp: foos){ 
     if(foos.equals(temp)){ 
      return temp; 
     } 
    } 
    return null; 
} 

これらのメソッドをFooクラスに追加します。 これらは、あなたがしなければならない、あなたの意図は、このような「特別な」グループ化を行うのであればFooのフィールドはbar1bar2bar3bar4

public void merge(Foo otherFoo){ 
    this.setBar3(this.getBar3 + otherFoo.getBar3); 
    this.setBar4(this.getBar4 + otherFoo.getBar4); 
} 

public boolean equals(Object object){ 
    if(object instanceof Foo){ 
     Foo otherFoo = (Foo)object; 
     if(getBar1.equals(otherFoo.getBar1) && getBar2.equals(otherFoo.getBar2)){ 
      return true; 
     } 
    } 
    return false; 
} 
0

と呼ばれていることを前提と(というか:可能)内蔵を使用しませんgroupByの機能です。組み込み関数のセマンティクスには、Fooオブジェクトで実行する「マージ」操作は含まれません。

代わりに、あなたはCollectors#toMap機能を使用することがあります。

  • keyMapperは、キー、エントリの「識別子」のいくつかの並べ替えを作成する関数です。あなたの場合、これはFooを受け取り、Entry<Integer, String>オブジェクトを作成し、マップのキーとして使用する関数です。 (あなたはそこに任意のPairTupleを使用することができます - でもList<Object>はそれを行うだろう)
  • valueMapperは恒等関数
  • することができmergeFunctionが、ここで重要なものです:それは同じ番号と文字列を持つ2つのFooオブジェクトを(取ります)、残りの値が追加された新しいマージされたFooオブジェクトを返します。

結果はMapになりますが、必要であれば、あなたは、このマップの値からListを作成することができます。ここで

は一例です:

import static java.util.stream.Collectors.toMap; 

import java.util.AbstractMap.SimpleEntry; 
import java.util.Arrays; 
import java.util.List; 
import java.util.Map; 
import java.util.Map.Entry; 
import java.util.function.BinaryOperator; 
import java.util.function.Function; 
import java.util.stream.Collectors; 

public class GroupByTest 
{ 
    public static void main(String[] args) 
    { 
     example(); 
     exampleUnmaintainable(); 
    } 


    private static void example() 
    { 
     List<Foo> foos = Arrays.asList(
      new Foo(1, "P1", 300, 400), 
      new Foo(1, "P4", 300, 400), 
      new Foo(2, "P2", 600, 400), 
      new Foo(3, "P3", 30, 20), 
      new Foo(3, "P3", 70, 20), 
      new Foo(1, "P1", 360, 40), 
      new Foo(4, "P4", 320, 200), 
      new Foo(4, "P4", 500, 900) 
     ); 

     Function<Foo, Entry<Integer, String>> keyMapper = foo -> 
      new SimpleEntry<Integer, String>(foo.getId(), foo.getS()); 
     Function<Foo, Foo> valueMapper = foo -> foo; 
     BinaryOperator<Foo> mergeFunction = (f0, f1) -> 
      new Foo(f0.getId(), f0.getS(), f0.getX()+f1.getX(), f0.getY()+f1.getY()); 
     Map<Entry<Integer, String>, Foo> result = 
      foos.stream().collect(toMap(keyMapper, valueMapper, mergeFunction)); 

     for (Entry<Entry<Integer, String>, Foo> entry : result.entrySet()) 
     { 
      System.out.println(entry); 
     } 
    } 


    private static void exampleUnmaintainable() 
    { 
     List<Foo> foos = Arrays.asList(
      new Foo(1, "P1", 300, 400), 
      new Foo(1, "P4", 300, 400), 
      new Foo(2, "P2", 600, 400), 
      new Foo(3, "P3", 30, 20), 
      new Foo(3, "P3", 70, 20), 
      new Foo(1, "P1", 360, 40), 
      new Foo(4, "P4", 320, 200), 
      new Foo(4, "P4", 500, 900) 
     ); 

     List<Foo> result = foos.stream().collect(toMap(
      foo -> new SimpleEntry<Integer, String>(foo.getId(), foo.getS()), 
      foo -> foo, (f0, f1) -> new Foo(f0.getId(), f0.getS(), 
       f0.getX()+f1.getX(), f0.getY()+f1.getY()))) 
      .values().stream().collect(Collectors.toList()); 

     for (Foo foo : result) 
     { 
      System.out.println(foo); 
     } 
    } 


    static class Foo 
    { 
     private int id; 
     private String s; 
     private int x; 
     private int y; 

     public Foo(int id, String s, int x, int y) 
     { 
      this.id = id; 
      this.s = s; 
      this.x = x; 
      this.y = y; 
     } 

     public int getId() 
     { 
      return id; 
     } 

     public String getS() 
     { 
      return s; 
     } 

     public int getX() 
     { 
      return x; 
     } 

     public int getY() 
     { 
      return y; 
     } 

     @Override 
     public String toString() 
     { 
      return "Foo [id=" + id + ", s=" + s + ", x=" + x + ", y=" + y + "]"; 
     } 
    } 

} 

うん、パッシブ・アグレッシブ発言:あなたはメソッド名などを好きではない場合、あなたは私達にあなたの実際のFooクラスを示している必要があります。私たちはここにちょっと推測するを持っています...

関連する問題