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