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.Preconditions.checkArgument;
018import static com.google.common.base.Preconditions.checkNotNull;
019
020import com.google.common.annotations.GwtCompatible;
021import java.io.Serializable;
022import java.util.Map;
023import org.checkerframework.checker.nullness.compatqual.NullableDecl;
024
025/**
026 * Static utility methods pertaining to {@code com.google.common.base.Function} instances; see that
027 * class for information about migrating to {@code java.util.function}.
028 *
029 * <p>All methods return serializable functions as long as they're given serializable parameters.
030 *
031 * <p>See the Guava User Guide article on <a
032 * href="https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code Function}</a>.
033 *
034 * @author Mike Bostock
035 * @author Jared Levy
036 * @since 2.0
037 */
038@GwtCompatible
039public final class Functions {
040  private Functions() {}
041
042  /**
043   * A function equivalent to the method reference {@code Object::toString}, for users not yet using
044   * Java 8. The function simply invokes {@code toString} on its argument and returns the result. It
045   * throws a {@link NullPointerException} on null input.
046   *
047   * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
048   * documented at {@link Function#apply}). For example, this function yields different results for
049   * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
050   *
051   * <p><b>Warning:</b> as with all function types in this package, avoid depending on the specific
052   * {@code equals}, {@code hashCode} or {@code toString} behavior of the returned function. A
053   * future migration to {@code java.util.function} will not preserve this behavior.
054   *
055   * <p><b>For Java 8 users:</b> use the method reference {@code Object::toString} instead. In the
056   * future, when this class requires Java 8, this method will be deprecated. See {@link Function}
057   * for more important information about the Java 8 transition.
058   */
059  public static Function<Object, String> toStringFunction() {
060    return ToStringFunction.INSTANCE;
061  }
062
063  // enum singleton pattern
064  private enum ToStringFunction implements Function<Object, String> {
065    INSTANCE;
066
067    @Override
068    public String apply(Object o) {
069      checkNotNull(o); // eager for GWT.
070      return o.toString();
071    }
072
073    @Override
074    public String toString() {
075      return "Functions.toStringFunction()";
076    }
077  }
078
079  /** Returns the identity function. */
080  // implementation is "fully variant"; E has become a "pass-through" type
081  @SuppressWarnings("unchecked")
082  public static <E> Function<E, E> identity() {
083    return (Function<E, E>) IdentityFunction.INSTANCE;
084  }
085
086  // enum singleton pattern
087  private enum IdentityFunction implements Function<Object, Object> {
088    INSTANCE;
089
090    @Override
091    @NullableDecl
092    public Object apply(@NullableDecl Object o) {
093      return o;
094    }
095
096    @Override
097    public String toString() {
098      return "Functions.identity()";
099    }
100  }
101
102  /**
103   * Returns a function which performs a map lookup. The returned function throws an {@link
104   * IllegalArgumentException} if given a key that does not exist in the map. See also {@link
105   * #forMap(Map, Object)}, which returns a default value in this case.
106   *
107   * <p>Note: if {@code map} is a {@link com.google.common.collect.BiMap BiMap} (or can be one), you
108   * can use {@link com.google.common.collect.Maps#asConverter Maps.asConverter} instead to get a
109   * function that also supports reverse conversion.
110   *
111   * <p><b>Java 8 users:</b> if you are okay with {@code null} being returned for an unrecognized
112   * key (instead of an exception being thrown), you can use the method reference {@code map::get}
113   * instead.
114   */
115  public static <K, V> Function<K, V> forMap(Map<K, V> map) {
116    return new FunctionForMapNoDefault<>(map);
117  }
118
119  private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable {
120    final Map<K, V> map;
121
122    FunctionForMapNoDefault(Map<K, V> map) {
123      this.map = checkNotNull(map);
124    }
125
126    @Override
127    public V apply(@NullableDecl K key) {
128      V result = map.get(key);
129      checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
130      return result;
131    }
132
133    @Override
134    public boolean equals(@NullableDecl Object o) {
135      if (o instanceof FunctionForMapNoDefault) {
136        FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
137        return map.equals(that.map);
138      }
139      return false;
140    }
141
142    @Override
143    public int hashCode() {
144      return map.hashCode();
145    }
146
147    @Override
148    public String toString() {
149      return "Functions.forMap(" + map + ")";
150    }
151
152    private static final long serialVersionUID = 0;
153  }
154
155  /**
156   * Returns a function which performs a map lookup with a default value. The function created by
157   * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
158   * set. See also {@link #forMap(Map)}, which throws an exception in this case.
159   *
160   * <p><b>Java 8 users:</b> you can just write the lambda expression {@code k ->
161   * map.getWithDefault(k, defaultValue)} instead.
162   *
163   * @param map source map that determines the function behavior
164   * @param defaultValue the value to return for inputs that aren't map keys
165   * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
166   *     defaultValue} otherwise
167   */
168  public static <K, V> Function<K, V> forMap(
169      Map<K, ? extends V> map, @NullableDecl V defaultValue) {
170    return new ForMapWithDefault<>(map, defaultValue);
171  }
172
173  private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable {
174    final Map<K, ? extends V> map;
175    final V defaultValue;
176
177    ForMapWithDefault(Map<K, ? extends V> map, @NullableDecl V defaultValue) {
178      this.map = checkNotNull(map);
179      this.defaultValue = defaultValue;
180    }
181
182    @Override
183    public V apply(@NullableDecl K key) {
184      V result = map.get(key);
185      return (result != null || map.containsKey(key)) ? result : defaultValue;
186    }
187
188    @Override
189    public boolean equals(@NullableDecl Object o) {
190      if (o instanceof ForMapWithDefault) {
191        ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
192        return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
193      }
194      return false;
195    }
196
197    @Override
198    public int hashCode() {
199      return Objects.hashCode(map, defaultValue);
200    }
201
202    @Override
203    public String toString() {
204      // TODO(cpovirk): maybe remove "defaultValue=" to make this look like the method call does
205      return "Functions.forMap(" + map + ", defaultValue=" + defaultValue + ")";
206    }
207
208    private static final long serialVersionUID = 0;
209  }
210
211  /**
212   * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
213   * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
214   *
215   * <p><b>Java 8 users:</b> use {@code g.compose(f)} or (probably clearer) {@code f.andThen(g)}
216   * instead.
217   *
218   * @param g the second function to apply
219   * @param f the first function to apply
220   * @return the composition of {@code f} and {@code g}
221   * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
222   */
223  public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
224    return new FunctionComposition<>(g, f);
225  }
226
227  private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
228    private final Function<B, C> g;
229    private final Function<A, ? extends B> f;
230
231    public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
232      this.g = checkNotNull(g);
233      this.f = checkNotNull(f);
234    }
235
236    @Override
237    public C apply(@NullableDecl A a) {
238      return g.apply(f.apply(a));
239    }
240
241    @Override
242    public boolean equals(@NullableDecl Object obj) {
243      if (obj instanceof FunctionComposition) {
244        FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
245        return f.equals(that.f) && g.equals(that.g);
246      }
247      return false;
248    }
249
250    @Override
251    public int hashCode() {
252      return f.hashCode() ^ g.hashCode();
253    }
254
255    @Override
256    public String toString() {
257      // TODO(cpovirk): maybe make this look like the method call does ("Functions.compose(...)")
258      return g + "(" + f + ")";
259    }
260
261    private static final long serialVersionUID = 0;
262  }
263
264  /**
265   * Creates a function that returns the same boolean output as the given predicate for all inputs.
266   *
267   * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
268   * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
269   *
270   * <p><b>Java 8 users:</b> use the method reference {@code predicate::test} instead.
271   */
272  public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) {
273    return new PredicateFunction<T>(predicate);
274  }
275
276  /** @see Functions#forPredicate */
277  private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable {
278    private final Predicate<T> predicate;
279
280    private PredicateFunction(Predicate<T> predicate) {
281      this.predicate = checkNotNull(predicate);
282    }
283
284    @Override
285    public Boolean apply(@NullableDecl T t) {
286      return predicate.apply(t);
287    }
288
289    @Override
290    public boolean equals(@NullableDecl Object obj) {
291      if (obj instanceof PredicateFunction) {
292        PredicateFunction<?> that = (PredicateFunction<?>) obj;
293        return predicate.equals(that.predicate);
294      }
295      return false;
296    }
297
298    @Override
299    public int hashCode() {
300      return predicate.hashCode();
301    }
302
303    @Override
304    public String toString() {
305      return "Functions.forPredicate(" + predicate + ")";
306    }
307
308    private static final long serialVersionUID = 0;
309  }
310
311  /**
312   * Returns a function that ignores its input and always returns {@code value}.
313   *
314   * <p><b>Java 8 users:</b> use the lambda expression {@code o -> value} instead.
315   *
316   * @param value the constant value for the function to return
317   * @return a function that always returns {@code value}
318   */
319  public static <E> Function<Object, E> constant(@NullableDecl E value) {
320    return new ConstantFunction<E>(value);
321  }
322
323  private static class ConstantFunction<E> implements Function<Object, E>, Serializable {
324    private final E value;
325
326    public ConstantFunction(@NullableDecl E value) {
327      this.value = value;
328    }
329
330    @Override
331    public E apply(@NullableDecl Object from) {
332      return value;
333    }
334
335    @Override
336    public boolean equals(@NullableDecl Object obj) {
337      if (obj instanceof ConstantFunction) {
338        ConstantFunction<?> that = (ConstantFunction<?>) obj;
339        return Objects.equal(value, that.value);
340      }
341      return false;
342    }
343
344    @Override
345    public int hashCode() {
346      return (value == null) ? 0 : value.hashCode();
347    }
348
349    @Override
350    public String toString() {
351      return "Functions.constant(" + value + ")";
352    }
353
354    private static final long serialVersionUID = 0;
355  }
356
357  /**
358   * Returns a function that ignores its input and returns the result of {@code supplier.get()}.
359   *
360   * <p><b>Java 8 users:</b> use the lambda expression {@code o -> supplier.get()} instead.
361   *
362   * @since 10.0
363   */
364  public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) {
365    return new SupplierFunction<T>(supplier);
366  }
367
368  /** @see Functions#forSupplier */
369  private static class SupplierFunction<T> implements Function<Object, T>, Serializable {
370
371    private final Supplier<T> supplier;
372
373    private SupplierFunction(Supplier<T> supplier) {
374      this.supplier = checkNotNull(supplier);
375    }
376
377    @Override
378    public T apply(@NullableDecl Object input) {
379      return supplier.get();
380    }
381
382    @Override
383    public boolean equals(@NullableDecl Object obj) {
384      if (obj instanceof SupplierFunction) {
385        SupplierFunction<?> that = (SupplierFunction<?>) obj;
386        return this.supplier.equals(that.supplier);
387      }
388      return false;
389    }
390
391    @Override
392    public int hashCode() {
393      return supplier.hashCode();
394    }
395
396    @Override
397    public String toString() {
398      return "Functions.forSupplier(" + supplier + ")";
399    }
400
401    private static final long serialVersionUID = 0;
402  }
403}