2014-10-02 2 views
4

Stream이 인 경우 java8의 Collectors.toMap을 사용하려고합니다. 처리 중에 발생할 수있는 예외가 있기 때문에 최선의 생각이 아닐 수도 있지만 가능한 것이어야합니다.java8 Collectors.toMap() 제한?

나는 이해하지 못하는 컴파일 오류 (추측 유추 엔진)를 얻고 있습니다.

import java.io.IOException; 
import java.util.Map; 
import java.util.stream.Collectors; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipFile; 

public class TestMapCollector { 

    private static class MyObject { 
    } 

    public static void main(String[] argv) throws IOException { 
     try (ZipFile zipFile = new ZipFile("test")) { 
      Map<String, MyObject> result = zipFile.stream() 
        .map(ZipEntry::getName) 
        .collect(Collectors.toMap(f -> "test", f -> new MyObject())); 
     } 
    } 
} 

이 코드는 그냥 .map(ZipEntry::getName) 라인을 언급하는 경우, 그러나 그것은 구축하지 않는있는 그대로 빌드 :

는 여기에 몇 가지 추출 데모 코드입니다. 마치 입력이 String의 스트림이지만 입력이 ZipEntry의 스트림 인 경우 toMap 콜렉터가 작동 할 수있는 것처럼? 이 예상되어 있는지 확실하지 않습니다 - 때문에 스트림 타입이 와일드 카드를 사용한다는 사실에

no suitable method found for collect(Collector<Object,CAP#1,Map<String,MyObject>>) 
    method Stream.<R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super CAP#2>,BiConsumer<R#1,R#1>) is not applicable 
     (cannot infer type-variable(s) R#1 
     (actual and formal argument lists differ in length)) 
    method Stream.<R#2,A>collect(Collector<? super CAP#2,A,R#2>) is not applicable 
     (cannot infer type-variable(s) R#2,A,CAP#3,T#2,K,U 
     (argument mismatch; Collector<CAP#2,CAP#4,Map<Object,Object>> cannot be converted to Collector<? super CAP#2,CAP#4,Map<Object,Object>>)) 
    where R#1,T#1,R#2,A,T#2,K,U are type-variables: 
    R#1 extends Object declared in method <R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super T#1>,BiConsumer<R#1,R#1>) 
    T#1 extends Object declared in interface Stream 
    R#2 extends Object declared in method <R#2,A>collect(Collector<? super T#1,A,R#2>) 
    A extends Object declared in method <R#2,A>collect(Collector<? super T#1,A,R#2>) 
    T#2 extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U>) 
    K extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U>) 
    U extends Object declared in method <T#2,K,U>toMap(Function<? super T#2,? extends K>,Function<? super T#2,? extends U... 
+0

어떤 컴파일러를 사용 했습니까? 나는'jdk1.8.0_05','jdk1.8.0_20','jdk1.8.0_40beta','Eclipse Luna (4.4.0)'을 테스트했다. 그들 중 누구도 코드를 컴파일하는 데 문제가 없었습니다. – Holger

+1

@Holger javac를 사용하여 jdk1.8.0_20으로'.map (ZipEntry :: name)'을 주석 처리해야합니다.) 문제를 재현 할 수 있습니다. – assylias

+1

@assylias : 알겠습니다. 1.8u20이 그 문제가있는 나의 목록의 유일한 사람이기 때문에, 우리는 [이 질문 (http://stackoverflow.com/q/25414867/2711488) (또는 [그 질문 [http : //stackoverflow.com/q/25490581/2711488))? – Holger

답변

6

문제가 될 것으로 보인다 : 참고로

, 여기 꽤 모호한의 빌드 오류의 시작입니다 행동. 해결 방법은 다음과 같습니다.

zipFile.stream().map(ZipEntry.class::cast) //or .map(z -> (ZipEntry) z) 
+2

아하 이해합니다. 네, 단순히'stream()'을 호출하는 대신'(() zipFile.stream())'으로 변경하면 컴파일됩니다. 그래서 java8 타입 유추의 한계가있는 것 같습니다. –

+1

문제가 재현되지 않으므로 (이 주석을 참고하십시오 (http://stackoverflow.com/questions/26157543/java8-collectors-tomap-limitation#comment41013050_26157543))이 문제는 예상 된 동작이 아닙니다 ... – Holger