• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.base;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 
22 import com.google.common.annotations.Beta;
23 import com.google.common.annotations.GwtCompatible;
24 
25 import java.io.Serializable;
26 import java.util.Map;
27 
28 import javax.annotation.Nullable;
29 
30 /**
31  * Static utility methods pertaining to {@code Function} instances.
32  *
33  * <p>All methods returns serializable functions as long as they're given serializable parameters.
34  *
35  * @author Mike Bostock
36  * @author Jared Levy
37  * @since 2.0 (imported from Google Collections Library)
38  */
39 @GwtCompatible
40 public final class Functions {
Functions()41   private Functions() {}
42 
43   /**
44    * Returns a function that calls {@code toString()} on its argument. The function does not accept
45    * nulls; it will throw a {@link NullPointerException} when applied to {@code null}.
46    *
47    * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
48    * documented at {@link Function#apply}). For example, this function yields different results for
49    * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
50    */
toStringFunction()51   public static Function<Object, String> toStringFunction() {
52     return ToStringFunction.INSTANCE;
53   }
54 
55   // enum singleton pattern
56   private enum ToStringFunction implements Function<Object, String> {
57     INSTANCE;
58 
59     @Override
apply(Object o)60     public String apply(Object o) {
61       checkNotNull(o);  // eager for GWT.
62       return o.toString();
63     }
64 
toString()65     @Override public String toString() {
66       return "toString";
67     }
68   }
69 
70   /**
71    * Returns the identity function.
72    */
73   @SuppressWarnings("unchecked")
identity()74   public static <E> Function<E, E> identity() {
75     return (Function<E, E>) IdentityFunction.INSTANCE;
76   }
77 
78   // enum singleton pattern
79   private enum IdentityFunction implements Function<Object, Object> {
80     INSTANCE;
81 
82     @Override
apply(Object o)83     public Object apply(Object o) {
84       return o;
85     }
86 
toString()87     @Override public String toString() {
88       return "identity";
89     }
90   }
91 
92   /**
93    * Returns a function which performs a map lookup. The returned function throws an {@link
94    * IllegalArgumentException} if given a key that does not exist in the map.
95    */
forMap(Map<K, V> map)96   public static <K, V> Function<K, V> forMap(Map<K, V> map) {
97     return new FunctionForMapNoDefault<K, V>(map);
98   }
99 
100   private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable {
101     final Map<K, V> map;
102 
FunctionForMapNoDefault(Map<K, V> map)103     FunctionForMapNoDefault(Map<K, V> map) {
104       this.map = checkNotNull(map);
105     }
106 
107     @Override
apply(K key)108     public V apply(K key) {
109       V result = map.get(key);
110       checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
111       return result;
112     }
113 
equals(@ullable Object o)114     @Override public boolean equals(@Nullable Object o) {
115       if (o instanceof FunctionForMapNoDefault) {
116         FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
117         return map.equals(that.map);
118       }
119       return false;
120     }
121 
hashCode()122     @Override public int hashCode() {
123       return map.hashCode();
124     }
125 
toString()126     @Override public String toString() {
127       return "forMap(" + map + ")";
128     }
129 
130     private static final long serialVersionUID = 0;
131   }
132 
133   /**
134    * Returns a function which performs a map lookup with a default value. The function created by
135    * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
136    * set.
137    *
138    * @param map source map that determines the function behavior
139    * @param defaultValue the value to return for inputs that aren't map keys
140    * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
141    *         defaultValue} otherwise
142    */
forMap(Map<K, ? extends V> map, @Nullable V defaultValue)143   public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) {
144     return new ForMapWithDefault<K, V>(map, defaultValue);
145   }
146 
147   private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable {
148     final Map<K, ? extends V> map;
149     final V defaultValue;
150 
ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue)151     ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) {
152       this.map = checkNotNull(map);
153       this.defaultValue = defaultValue;
154     }
155 
156     @Override
apply(K key)157     public V apply(K key) {
158       V result = map.get(key);
159       return (result != null || map.containsKey(key)) ? result : defaultValue;
160     }
161 
equals(@ullable Object o)162     @Override public boolean equals(@Nullable Object o) {
163       if (o instanceof ForMapWithDefault) {
164         ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
165         return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
166       }
167       return false;
168     }
169 
hashCode()170     @Override public int hashCode() {
171       return Objects.hashCode(map, defaultValue);
172     }
173 
toString()174     @Override public String toString() {
175       return "forMap(" + map + ", defaultValue=" + defaultValue + ")";
176     }
177 
178     private static final long serialVersionUID = 0;
179   }
180 
181   /**
182    * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
183    * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
184    *
185    * @param g the second function to apply
186    * @param f the first function to apply
187    * @return the composition of {@code f} and {@code g}
188    * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
189    */
compose(Function<B, C> g, Function<A, ? extends B> f)190   public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
191     return new FunctionComposition<A, B, C>(g, f);
192   }
193 
194   private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
195     private final Function<B, C> g;
196     private final Function<A, ? extends B> f;
197 
FunctionComposition(Function<B, C> g, Function<A, ? extends B> f)198     public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
199       this.g = checkNotNull(g);
200       this.f = checkNotNull(f);
201     }
202 
203     @Override
apply(A a)204     public C apply(A a) {
205       return g.apply(f.apply(a));
206     }
207 
equals(@ullable Object obj)208     @Override public boolean equals(@Nullable Object obj) {
209       if (obj instanceof FunctionComposition) {
210         FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
211         return f.equals(that.f) && g.equals(that.g);
212       }
213       return false;
214     }
215 
hashCode()216     @Override public int hashCode() {
217       return f.hashCode() ^ g.hashCode();
218     }
219 
toString()220     @Override public String toString() {
221       return g.toString() + "(" + f.toString() + ")";
222     }
223 
224     private static final long serialVersionUID = 0;
225   }
226 
227   /**
228    * Creates a function that returns the same boolean output as the given predicate for all inputs.
229    *
230    * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
231    * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
232    */
forPredicate(Predicate<T> predicate)233   public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) {
234     return new PredicateFunction<T>(predicate);
235   }
236 
237   /** @see Functions#forPredicate */
238   private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable {
239     private final Predicate<T> predicate;
240 
PredicateFunction(Predicate<T> predicate)241     private PredicateFunction(Predicate<T> predicate) {
242       this.predicate = checkNotNull(predicate);
243     }
244 
245     @Override
apply(T t)246     public Boolean apply(T t) {
247       return predicate.apply(t);
248     }
249 
equals(@ullable Object obj)250     @Override public boolean equals(@Nullable Object obj) {
251       if (obj instanceof PredicateFunction) {
252         PredicateFunction<?> that = (PredicateFunction<?>) obj;
253         return predicate.equals(that.predicate);
254       }
255       return false;
256     }
257 
hashCode()258     @Override public int hashCode() {
259       return predicate.hashCode();
260     }
261 
toString()262     @Override public String toString() {
263       return "forPredicate(" + predicate + ")";
264     }
265 
266     private static final long serialVersionUID = 0;
267   }
268 
269   /**
270    * Creates a function that returns {@code value} for any input.
271    *
272    * @param value the constant value for the function to return
273    * @return a function that always returns {@code value}
274    */
constant(@ullable E value)275   public static <E> Function<Object, E> constant(@Nullable E value) {
276     return new ConstantFunction<E>(value);
277   }
278 
279   private static class ConstantFunction<E> implements Function<Object, E>, Serializable {
280     private final E value;
281 
ConstantFunction(@ullable E value)282     public ConstantFunction(@Nullable E value) {
283       this.value = value;
284     }
285 
286     @Override
apply(@ullable Object from)287     public E apply(@Nullable Object from) {
288       return value;
289     }
290 
equals(@ullable Object obj)291     @Override public boolean equals(@Nullable Object obj) {
292       if (obj instanceof ConstantFunction) {
293         ConstantFunction<?> that = (ConstantFunction<?>) obj;
294         return Objects.equal(value, that.value);
295       }
296       return false;
297     }
298 
hashCode()299     @Override public int hashCode() {
300       return (value == null) ? 0 : value.hashCode();
301     }
302 
toString()303     @Override public String toString() {
304       return "constant(" + value + ")";
305     }
306 
307     private static final long serialVersionUID = 0;
308   }
309 
310   /**
311    * Returns a function that always returns the result of invoking {@link Supplier#get} on {@code
312    * supplier}, regardless of its input.
313    *
314    * @since 10.0
315    */
316   @Beta
forSupplier(Supplier<T> supplier)317   public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) {
318     return new SupplierFunction<T>(supplier);
319   }
320 
321   /** @see Functions#forSupplier*/
322   private static class SupplierFunction<T> implements Function<Object, T>, Serializable {
323 
324     private final Supplier<T> supplier;
325 
SupplierFunction(Supplier<T> supplier)326     private SupplierFunction(Supplier<T> supplier) {
327       this.supplier = checkNotNull(supplier);
328     }
329 
apply(@ullable Object input)330     @Override public T apply(@Nullable Object input) {
331       return supplier.get();
332     }
333 
equals(@ullable Object obj)334     @Override public boolean equals(@Nullable Object obj) {
335       if (obj instanceof SupplierFunction) {
336         SupplierFunction<?> that = (SupplierFunction<?>) obj;
337         return this.supplier.equals(that.supplier);
338       }
339       return false;
340     }
341 
hashCode()342     @Override public int hashCode() {
343       return supplier.hashCode();
344     }
345 
toString()346     @Override public String toString() {
347       return "forSupplier(" + supplier + ")";
348     }
349 
350     private static final long serialVersionUID = 0;
351   }
352 }
353