2017-12-23 12 views
0

단어 스트림을 사용하여 일부 작업을 수행하는 스트림 처리 코드가 있는데 단어를 키로 사용하고 단어 수가 출제 횟수가 LongMap으로 줄입니다. 코드의 간결함을 위해 의 Seq 클래스를 사용했으며, 여기에는 여러 가지 유용한 바로 가기 메서드가 포함되어 있습니다. 나는이처럼 작성하는 경우Java가이 코드를 typecheck 할 수없는 이유는 무엇입니까?

코드는 잘 컴파일 :

item.setWordIndex (
     getWords (item)      // returns a Seq<String> 
       .map (this::removePunctuation) // String -> String 
       .map (stemmer::stem)   // String -> String 
       .groupBy(str -> str, Collectors.counting())); 

그러나, 나는 함께 str -> str 람다를 교체하려고하면 더 자기 문서화 Function::identity을, 나는 다음과 같은 오류를 얻을 :

(Map<Object,Long>)
유형 Function이를 정의하지 않습니다

유형 MyClass의 방법 setWordIndex(Map<String,Long>)는 인수 적용 할 수 없습니다 나는 (아마도 순진) 가정하는

Function::identitystr -> str 다르게 어떤 행동 않습니다 여기에 적용직접 해당하는, 그리고 그것을 사용하는 경우 왜 컴파일러는 그것을 처리 할 수 ​​있습니까?

(그리고 그래, 나는이 groupBy 작업에 이전 map 응용 프로그램을 이동하여 식별 기능을 제거 할 수 있습니다 알고 있어요,하지만 더 직접 응용 프로그램 논리를 다음과 때문에,이 같은 코드를 명확하게 찾을 수)

+0

가능한 복제 [자바 8 람다, Function.identity() 또는 T-> t (https://stackoverflow.com/questions/28032827/java- 8-lambdas-function-identity-or-tt) – Kraylog

+0

당신은'Function :: identity'보다는'Function.identity()'를 원합니다. –

+0

@ NimrodArgov -이 질문은이 특정 경우에 'Function :: identity'가 작동하지 않는 이유보다 둘 다 적합한 경우에 어떤 것이 바람직한 지 묻습니다. – Jules

답변

7

당신은 (A Function<T, T>를 반환하는) Function.identity()를 원합니다 (SAM 유형 Supplier<Function<T, T>> 일치)하지 Function::identity.

다음 코드는 잘 컴파일 :

static String removePunctuation(String x) { return x; } 
static String stem(String x) { return x; } 

// ... 

final Map<String, Long> yeah = Seq.of("a", "b", "c") 
     .map(Test::removePunctuation) 
     .map(Test::stem) 
     .groupBy(Function.identity(), Collectors.counting()); 
+0

아, 네. 이제 나는 그것을 다시 본다. :) – Jules

2

두 가지 유형간에 약간의 차이가 있습니다. 이들은 직접 상응하지 : 해당 유형 Function<T, T> 때문에

  • Function.identity()는 입력 유형을 리턴한다;
  • str -> str은 더 넓은 유형을 반환 할 수 있습니다. 실제로는 Function<? extends T, T>입니다.
+0

이것이 사실이지만, 나는 이것이 어떻게 관련이 있는지 이해하지 못한다 : 코드를 작동시키는 올바른 타입은'Function '이다. 그래서 더 넓은 타입에 대한 필요성은 거기에 없을 것 같다? – Jules

+0

@Jules 나는 단지 그들이 직접적으로 동등하지 않다는 것을 지적하고있다. –