2016-10-03 45 views
3

我想在流的collect(Collectors.toMap(..))調用中編寫方法引用。在下面的例子中,我有一些代碼來完成我的任務,而不方法參考:在流收集器中編寫Java 8方法引用

class A { 
    private String property1; 
    private B property2; 

    public String getProperty1() { return property1; } 
    public B getProperty2() { return property2; } 
} 

class B { 
    private String property3; 

    public String getProperty3() { return property3; } 
} 

public class Main { 
    public static void Main() { 
     List<A> listOfA = /* get list */; 

     Map<String, String> = listOfA.stream() 
      .collect(toMap(x -> x.getProperty1(), x -> x.getProperty2().getProperty3())); 
    } 
} 

這是微不足道的改變x -> x.getProperty1()A::getProperty1()。然而它不像x -> x.getProperty2().getProperty3()那樣微不足道。我想下面的工作之一:

.collect(toMap(A::getProperty1, ((Function)A::getProperty2).andThen((Function)B::getProperty3))) 

.collect(toMap(A::getProperty1, ((Function)B::getProperty3).compose((Function)A::getProperty2))) 

然而,他們都給予我的錯誤Non-static method cannot be referenced from static context

+3

有ISN這不會是一個更好的方式來做到這一點。原來的lambda是你將要得到的最好的。 –

+4

你最終會得到的每個答案都會比lambda表達式更長,更笨拙和更難以理解。你爲什麼要用另一種方式? – Tunaki

+0

我主要是出於好奇,至少在這個問題的具體表述中探索這個。即使我提供的兩個例子(不起作用)比lambda更笨拙,可讀性也更差。但是,如果可以的話,方法組合是一個非常強大的功能,我會更頻繁地使用它。如果你們中的任何一個人都可以解釋爲什麼這是不允許的,另外在哪些情況下我可以使用方法組合(例如,如果所有方法都是靜態的,是否有可能?),那將是非常有用的並且值得接受回答我的看法。謝謝你的方式! –

回答

3

A::getProperty2是一個Function<A, B>(這是一個函數,它接受A的一個實例並返回一個B的實例)。

你可以施放和撰寫它:

((Function<A, B>)A::getProperty2).andThen(B::getProperty3) 

或者你可以創建這樣一個功能製片人:

public static <A, B, R> Function<A, R> compose(
     Function<A, B> f1, Function<B, R> f2) { 
    return f1.andThen(f2); 
} 

,並用它組成爲:

compose(A::getProperty2, B::getProperty3) 
+1

'A :: getProperty2'是一個'Function'的有效方法引用,它不能用作'Supplier',因爲它需要一個'A'類型的參數。 –

+0

@DidierL,你是對的。更新了我的答案。 – ericbn

+0

因此,我澄清說,我的錯誤是將其轉換爲'Function'而不是'Function '。謝謝! –