001/*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 */
014
015package com.google.common.base;
016
017import static com.google.common.base.NullnessCasts.uncheckedCastNullableTToT;
018import static com.google.common.base.Preconditions.checkArgument;
019import static com.google.common.base.Preconditions.checkNotNull;
020
021import com.google.common.annotations.GwtCompatible;
022import java.io.Serializable;
023import java.util.Map;
024import javax.annotation.CheckForNull;
025import org.checkerframework.checker.nullness.qual.Nullable;
026
027/**
028 * Static utility methods pertaining to {@code com.google.common.base.Function} instances; see that
029 * class for information about migrating to {@code java.util.function}.
030 *
031 * <p>All methods return serializable functions as long as they're given serializable parameters.
032 *
033 * <p>See the Guava User Guide article on <a
034 * href="https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code Function}</a>.
035 *
036 * @author Mike Bostock
037 * @author Jared Levy
038 * @since 2.0
039 */
040@GwtCompatible
041@ElementTypesAreNonnullByDefault
042public final class Functions {
043  private Functions() {}
044
045  /**
046   * A function equivalent to the method reference {@code Object::toString}, for users not yet using
047   * Java 8. The function simply invokes {@code toString} on its argument and returns the result. It
048   * throws a {@link NullPointerException} on null input.
049   *
050   * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
051   * documented at {@link Function#apply}). For example, this function yields different results for
052   * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
053   *
054   * <p><b>Warning:</b> as with all function types in this package, avoid depending on the specific
055   * {@code equals}, {@code hashCode} or {@code toString} behavior of the returned function. A
056   * future migration to {@code java.util.function} will not preserve this behavior.
057   *
058   * <p><b>For Java 8 users:</b> use the method reference {@code Object::toString} instead. In the
059   * future, when this class requires Java 8, this method will be deprecated. See {@link Function}
060   * for more important information about the Java 8 transition.
061   */
062  public static Function<Object, String> toStringFunction() {
063    return ToStringFunction.INSTANCE;
064  }
065
066  // enum singleton pattern
067  private enum ToStringFunction implements Function<Object, String> {
068    INSTANCE;
069
070    @Override
071    public String apply(Object o) {
072      checkNotNull(o); // eager for GWT.
073      return o.toString();
074    }
075
076    @Override
077    public String toString() {
078      return "Functions.toStringFunction()";
079    }
080  }
081
082  /** Returns the identity function. */
083  // implementation is "fully variant"; E has become a "pass-through" type
084  @SuppressWarnings("unchecked")
085  public static <E extends @Nullable Object> Function<E, E> identity() {
086    return (Function<E, E>) IdentityFunction.INSTANCE;
087  }
088
089  // enum singleton pattern
090  private enum IdentityFunction implements Function<@Nullable Object, @Nullable Object> {
091    INSTANCE;
092
093    @Override
094    @CheckForNull
095    public Object apply(@CheckForNull Object o) {
096      return o;
097    }
098
099    @Override
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   */
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   */
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
146    FunctionForMapNoDefault(Map<K, V> map) {
147      this.map = checkNotNull(map);
148    }
149
150    @Override
151    @ParametricNullness
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
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
169    public int hashCode() {
170      return map.hashCode();
171    }
172
173    @Override
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
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
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
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
211    public int hashCode() {
212      return Objects.hashCode(map, defaultValue);
213    }
214
215    @Override
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>
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
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
254    public C apply(@ParametricNullness A a) {
255      return g.apply(f.apply(a));
256    }
257
258    @Override
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
268    public int hashCode() {
269      return f.hashCode() ^ g.hashCode();
270    }
271
272    @Override
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   */
289  public static <T extends @Nullable Object> Function<T, Boolean> forPredicate(
290      Predicate<T> predicate) {
291    return new PredicateFunction<T>(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
299    private PredicateFunction(Predicate<T> predicate) {
300      this.predicate = checkNotNull(predicate);
301    }
302
303    @Override
304    public Boolean apply(@ParametricNullness T t) {
305      return predicate.apply(t);
306    }
307
308    @Override
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
318    public int hashCode() {
319      return predicate.hashCode();
320    }
321
322    @Override
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   */
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
347    public ConstantFunction(@ParametricNullness E value) {
348      this.value = value;
349    }
350
351    @Override
352    @ParametricNullness
353    public E apply(@CheckForNull Object from) {
354      return value;
355    }
356
357    @Override
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
367    public int hashCode() {
368      return (value == null) ? 0 : value.hashCode();
369    }
370
371    @Override
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   */
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
397    private SupplierFunction(Supplier<T> supplier) {
398      this.supplier = checkNotNull(supplier);
399    }
400
401    @Override
402    @ParametricNullness
403    public T apply(@ParametricNullness F input) {
404      return supplier.get();
405    }
406
407    @Override
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
417    public int hashCode() {
418      return supplier.hashCode();
419    }
420
421    @Override
422    public String toString() {
423      return "Functions.forSupplier(" + supplier + ")";
424    }
425
426    private static final long serialVersionUID = 0;
427  }
428}