Please explain the use of the interface Supplier(in Guava) with a suitable example .
6 Answers
The Supplier interface is simply an abstraction of a no-arg function that returns a value... it is a means of getting some instance or instances of an object. Since it is so general, it can be used as many things. Jared explained how the Multimaps factories utilize it as a factory for creating a new instance of a Collection of some type for values.
Given the simplicity of the interface, it also allows for some very powerful decoration of a Supplier's behavior by wrapping it in another Supplier that alters its behavior somehow. Memoization is one example of that. I've used the Suppliers.memoizeWithExpiration method myself as an easy way to make it so some data will only be read from a server at most once in a given period of time.
I'd also recommend taking a look at Guice and how the Provider interface is used in it. Provider is exactly equivalent to Supplier and is central to how Guice works.
Providerallows users to define a custom way of creating new objects of a given class. Users can write aget()method which can execute whatever code is needed to create a new object, so they aren't limited to having Guice use constructors alone to create objects. Here, they are using it to define a custom factory for new instance of an object.- Guice allows injection of a
Providerof any dependency. This may return a new instance every timeget()is called or it may always return a single instance or anything in between, depending on how the binding theProviderrepresents is scoped. This also allows for "lazy instantiation" of dependencies... theProvidergives a class a means of creating an object without needing to actually create the object ahead of time. An instance of the object does not need to be created until when, and if,get()is called. - As indicated above,
Providers form the basis of scoping in Guice. If you take a look at the Scope interface, you'll notice its single methodProvider<T> scope(Key<T> key, Provider<T> unscoped)is defined in terms ofProviders. This method takes something that creates a new instance of an object (theProvider<T> unscoped) and returns aProvider<T>based on that which applies whatever policy the scope defines, potentially returning some cached instance of the object rather than creating a new one. The defaultNO_SCOPEscope simply passes along theunscopedprovider, meaning a new instance will be created each time. TheSINGLETONscope caches the result of the first call tounscoped.get()and thereafter returns that single instance, ensuring that everything that depends on the singleton-scoped object gets a reference to that single object. Note that theProviderreturned by theSINGLETONscope'sscopemethod does essentially the same thing as theSupplierreturned bySuppliers.memoize(though it's a bit more complicated).
The main reason we included Supplier in Guava was to support the Multimaps methods that generate arbitrary Multimaps, such as
public static <K,V> Multimap<K,V> newMultimap(Map<K,Collection<V>> map,
Supplier<? extends Collection<V>> factory)
The Supplier creates a Collection that holds all of the values for a given key. The Multimap uses the Supplier whenever you store a key-value pair with a key that's not already in the Multimap.
- 1,544
- 2
- 14
- 15
- 1,986
- 13
- 12
-
Do you know about mnemonize in suppliers ?If so please give a sample for that too. – Emil Nov 10 '10 at 07:55
-
1@Emil: `memoize` gets use e.g. [here](http://stackoverflow.com/questions/3636244/thread-safe-cache-of-one-object-in-java/3636791#3636791) – maaartinus Sep 14 '11 at 08:27
It's a way to provide an indirect object. You may want to provide another object each time Supplier.get() is called.
For example, i have a singleton class called SmtpMailSender, which takes a hostname for the smtp server. However, the hostname can change at runtime, so instead of taking a String hostname, it takes a Supplier<String> hostname.
- 27,242
- 4
- 49
- 58
Another example use of Supplier:
http://javawayoflife.blogspot.com/2010/06/unit-test-and-new-date.html
- 31
- 1
Another great use of the class is decoupling - if a component only uses another to obtain a value, do not depend on the concrete implementation, but on this interface.
Anyway, there is some example code here: http://www.slideshare.net/tfnico/google-guava
- 21,755
- 5
- 88
- 103