2016-09-16 2 views
3

Java 8 Streams에 대한 간단한 예제를 이해하고 싶습니다. 무료 택시를 반환하는이 코드가 있습니다. 내가 taxis의 목록을 반복for 루프에서 Java 8 스트림 예제

private List<Taxi> taxis = new ArrayList<Taxi>(); 

Taxi scheduleTaxi(){ 
    for (Taxi taxi : taxis) { 
     if (taxi.isFree()) { 
      return taxi; 
     } 
    } 
    return null; 
} 

taxi 측면 경우 조건을 평가 : 나는 자바 8 개 스트림을 사용하여 해당 코드 루프이 대체하고 싶습니다. 조건이 적용되면 루프를 중지하고 taxi을 반환합니다.

제안 사항? , 목록에서 스트림을 얻기 후에, 당신은 기본적으로 조 건을 고려한 filter을 사용

+2

'return taxis.stream(). filter (택시 :: isFree) .findFirst() .Else (null);'. 마지막 것은'Stream' 메쏘드가 아니라'Optional' 메쏘드입니다. – Andreas

+3

'Stream'을 사용한다면 Andreas는 정확 합니다만,'orElse (null)'을 생략하고 대신''Optional ' (https://docs.oracle.com)을 반환해야합니다. /javase/8/docs/api/java/util/Optional.html) ['ifPresent']와 같은 편리한 메소드를 제공 할 것이기 때문에 (https://docs.oracle.com/javase/8/docs/api/) java/util/Optional.html # ifPresent-java.util.function.Consumer-) – 4castle

+0

@ 4castle [긴 응답] (http://stackoverflow.com/a/39540979/5221149)을 쓰기로 결심했으며, 당신의 제안. – Andreas

답변

7

은 무엇 당신이 찾고있는 것은 이것이다 | 유형                     | 대체
taxis                           | List<Taxi>
stream()                       | Stream<Taxi>     | parallelStream()
filter(Taxi::isFree) | Stream<Taxi>          
findFirst()       | Optional<Taxi> | findAny()        
orElse(null)       |             | filter(Taxi::isFree) 호가 method reference를 사용


이하 중에 참조하지 않는다.
또한 이용하여 기록 될 수있는 lambda expression :

filter(t -> t.isFree()) 

또는 람다 식 블록 사용 : 파라미터는 타입을 지정할 수

filter(t -> { 
    return t.isFree(); 
}) 

을 더 명시 될 :

filter((Taxi t) -> { return t.isFree(); }) 

더 비슷해 보이게하려면 anonymous class과 같습니다. t에 :

filter(new Predicate<Taxi>() { 
    @Override 
    public boolean test(Taxi t) { 
     return t.isFree(); 
    } 
}) 

으로 @mentioned in a comment 4castle, 당신의 scheduleTaxi() 방법의 필요에 따라, 당신은 호출자가 명시 적으로 만들기 위해 마지막 단계를 반환 형식을 변경하고 생략 할 수 있습니다 그것이를 택시를 찾을 수 없을 수도 있습니다.

Optional<Taxi> scheduleTaxi() { 
    return taxis.stream().filter(Taxi::isFree).findFirst(); 
} 
+0

나는 이것이 OPs 코드와 동일하다는 것을 알고 있지만 텍스트에는 무료 택시를 찾는 것에 대한 언급 만있다. 임의성이 좋고 택시 목록이 상당히 큰 경우 병렬 스트림과'findAny' 메소드 대'findFirst' 메소드의 사용에는 약간의 가치가있을 수 있습니다. –

+0

@AaronDavis 그래서'parallelStream()'과'findAny()'를 * alternatives *로 나열했으나 표시된 기본 호출은 원래 코드와 직접적으로 같습니다. 나는이 답변의 독자들에게 다양한 방법의 javadoc을 읽고 스스로 차이점에 대해 배우도록 맡겨두고있다. 그들은 언제나 StackOverflow에서 질문을 만들 수 있습니다. 그런 다음 그 차이에 대한 * 구체적인 * 질문을 갖습니다. – Andreas

+0

하 .. 그 대답은 그 대답의 뒷부분에 놓쳤습니다. 그것은 내 전화에서 완전히 읽지 않고 답변에 대해 의견을 말하도록 가르쳐 줄 것입니다 :-) –

0

댓글 좀 이미 말했지만, 나는보다 조금 설명 할 것이다 :

private List<Taxi> taxis = new ArrayList<Taxi>(); 
Optional<Taxi> optTaxi = taxis.stream().filter(taxi -> taxi.isFree()).findFirst() //or findAny() 
다음

논리적으로 무슨이다 목록에있는 항목 중 어떤 항목이 항목을 충족시키는 지 확인하고 이러한 항목 만있는 스트림을 반환합니다. 그런 다음 findFirst/Any 첫 번째/모든 항목을 잡고 Optional으로 반환합니다. 필터링에서 "생존"하는 항목이 없으면 Optionalnull이 포함됩니다.

스트림 실행 방식이 다르기 때문에 코드 실행 순서가 위에서 설명한 것과 같지 않습니다. filter(...).filter(...).filter(...)을 수행하면 반복해서 반복하지 않고 한 번만 반복합니다.

코드로 돌아 가기 : Optional<Taxi> 그 자체를 반환하거나 포장을 풀고 Taxi 개체를 반환 할 수 있습니다. 원하는 대상에 따라 null 수 있습니다.

표현 단계         : 여기

return taxis.stream() 
      .filter(Taxi::isFree) 
      .findFirst() 
      .orElse(null); 

이 발현 자신의 반환 형식과 단계 및 javadoc의
-링크의 목록입니다

9

최신 IntelliJ IDEA 2016.3 EAP (Community Edition 또는 Ultimate edition)을 사용하면 자동으로 변환 할 수 있습니다.

Idea

하려면 Alt-입력하고 "()로 findFirst로 교체"를 선택 :

Idea

짜잔는, 당신이 일을 끝낼 그냥가에 대한 루프에 커서를!

Idea

면책 조항 : 나는하게 IntelliJ IDEA의 개발자입니다.