2015-08-23 20 views
6

Trong java, bạn có thể thêm các tham số kiểu vào các phương thức tĩnh, để tạo các phương thức xử lý các Generics. Bạn có thể làm tương tự với lambdas?Tạo lambdas chung trong Java

Trong mã của tôi, tôi có

final private static <K,V> Supplier<Map<K, List<V>> supplier=HashMap::new; 

Tôi đang cố gắng để làm tham số kiểu như đó là một chức năng, nhưng nó sẽ không cho phép tôi.

Và nếu tôi làm:

final private static Supplier<Map<?, List<?>>> supplier=HashMap::new; 

Nó không chấp nhận lập luận mà tôi cố gắng sử dụng nó. Tôi có thể làm gì?

+1

Đó không thể là một biến. Trong thực tế, việc khai báo một biến như 'WhateverClassThatSupportsGenerics var = ...;' trừ khi nó là một tham số của một phương thức. –

+0

Bạn cố gắng sử dụng tờ khai thứ hai ở đâu? (Đầu tiên, như bạn đã có thể phát hiện, là không hợp lệ theo cú pháp.) – Makoto

+1

Không thể xây dựng một đối tượng chung được bao bọc. Dòng mã của bạn không thành công vì cùng một lý do 'HashMap mới >' là hợp pháp, nhưng 'mới HashMap >' thì không. '?' có nghĩa là "Tôi không biết loại HashMap này sử dụng", nhưng khi bạn tạo một HashMap, bạn luôn biết những gì bạn định đưa vào nó (ngay cả khi bạn quyết định nó là java.lang.Object). – VGR

Trả lời

8

Một workaround cho điều này có thể để bọc các tài liệu tham khảo phương pháp thành một phương pháp, do đó loại mục tiêu trừ giải quyết các loại tại địa điểm cuộc gọi:

import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.function.Supplier; 

public class GenericLambda 
{ 
    // Syntactically invalid 
    //final private static <K,V> Supplier<Map<K, List<V>> supplier=HashMap::new; 

    final private static Supplier<Map<?, List<?>>> supplier=HashMap::new; 

    // A workaround 
    private static <K,V> Supplier<Map<K, List<V>>> supplier() 
    { 
     return HashMap::new; 
    } 


    public static void main(String[] args) 
    { 
     // Does not work 
     //useSupplier(supplier); 

     // Works 
     useSupplier(supplier()); 
    } 

    private static <K, V> void useSupplier(Supplier<Map<K, List<V>>> s) 
    { 
     System.out.println(s.get()); 
    } 
} 
+0

Tôi nghĩ bạn cần một dàn diễn viên trên 'HashMap :: new' là' Bản đồ '(hoặc' Bản đồ ') nhưng không phải' Bản đồ > '). Xem cách thức 'Collections.emptyList()' được thực thi. – NoDataFound

+1

@NoDataFound Bạn không chắc chắn ý bạn là gì, nhưng ở đây, không cần phải cast (mặc dù cast tàn bạo cũng có thể an toàn trong trường hợp này, vì tất cả các tham số type biến thành 'Object' dù được biên dịch ...) – Marco13

+0

@ NoDataFound: Danh sách được trả về bởi 'Collections.emptyList()' là không thay đổi và do đó có thể luôn trả về cùng một đối tượng và chỉ cần bỏ nó. Trong trường hợp này, tuy nhiên, bạn luôn nhận được một 'HashMap' mới và sử dụng' HashMap :: new' trình biên dịch có thể suy ra các tham số chung chính xác một cách tự động. Tuy nhiên, có thể luôn luôn truyền và trả về trường tĩnh. Nhưng đúc trong trường hợp này là một chút bất tiện: Bạn cần phải sử dụng '(Nhà cung cấp >>) (Nhà cung cấp ) nhà cung cấp'. Và nó tạo ra cảnh báo về phôi không được kiểm soát và hiệu suất thường không tạo nên sự khác biệt. – siegi

Các vấn đề liên quan