• 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"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.common.base;
16 
17 import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT;
18 import static com.google.common.base.Preconditions.checkArgument;
19 import static com.google.common.base.Preconditions.checkNotNull;
20 
21 import com.google.common.annotations.GwtCompatible;
22 import java.io.Serializable;
23 import java.util.Map;
24 import javax.annotation.CheckForNull;
25 import org.checkerframework.checker.nullness.qual.Nullable;
26 
27 /**
28  * Static utility methods pertaining to {@code com.google.common.base.Function} instances; see that
29  * class for information about migrating to {@code java.util.function}.
30  *
31  * <p>All methods return serializable functions as long as they're given serializable parameters.
32  *
33  * <p>See the Guava User Guide article on <a
34  * href="https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code Function}</a>.
35  *
36  * @author Mike Bostock
37  * @author Jared Levy
38  * @since 2.0
39  */
40 @GwtCompatible
41 @ElementTypesAreNonnullByDefault
42 public final class Functions {
Functions()43   private Functions() {}
44 
45   /**
46    * A function equivalent to the method reference {@code Object::toString}, for users not yet using
47    * Java 8. The function simply invokes {@code toString} on its argument and returns the result. It
48    * throws a {@link NullPointerException} on null input.
49    *
50    * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
51    * documented at {@link Function#apply}). For example, this function yields different results for
52    * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
53    *
54    * <p><b>Warning:</b> as with all function types in this package, avoid depending on the specific
55    * {@code equals}, {@code hashCode} or {@code toString} behavior of the returned function. A
56    * future migration to {@code java.util.function} will not preserve this behavior.
57    *
58    * <p><b>For Java 8 users:</b> use the method reference {@code Object::toString} instead. In the
59    * future, when this class requires Java 8, this method will be deprecated. See {@link Function}
60    * for more important information about the Java 8 transition.
61    */
toStringFunction()62   public static Function<Object, String> toStringFunction() {
63     return ToStringFunction.INSTANCE;
64   }
65 
66   // enum singleton pattern
67   private enum ToStringFunction implements Function<Object, String> {
68     INSTANCE;
69 
70     @Override
apply(Object o)71     public String apply(Object o) {
72       checkNotNull(o); // eager for GWT.
73       return o.toString();
74     }
75 
76     @Override
toString()77     public String toString() {
78       return "Functions.toStringFunction()";
79     }
80   }
81 
82   /** Returns the identity function. */
83   // implementation is "fully variant"; E has become a "pass-through" type
84   @SuppressWarnings("unchecked")
identity()85   public static <E extends @Nullable Object> Function<E, E> identity() {
86     return (Function<E, E>) IdentityFunction.INSTANCE;
87   }
88 
89   // enum singleton pattern
90   private enum IdentityFunction implements Function<@Nullable Object, @Nullable Object> {
91     INSTANCE;
92 
93     @Override
94     @CheckForNull
apply(@heckForNull Object o)95     public Object apply(@CheckForNull Object o) {
96       return o;
97     }
98 
99     @Override
toString()100     public String toString() {
101       return "Functions.identity()";
102     }
103   }
104 
105   /**
106    * Returns a function which performs a map lookup. The returned function throws an {@link
107    * IllegalArgumentException} if given a key that does not exist in the map. See also {@link
108    * #forMap(Map, Object)}, which returns a default value in this case.
109    *
110    * <p>Note: if {@code map} is a {@link com.google.common.collect.BiMap BiMap} (or can be one), you
111    * can use {@link com.google.common.collect.Maps#asConverter Maps.asConverter} instead to get a
112    * function that also supports reverse conversion.
113    *
114    * <p><b>Java 8 users:</b> if you are okay with {@code null} being returned for an unrecognized
115    * key (instead of an exception being thrown), you can use the method reference {@code map::get}
116    * instead.
117    */
forMap( Map<K, V> map)118   public static <K extends @Nullable Object, V extends @Nullable Object> Function<K, V> forMap(
119       Map<K, V> map) {
120     return new FunctionForMapNoDefault<>(map);
121   }
122 
123   /**
124    * Returns a function which performs a map lookup with a default value. The function created by
125    * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
126    * set. See also {@link #forMap(Map)}, which throws an exception in this case.
127    *
128    * <p><b>Java 8 users:</b> you can just write the lambda expression {@code k ->
129    * map.getOrDefault(k, defaultValue)} instead.
130    *
131    * @param map source map that determines the function behavior
132    * @param defaultValue the value to return for inputs that aren't map keys
133    * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
134    *     defaultValue} otherwise
135    */
forMap( Map<K, ? extends V> map, @ParametricNullness V defaultValue)136   public static <K extends @Nullable Object, V extends @Nullable Object> Function<K, V> forMap(
137       Map<K, ? extends V> map, @ParametricNullness V defaultValue) {
138     return new ForMapWithDefault<>(map, defaultValue);
139   }
140 
141   private static class FunctionForMapNoDefault<
142           K extends @Nullable Object, V extends @Nullable Object>
143       implements Function<K, V>, Serializable {
144     final Map<K, V> map;
145 
FunctionForMapNoDefault(Map<K, V> map)146     FunctionForMapNoDefault(Map<K, V> map) {
147       this.map = checkNotNull(map);
148     }
149 
150     @Override
151     @ParametricNullness
apply(@arametricNullness K key)152     public V apply(@ParametricNullness K key) {
153       V result = map.get(key);
154       checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
155       // The unchecked cast is safe because of the containsKey check.
156       return uncheckedCastNullableTToT(result);
157     }
158 
159     @Override
equals(@heckForNull Object o)160     public boolean equals(@CheckForNull Object o) {
161       if (o instanceof FunctionForMapNoDefault) {
162         FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
163         return map.equals(that.map);
164       }
165       return false;
166     }
167 
168     @Override
hashCode()169     public int hashCode() {
170       return map.hashCode();
171     }
172 
173     @Override
toString()174     public String toString() {
175       return "Functions.forMap(" + map + ")";
176     }
177 
178     private static final long serialVersionUID = 0;
179   }
180 
181   private static class ForMapWithDefault<K extends @Nullable Object, V extends @Nullable Object>
182       implements Function<K, V>, Serializable {
183     final Map<K, ? extends V> map;
184     @ParametricNullness final V defaultValue;
185 
ForMapWithDefault(Map<K, ? extends V> map, @ParametricNullness V defaultValue)186     ForMapWithDefault(Map<K, ? extends V> map, @ParametricNullness V defaultValue) {
187       this.map = checkNotNull(map);
188       this.defaultValue = defaultValue;
189     }
190 
191     @Override
192     @ParametricNullness
apply(@arametricNullness K key)193     public V apply(@ParametricNullness K key) {
194       V result = map.get(key);
195       // The unchecked cast is safe because of the containsKey check.
196       return (result != null || map.containsKey(key))
197           ? uncheckedCastNullableTToT(result)
198           : defaultValue;
199     }
200 
201     @Override
equals(@heckForNull Object o)202     public boolean equals(@CheckForNull Object o) {
203       if (o instanceof ForMapWithDefault) {
204         ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
205         return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
206       }
207       return false;
208     }
209 
210     @Override
hashCode()211     public int hashCode() {
212       return Objects.hashCode(map, defaultValue);
213     }
214 
215     @Override
toString()216     public String toString() {
217       // TODO(cpovirk): maybe remove "defaultValue=" to make this look like the method call does
218       return "Functions.forMap(" + map + ", defaultValue=" + defaultValue + ")";
219     }
220 
221     private static final long serialVersionUID = 0;
222   }
223 
224   /**
225    * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
226    * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
227    *
228    * <p><b>Java 8 users:</b> use {@code g.compose(f)} or (probably clearer) {@code f.andThen(g)}
229    * instead.
230    *
231    * @param g the second function to apply
232    * @param f the first function to apply
233    * @return the composition of {@code f} and {@code g}
234    * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
235    */
236   public static <A extends @Nullable Object, B extends @Nullable Object, C extends @Nullable Object>
compose(Function<B, C> g, Function<A, ? extends B> f)237       Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
238     return new FunctionComposition<>(g, f);
239   }
240 
241   private static class FunctionComposition<
242           A extends @Nullable Object, B extends @Nullable Object, C extends @Nullable Object>
243       implements Function<A, C>, Serializable {
244     private final Function<B, C> g;
245     private final Function<A, ? extends B> f;
246 
FunctionComposition(Function<B, C> g, Function<A, ? extends B> f)247     public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
248       this.g = checkNotNull(g);
249       this.f = checkNotNull(f);
250     }
251 
252     @Override
253     @ParametricNullness
apply(@arametricNullness A a)254     public C apply(@ParametricNullness A a) {
255       return g.apply(f.apply(a));
256     }
257 
258     @Override
equals(@heckForNull Object obj)259     public boolean equals(@CheckForNull Object obj) {
260       if (obj instanceof FunctionComposition) {
261         FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
262         return f.equals(that.f) && g.equals(that.g);
263       }
264       return false;
265     }
266 
267     @Override
hashCode()268     public int hashCode() {
269       return f.hashCode() ^ g.hashCode();
270     }
271 
272     @Override
toString()273     public String toString() {
274       // TODO(cpovirk): maybe make this look like the method call does ("Functions.compose(...)")
275       return g + "(" + f + ")";
276     }
277 
278     private static final long serialVersionUID = 0;
279   }
280 
281   /**
282    * Creates a function that returns the same boolean output as the given predicate for all inputs.
283    *
284    * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
285    * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
286    *
287    * <p><b>Java 8 users:</b> use the method reference {@code predicate::test} instead.
288    */
forPredicate( Predicate<T> predicate)289   public static <T extends @Nullable Object> Function<T, Boolean> forPredicate(
290       Predicate<T> predicate) {
291     return new PredicateFunction<>(predicate);
292   }
293 
294   /** @see Functions#forPredicate */
295   private static class PredicateFunction<T extends @Nullable Object>
296       implements Function<T, Boolean>, Serializable {
297     private final Predicate<T> predicate;
298 
PredicateFunction(Predicate<T> predicate)299     private PredicateFunction(Predicate<T> predicate) {
300       this.predicate = checkNotNull(predicate);
301     }
302 
303     @Override
apply(@arametricNullness T t)304     public Boolean apply(@ParametricNullness T t) {
305       return predicate.apply(t);
306     }
307 
308     @Override
equals(@heckForNull Object obj)309     public boolean equals(@CheckForNull Object obj) {
310       if (obj instanceof PredicateFunction) {
311         PredicateFunction<?> that = (PredicateFunction<?>) obj;
312         return predicate.equals(that.predicate);
313       }
314       return false;
315     }
316 
317     @Override
hashCode()318     public int hashCode() {
319       return predicate.hashCode();
320     }
321 
322     @Override
toString()323     public String toString() {
324       return "Functions.forPredicate(" + predicate + ")";
325     }
326 
327     private static final long serialVersionUID = 0;
328   }
329 
330   /**
331    * Returns a function that ignores its input and always returns {@code value}.
332    *
333    * <p><b>Java 8 users:</b> use the lambda expression {@code o -> value} instead.
334    *
335    * @param value the constant value for the function to return
336    * @return a function that always returns {@code value}
337    */
constant( @arametricNullness E value)338   public static <E extends @Nullable Object> Function<@Nullable Object, E> constant(
339       @ParametricNullness E value) {
340     return new ConstantFunction<>(value);
341   }
342 
343   private static class ConstantFunction<E extends @Nullable Object>
344       implements Function<@Nullable Object, E>, Serializable {
345     @ParametricNullness private final E value;
346 
ConstantFunction(@arametricNullness E value)347     public ConstantFunction(@ParametricNullness E value) {
348       this.value = value;
349     }
350 
351     @Override
352     @ParametricNullness
apply(@heckForNull Object from)353     public E apply(@CheckForNull Object from) {
354       return value;
355     }
356 
357     @Override
equals(@heckForNull Object obj)358     public boolean equals(@CheckForNull Object obj) {
359       if (obj instanceof ConstantFunction) {
360         ConstantFunction<?> that = (ConstantFunction<?>) obj;
361         return Objects.equal(value, that.value);
362       }
363       return false;
364     }
365 
366     @Override
hashCode()367     public int hashCode() {
368       return (value == null) ? 0 : value.hashCode();
369     }
370 
371     @Override
toString()372     public String toString() {
373       return "Functions.constant(" + value + ")";
374     }
375 
376     private static final long serialVersionUID = 0;
377   }
378 
379   /**
380    * Returns a function that ignores its input and returns the result of {@code supplier.get()}.
381    *
382    * <p><b>Java 8 users:</b> use the lambda expression {@code o -> supplier.get()} instead.
383    *
384    * @since 10.0
385    */
forSupplier( Supplier<T> supplier)386   public static <F extends @Nullable Object, T extends @Nullable Object> Function<F, T> forSupplier(
387       Supplier<T> supplier) {
388     return new SupplierFunction<>(supplier);
389   }
390 
391   /** @see Functions#forSupplier */
392   private static class SupplierFunction<F extends @Nullable Object, T extends @Nullable Object>
393       implements Function<F, T>, Serializable {
394 
395     private final Supplier<T> supplier;
396 
SupplierFunction(Supplier<T> supplier)397     private SupplierFunction(Supplier<T> supplier) {
398       this.supplier = checkNotNull(supplier);
399     }
400 
401     @Override
402     @ParametricNullness
apply(@arametricNullness F input)403     public T apply(@ParametricNullness F input) {
404       return supplier.get();
405     }
406 
407     @Override
equals(@heckForNull Object obj)408     public boolean equals(@CheckForNull Object obj) {
409       if (obj instanceof SupplierFunction) {
410         SupplierFunction<?, ?> that = (SupplierFunction<?, ?>) obj;
411         return this.supplier.equals(that.supplier);
412       }
413       return false;
414     }
415 
416     @Override
hashCode()417     public int hashCode() {
418       return supplier.hashCode();
419     }
420 
421     @Override
toString()422     public String toString() {
423       return "Functions.forSupplier(" + supplier + ")";
424     }
425 
426     private static final long serialVersionUID = 0;
427   }
428 }
429