2017-11-29 12 views
0

내가 하나 그룹 (A 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); 

     } 
    } 
} 

내가이 유일한 문제입니다 경우 I applyMerge() 함수를 호출하면 이전 합계 값의 맨 위에 모든 값이 추가됩니다. 나는 객체 MyClass head이 단지 일시적인 것이라고 생각하지만, 참조는 tmp이고 map 인 것으로 보인다.

내 오해는 무엇입니까?

ps : 데이터베이스에서 sqlResultList을 갱신 할 수 있지만 데이터 자체가 변경되지 않았으므로이를 피하고 싶습니다.

+1

downvoter가 아니지만 참조 유형 *이라고 불리는 이유가 있습니다. – shmosel

+1

@shmosel이 경우 올바른 접근 방법은 무엇입니까? – wittich

+0

무엇에 접근합니까? 당신은 당신이하려고하는 것을 간신히 설명했습니다. – shmosel

답변

1

귀하의 head 개체는 원래 목록에있는 개체에 대한 참조입니다. 복사본이 아니므로 해당 개체에 대한 모든 수정 사항은 해당 개체에 대한 다른 참조에서도 볼 수 있습니다.

가 복제
MyClass head = tmp.get(0).clone(); 

방법은 다양하지만 일반적인 방법은 Object#clone() 메소드를 오버라이드 (override)하는 것입니다

당신은 복제 대신 개체를 원할 것입니다. 이 방법에서는 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 메소드도 제공합니다.