2017-11-29 1 views
0

私は1つでグループに(DBからの)オブジェクトのリストが欲しい正常に動作し、その要素は、以下のこの単純化されたコードであれば:オブジェクトのリストをIDでグループ化するのは、その関数の最初の呼び出しでのみ機能しますか?

List<MyClass> sqlResultList; 
List<MyClass> resultList; 

public void applyMerge() { 

    Map<Integer, List<MyClass>> map = 
      sqlResultList.stream().collect(Collectors.groupingBy(MyClass::getIdItem)); 

    resultList = new ArrayList<>(); 
    for (Integer IdItem : map.keySet()) { 

     List<MyClass> tmp = map.get(IdItem); 

     if (tmp.size() > 0) { 

      MyClass head = tmp.get(0); // seems to create just a reference 

     for (int i = 1; i < tmp.size(); i++) { 

       MyClass obj = tmp.get(i); 
       head.setMinutes(head.getMinutes() + obj.getMinutes()); 

      } 

      resultList.add(head); 

     } 
    } 
} 

私はを持っている唯一の問題であり、その場合、私再呼び出しapplyMerge()関数は、前の合計値の上にすべての値を追加します。オブジェクトMyClass headはちょうど一時的なものだと思ったが、参照tmpmapと思われる。

私の誤解は何ですか?

ps:私はDBからsqlResultListを更新することができますが、データ自体は変更されていないので、これを避けたかったのです。

+1

downvoterではなく、参照型*と呼ばれる理由があります。 – shmosel

+1

@shmoselこの場合の正しいアプローチは何ですか? – wittich

+0

何に近づきますか?あなたは何をしようとしているのかをほとんど説明していません。 – shmosel

答えて

1

headオブジェクトは、元のリストのオブジェクトへの参照です。コピーではないので、そのオブジェクトに加えた変更は、そのオブジェクトへの他の参照によっても見られます。

あなたが代わりにクローンにオブジェクトをお勧めします:クローニングの

MyClass head = tmp.get(0).clone(); 

方法は異なりますが、一般的な方法は、Object#clone()メソッドをオーバーライドすることです。このメソッドでは、MyClassという新しいインスタンスを作成し、必要なすべてのプロパティをコピーします。たとえば:あなたは他のプロパティを持っている場合は

public class MyClass { 
    private int minutes; 

    public MyClass clone() { 
     MyClass clonedInstance = new MyClass(); 
     clonedInstance.setMinutes(getMinutes()); 
     return clonedInstance; 
    } 

    public int getMinutes() { 
     return this.minutes; 
    } 

    public void setMinutes(int minutes) { 
     this.minutes = minutes; 
    } 
} 

は、あなたがあまりにも、必要な任意の深いクローニングを認識していることを確認したくなるでしょう。たとえば、変更可能なタイプのプロパティ(たとえば、Listなど)がある場合、そのプロパティを複製したり、繰り返したりすることができます。

多くの標準JDKタイプは、ArrayListなどの独自のcloneメソッドも提供しています。

関連する問題