简体   繁体   中英

Generic method as functional programming using java.util.Function

I am not sure can we write the generic method as a function programming using Java 8 lamda expression as below

Generic method

public <T> MongoCollection<T> getCollection(String collectionName, Class<T> typeParameterClass) {
    return mongoClient
            .getDatabase(mongodbConfiguration.getDatabase())
            .getCollection(collectionName, typeParameterClass);
}

I want to convert this generic method to generic functional lamda expression as below

public BiFunction<String, Class<T>, T> getCollection = (collectionName, typeParameterClass) -> {
    return mongoClient
            .getDatabase(mongodbConfiguration.getDatabase())
            .getCollection(collectionName, typeParameterClass);
};

From the above code I have an error on type T and typeParameterClass

在此处输入图像描述

Update 1

While implementing the method suggested by @Clashsoft the second argumenent is Class<Object> instead of Class<T>

repository.getCollectionFactory().apply("", Category.class);

在此处输入图像描述

That's not possible with a field. You can however create another method / getter with a type parameter:

public <T> BiFunction<String, Class<T>, MongoCollection<T>> getCollectionFactory() {
    return  (collectionName, typeParameterClass) -> {
        return mongoClient
                .getDatabase(mongodbConfiguration.getDatabase())
                .getCollection(collectionName, typeParameterClass);
    };
};

Keep in mind you have to specify the type when calling the method:

repository.<Category>.getCollectionFactory().apply("test", Category.class)

Or use a variable with an explicit type:

BiFunction<String, Class<Category>, MongoCollection<Category>> factory = repository.getCollectionFactory();
factory.apply("test", Category.class)

Of course, you can already do this with the regular old getCollection method:

BiFunction<String, Class<Category>, MongoCollection<Category>> factory = repository::getCollection;

So the usefulness of the factory method is questionable.

The BiFunction has wrong the third type (the result type) that should be MongoCollection<T> :

public BiFunction<String, Class<T>, MongoCollection<T>> getCollection = (name, type) -> 
    mongoClient
        .getDatabase(mongodbConfiguration.getDatabase())
        .getCollection(name, type);

Also note the T must be the class generic parameter as long as getCollection is no longer a method but a field.

public class ClassHavingGetCollectionField<T> {
   ...
}

... otherwise you need to define a method with a generic type returning such functional interface implementation:

public <T> BiFunction<String, Class<T>, MongoCollection<T>> getCollectionBiFunction() {
    return (name, type) ->
         mongoClient
             .getDatabase(mongodbConfiguration.getDatabase())
             .getCollection(name, type);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM