2017-03-22 8 views
2

다음과 같은 코드 조각이 있습니다.Java 스트림이 sideeffect로 매핑되고 결과 목록을 수집하거나 foreach하고 채 웁니다.

나는 이와 관련하여 두 가지 모순되는 (?) "규칙"을 읽었습니다.

스트림을 사용하고 목록을 반환하기 위해 어떻게 해결할 수 있습니까? 아니면 단순히 스트림을 건너 뛸까요?

@Transactional 
public Collection<Thing> save(Collection<Thing> things) { 
    return things.stream().map(this::save).collect(Collectors.toList()); 
} 

@Transactional 
public Thing save(Thing thing) { 
    // org.springframework.data.repository.CrudRepository.save 
    // Saves a given entity. Use the returned instance for further operations as the save operation might have changed the entity instance completely. 
    Thing saved = thingRepo.save(thing); 
    return saved; 
} 
+0

.foreach와 관련된 규칙의 정확한 출처를 알려주시겠습니까? 그것이 작업하고있는 객체의 변수 또는 어떤 종류의 변수입니까? (그것은 '변경 가능 변수 업데이트'라고 말하는 것이 이상합니다. '불변 변수 업데이트'란 무엇입니까?) 어쨌든 여기서는 for 루프를 사용하고 명시 적 컬렉션 관리를 사용하면 스트림이 실제로 작업을 저장하지 않을 것이라고 제안하거나 여기에 더 많은 명확성을 제공합니다. –

+1

요점은 * 간섭 *을 피해야한다는 것입니다. 동일한 'Thing'인스턴스가 소스 컬렉션에 두 번 이상 나타나면 실행할 수 있지만 응용 프로그램 논리로 인해이를 배제 할 수 있다고 가정합니다. 그러면'thingRepo.save (...)'가'thingRepo'의 상태를 어떻게 변경시킬 수 있는지에 달려 있습니다. 일반적으로'forEach'를 통해리스트를 생성하기 전에 스트림을 사용하지 않는 편이 좋을 것입니다. 왜냐하면 후자는'for' 루프보다 간단하고 깨끗한 코드를 생성하지 않기 때문입니다. – Holger

답변

2

해당 종이가 가변 상태라고 말하지 않습니까? 귀하의 경우에는 메서드 내에서 목록을 선언 한 다음 forEach을 사용하면 모든 것이 정상입니다. 두 번째 대답 here에는 수행하려는 작업이 정확히 나와 있습니다.

+0

내 생각에,하지만 그들은 '공유'에 의해 어떻게 의미가 확실하지 않은 이후 예제로 명확하지 않았습니다. 가능하다면 일반적으로 공유 된 가변 상태를 원한다는 것을 확신하지 못합니다. :) 두 번째 대답은 정확히 내가 다음과 같은 것입니다 (순서를 제외합니다) –

1

는 전혀 변이하지 않는 경우 List 완전히 새로운를 수집하기 위해 아무 이유없이 거의있다. 게다가 사용 사례는 기본적으로 컬렉션의 모든 요소를 ​​반복하고 for-each을 사용하여 간단히 달성 할 수있는 것을 저장합니다. 어떤 이유로 hingRepo.save(thing) 당신은 여전히 ​​같은 모음을 반환 할 수 있습니다 개체를 변이합니다,하지만이 시점에서이 hingRepo.save(thing) 그 제안하지 않기 때문에 전혀 명확하게 보이지 않는 숨겨진 돌연변이가 있다면

.

+0

저장 개체가 변경되었습니다. 주어진 개체를 저장합니다. 저장 조작으로 엔티티 인스턴스가 완전히 변경되었을 수 있으므로 리턴 된 인스턴스를 추가 조작에 사용하십시오. –

+1

@ViktorMellgren 그러면 완전히 새로운 컬렉션을 반환하는 것이 좋습니다. 그러나 이것은 실제로 객체의 이전 값과 현재 값을 가진 두 개의 콜렉션이 필요한지에 달려 있습니다. –

+0

내가 할 :) 설정 한 ID가 필요합니다 –