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>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  /**
083   * Returns the identity function.
084   *
085   * <p><b>Discouraged:</b> Prefer using a lambda like {@code v -> v}, which is shorter and often
086   * more readable.
087   */
088  // implementation is "fully variant"; E has become a "pass-through" type
089  @SuppressWarnings("unchecked")
090  public static <E extends @Nullable Object> Function<E, E> identity() {
091    return (Function<E, E>) IdentityFunction.INSTANCE;
092  }
093
094  // enum singleton pattern
095  private enum IdentityFunction implements Function<@Nullable Object, @Nullable Object> {
096    INSTANCE;
097
098    @Override
099    @CheckForNull
100    public Object apply(@CheckForNull Object o) {
101      return o;
102    }
103
104    @Override
105    public String toString() {
106      return "Functions.identity()";
107    }
108  }
109
110  /**
111   * Returns a function which performs a map lookup. The returned function throws an {@link
112   * IllegalArgumentException} if given a key that does not exist in the map. See also {@link
113   * #forMap(Map, Object)}, which returns a default value in this case.
114   *
115   * <p>Note: if {@code map} is a {@link com.google.common.collect.BiMap BiMap} (or can be one), you
116   * can use {@link com.google.common.collect.Maps#asConverter Maps.asConverter} instead to get a
117   * function that also supports reverse conversion.
118   *
119   * <p><b>Java 8+ users:</b> if you are okay with {@code null} being returned for an unrecognized
120   * key (instead of an exception being thrown), you can use the method reference {@code map::get}
121   * instead.
122   */
123  public static <K extends @Nullable Object, V extends @Nullable Object> Function<K, V> forMap(
124      Map<K, V> map) {
125    return new FunctionForMapNoDefault<>(map);
126  }
127
128  /**
129   * Returns a function which performs a map lookup with a default value. The function created by
130   * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
131   * set. See also {@link #forMap(Map)}, which throws an exception in this case.
132   *
133   * <p><b>Java 8+ users:</b> you can just write the lambda expression {@code k ->
134   * map.getOrDefault(k, defaultValue)} instead.
135   *
136   * @param map source map that determines the function behavior
137   * @param defaultValue the value to return for inputs that aren't map keys
138   * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
139   *     defaultValue} otherwise
140   */
141  public static <K extends @Nullable Object, V extends @Nullable Object> Function<K, V> forMap(
142      Map<K, ? extends V> map, @ParametricNullness V defaultValue) {
143    return new ForMapWithDefault<>(map, defaultValue);
144  }
145
146  private static class FunctionForMapNoDefault<
147          K extends @Nullable Object, V extends @Nullable Object>
148      implements Function<K, V>, Serializable {
149    final Map<K, V> map;
150
151    FunctionForMapNoDefault(Map<K, V> map) {
152      this.map = checkNotNull(map);
153    }
154
155    @Override
156    @ParametricNullness
157    public V apply(@ParametricNullness K key) {
158      V result = map.get(key);
159      checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
160      // The unchecked cast is safe because of the containsKey check.
161      return uncheckedCastNullableTToT(result);
162    }
163
164    @Override
165    public boolean equals(@CheckForNull Object o) {
166      if (o instanceof FunctionForMapNoDefault) {
167        FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
168        return map.equals(that.map);
169      }
170      return false;
171    }
172
173    @Override
174    public int hashCode() {
175      return map.hashCode();
176    }
177
178    @Override
179    public String toString() {
180      return "Functions.forMap(" + map + ")";
181    }
182
183    private static final long serialVersionUID = 0;
184  }
185
186  private static class ForMapWithDefault<K extends @Nullable Object, V extends @Nullable Object>
187      implements Function<K, V>, Serializable {
188    final Map<K, ? extends V> map;
189    @ParametricNullness final V defaultValue;
190
191    ForMapWithDefault(Map<K, ? extends V> map, @ParametricNullness V defaultValue) {
192      this.map = checkNotNull(map);
193      this.defaultValue = defaultValue;
194    }
195
196    @Override
197    @ParametricNullness
198    public V apply(@ParametricNullness K key) {
199      V result = map.get(key);
200      // The unchecked cast is safe because of the containsKey check.
201      return (result != null || map.containsKey(key))
202          ? uncheckedCastNullableTToT(result)
203          : defaultValue;
204    }
205
206    @Override
207    public boolean equals(@CheckForNull Object o) {
208      if (o instanceof ForMapWithDefault) {
209        ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
210        return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
211      }
212      return false;
213    }
214
215    @Override
216    public int hashCode() {
217      return Objects.hashCode(map, defaultValue);
218    }
219
220    @Override
221    public String toString() {
222      // TODO(cpovirk): maybe remove "defaultValue=" to make this look like the method call does
223      return "Functions.forMap(" + map + ", defaultValue=" + defaultValue + ")";
224    }
225
226    private static final long serialVersionUID = 0;
227  }
228
229  /**
230   * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
231   * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
232   *
233   * <p><b>Java 8+ users:</b> use {@code g.compose(f)} or (probably clearer) {@code f.andThen(g)}
234   * instead.
235   *
236   * @param g the second function to apply
237   * @param f the first function to apply
238   * @return the composition of {@code f} and {@code g}
239   * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
240   */
241  public static <A extends @Nullable Object, B extends @Nullable Object, C extends @Nullable Object>
242      Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
243    return new FunctionComposition<>(g, f);
244  }
245
246  private static class FunctionComposition<
247          A extends @Nullable Object, B extends @Nullable Object, C extends @Nullable Object>
248      implements Function<A, C>, Serializable {
249    private final Function<B, C> g;
250    private final Function<A, ? extends B> f;
251
252    public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
253      this.g = checkNotNull(g);
254      this.f = checkNotNull(f);
255    }
256
257    @Override
258    @ParametricNullness
259    public C apply(@ParametricNullness A a) {
260      return g.apply(f.apply(a));
261    }
262
263    @Override
264    public boolean equals(@CheckForNull Object obj) {
265      if (obj instanceof FunctionComposition) {
266        FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
267        return f.equals(that.f) && g.equals(that.g);
268      }
269      return false;
270    }
271
272    @Override
273    public int hashCode() {
274      return f.hashCode() ^ g.hashCode();
275    }
276
277    @Override
278    public String toString() {
279      // TODO(cpovirk): maybe make this look like the method call does ("Functions.compose(...)")
280      return g + "(" + f + ")";
281    }
282
283    private static final long serialVersionUID = 0;
284  }
285
286  /**
287   * Creates a function that returns the same boolean output as the given predicate for all inputs.
288   *
289   * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
290   * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
291   *
292   * <p><b>Java 8+ users:</b> use the method reference {@code predicate::test} instead.
293   */
294  public static <T extends @Nullable Object> Function<T, Boolean> forPredicate(
295      Predicate<T> predicate) {
296    return new PredicateFunction<>(predicate);
297  }
298
299  /** @see Functions#forPredicate */
300  private static class PredicateFunction<T extends @Nullable Object>
301      implements Function<T, Boolean>, Serializable {
302    private final Predicate<T> predicate;
303
304    private PredicateFunction(Predicate<T> predicate) {
305      this.predicate = checkNotNull(predicate);
306    }
307
308    @Override
309    public Boolean apply(@ParametricNullness T t) {
310      return predicate.apply(t);
311    }
312
313    @Override
314    public boolean equals(@CheckForNull Object obj) {
315      if (obj instanceof PredicateFunction) {
316        PredicateFunction<?> that = (PredicateFunction<?>) obj;
317        return predicate.equals(that.predicate);
318      }
319      return false;
320    }
321
322    @Override
323    public int hashCode() {
324      return predicate.hashCode();
325    }
326
327    @Override
328    public String toString() {
329      return "Functions.forPredicate(" + predicate + ")";
330    }
331
332    private static final long serialVersionUID = 0;
333  }
334
335  /**
336   * Returns a function that ignores its input and always returns {@code value}.
337   *
338   * <p><b>Java 8+ users:</b> use the lambda expression {@code o -> value} instead.
339   *
340   * @param value the constant value for the function to return
341   * @return a function that always returns {@code value}
342   */
343  public static <E extends @Nullable Object> Function<@Nullable Object, E> constant(
344      @ParametricNullness E value) {
345    return new ConstantFunction<>(value);
346  }
347
348  private static class ConstantFunction<E extends @Nullable Object>
349      implements Function<@Nullable Object, E>, Serializable {
350    @ParametricNullness private final E value;
351
352    public ConstantFunction(@ParametricNullness E value) {
353      this.value = value;
354    }
355
356    @Override
357    @ParametricNullness
358    public E apply(@CheckForNull Object from) {
359      return value;
360    }
361
362    @Override
363    public boolean equals(@CheckForNull Object obj) {
364      if (obj instanceof ConstantFunction) {
365        ConstantFunction<?> that = (ConstantFunction<?>) obj;
366        return Objects.equal(value, that.value);
367      }
368      return false;
369    }
370
371    @Override
372    public int hashCode() {
373      return (value == null) ? 0 : value.hashCode();
374    }
375
376    @Override
377    public String toString() {
378      return "Functions.constant(" + value + ")";
379    }
380
381    private static final long serialVersionUID = 0;
382  }
383
384  /**
385   * Returns a function that ignores its input and returns the result of {@code supplier.get()}.
386   *
387   * <p><b>Java 8+ users:</b> use the lambda expression {@code o -> supplier.get()} instead.
388   *
389   * @since 10.0
390   */
391  public static <F extends @Nullable Object, T extends @Nullable Object> Function<F, T> forSupplier(
392      Supplier<T> supplier) {
393    return new SupplierFunction<>(supplier);
394  }
395
396  /** @see Functions#forSupplier */
397  private static class SupplierFunction<F extends @Nullable Object, T extends @Nullable Object>
398      implements Function<F, T>, Serializable {
399
400    private final Supplier<T> supplier;
401
402    private SupplierFunction(Supplier<T> supplier) {
403      this.supplier = checkNotNull(supplier);
404    }
405
406    @Override
407    @ParametricNullness
408    public T apply(@ParametricNullness F input) {
409      return supplier.get();
410    }
411
412    @Override
413    public boolean equals(@CheckForNull Object obj) {
414      if (obj instanceof SupplierFunction) {
415        SupplierFunction<?, ?> that = (SupplierFunction<?, ?>) obj;
416        return this.supplier.equals(that.supplier);
417      }
418      return false;
419    }
420
421    @Override
422    public int hashCode() {
423      return supplier.hashCode();
424    }
425
426    @Override
427    public String toString() {
428      return "Functions.forSupplier(" + supplier + ")";
429    }
430
431    private static final long serialVersionUID = 0;
432  }
433}