2017-12-13 12 views
3

나는 다음과 같은 코드가 있습니다. lambdas를 사용하여 fields을 어떻게 수정할 수 있습니까? 그 일을 할forEach 내부에서 람다 외부의 개체에 액세스하는 방법은 무엇입니까?</p> <pre><code>String fields = ""; listofObjects.stream().forEach(l -> fields = fields + l.text); </code></pre> <p>이 <code>fields</code> 최종해야하기 때문에 작동하지 않습니다

+1

당신이 할 수있는'.stream'에 필요()' – alfasin

+1

항상 스트림 람다가 병렬로 실행될 수있는 그 기억을 listofObjects.forEach' 없습니다 Java는 실수로 최종 속성이 아닌 것을 덮어 쓰지 못하게합니다 – Mick

답변

11

스트림과 람다는 일반적으로 무국적이어야합니다. 여기에 귀하의 경우에 대한 기존의 솔루션입니다 :

String fields = listofObjects.stream() 
     .map(l -> l.text) 
     .collect(Collectors.joining()); 
8

작은 변화는 대신 StringBuilder을 사용하는 것 - 그것은 더 효율적인 것 :

StringBuilder builder = new StringBuilder(); 
listofObjects.stream().forEach(l -> builder.append(l.text)); 
String fields = builder.toString(); 

마틴 노트로, Collectors.joining()이 기능에 합류 일반 문자열을 제공하지만, 당신이 매핑해야 문자열 스트림에 객체 스트림을 먼저 저장하십시오. (map으로하기 쉽고, 이것을 자주해야하는 경우 자신 만의 수집기를 만들어서 할 수 있습니다.)

1

정확히 동일 할 필요가있는 경우 :

StringBuilder builder = new StringBuilder(); 
listofObjects.stream().forEach(l -> builder.append(l.text)); 

그러나 더 많은 기능 접근 방식은

fields = listofObjects.stream().map(l -> l.text).collect(Collectors.joining()); 
0

우리는 reduce을 사용할 수있을 것입니다 :

String fields = listofObjects.stream() 
          .reduce((x, y) -> x + y).orElse(""); 

또는 아래 @의 shmosel의 코멘트 당 : - 그리고 그 이유 이유

String fields = listofObjects.stream() 
          .reduce("", String::concat); 
+1

또는'.reduce ("", String :: concat);'. 하지만 왜 더 효율적인 콜렉터가있을 때'reduce()'를 사용해야할까요? – shmosel

+0

@shmosel 사실, reduce에는 사용할 수있는 초기 값을 갖는 또 다른 오버로드 된 버전이 있습니다. 나는 당신이 제공 한 해결책이 아닌 다른 것을 수행하는 것의 부가 가치를 보지 못합니다. 그 중 한 명에게 프로/죄수가 보이십니까? – alfasin

+1

내가 제안한 오버로드 값은 일반적으로 피해야하는'get()'호출을 필요로하지 않는다는 것입니다. 'Optional' 오버로드를 사용한다면 적어도 OP의 의도를 반영하기 위해'orElse ("")'를 사용하십시오. 수집가의 가치는 틀림없이 더 관용적이며 더 익숙하다는 것입니다. 게다가 내부적으로'StringJoiner'를 사용하기 때문에 반복 된 연결 비용을 피할 수 있습니다. – shmosel