001/*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.base;
018
019import static com.google.common.base.Preconditions.checkArgument;
020import static com.google.common.base.Preconditions.checkNotNull;
021
022import com.google.common.annotations.Beta;
023import com.google.common.annotations.GwtCompatible;
024
025import java.io.Serializable;
026import java.util.Map;
027
028import javax.annotation.Nullable;
029
030/**
031 * Static utility methods pertaining to {@code Function} instances.
032 *
033 * <p>All methods return serializable functions as long as they're given serializable parameters.
034 * 
035 * <p>See the Guava User Guide article on <a href=
036 * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the use of {@code
037 * Function}</a>.
038 *
039 * @author Mike Bostock
040 * @author Jared Levy
041 * @since 2.0 (imported from Google Collections Library)
042 */
043@GwtCompatible
044public final class Functions {
045  private Functions() {}
046
047  /**
048   * Returns a function that calls {@code toString()} on its argument. The function does not accept
049   * nulls; it will throw a {@link NullPointerException} when applied to {@code null}.
050   *
051   * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
052   * documented at {@link Function#apply}). For example, this function yields different results for
053   * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
054   */
055  public static Function<Object, String> toStringFunction() {
056    return ToStringFunction.INSTANCE;
057  }
058
059  // enum singleton pattern
060  private enum ToStringFunction implements Function<Object, String> {
061    INSTANCE;
062
063    @Override
064    public String apply(Object o) {
065      checkNotNull(o);  // eager for GWT.
066      return o.toString();
067    }
068
069    @Override public String toString() {
070      return "toString";
071    }
072  }
073
074  /**
075   * Returns the identity function.
076   */
077  // implementation is "fully variant"; E has become a "pass-through" type
078  @SuppressWarnings("unchecked")
079  public static <E> Function<E, E> identity() {
080    return (Function<E, E>) IdentityFunction.INSTANCE;
081  }
082
083  // enum singleton pattern
084  private enum IdentityFunction implements Function<Object, Object> {
085    INSTANCE;
086
087    @Override
088    @Nullable
089    public Object apply(@Nullable Object o) {
090      return o;
091    }
092
093    @Override public String toString() {
094      return "identity";
095    }
096  }
097
098  /**
099   * Returns a function which performs a map lookup. The returned function throws an {@link
100   * IllegalArgumentException} if given a key that does not exist in the map.
101   */
102  public static <K, V> Function<K, V> forMap(Map<K, V> map) {
103    return new FunctionForMapNoDefault<K, V>(map);
104  }
105
106  private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable {
107    final Map<K, V> map;
108
109    FunctionForMapNoDefault(Map<K, V> map) {
110      this.map = checkNotNull(map);
111    }
112
113    @Override
114    public V apply(@Nullable K key) {
115      V result = map.get(key);
116      checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
117      return result;
118    }
119
120    @Override public boolean equals(@Nullable Object o) {
121      if (o instanceof FunctionForMapNoDefault) {
122        FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
123        return map.equals(that.map);
124      }
125      return false;
126    }
127
128    @Override public int hashCode() {
129      return map.hashCode();
130    }
131
132    @Override public String toString() {
133      return "forMap(" + map + ")";
134    }
135
136    private static final long serialVersionUID = 0;
137  }
138
139  /**
140   * Returns a function which performs a map lookup with a default value. The function created by
141   * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
142   * set.
143   *
144   * @param map source map that determines the function behavior
145   * @param defaultValue the value to return for inputs that aren't map keys
146   * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
147   *         defaultValue} otherwise
148   */
149  public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) {
150    return new ForMapWithDefault<K, V>(map, defaultValue);
151  }
152
153  private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable {
154    final Map<K, ? extends V> map;
155    final V defaultValue;
156
157    ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) {
158      this.map = checkNotNull(map);
159      this.defaultValue = defaultValue;
160    }
161
162    @Override
163    public V apply(@Nullable K key) {
164      V result = map.get(key);
165      return (result != null || map.containsKey(key)) ? result : defaultValue;
166    }
167
168    @Override public boolean equals(@Nullable Object o) {
169      if (o instanceof ForMapWithDefault) {
170        ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
171        return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
172      }
173      return false;
174    }
175
176    @Override public int hashCode() {
177      return Objects.hashCode(map, defaultValue);
178    }
179
180    @Override public String toString() {
181      return "forMap(" + map + ", defaultValue=" + defaultValue + ")";
182    }
183
184    private static final long serialVersionUID = 0;
185  }
186
187  /**
188   * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
189   * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
190   *
191   * @param g the second function to apply
192   * @param f the first function to apply
193   * @return the composition of {@code f} and {@code g}
194   * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
195   */
196  public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
197    return new FunctionComposition<A, B, C>(g, f);
198  }
199
200  private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
201    private final Function<B, C> g;
202    private final Function<A, ? extends B> f;
203
204    public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
205      this.g = checkNotNull(g);
206      this.f = checkNotNull(f);
207    }
208
209    @Override
210    public C apply(@Nullable A a) {
211      return g.apply(f.apply(a));
212    }
213
214    @Override public boolean equals(@Nullable Object obj) {
215      if (obj instanceof FunctionComposition) {
216        FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
217        return f.equals(that.f) && g.equals(that.g);
218      }
219      return false;
220    }
221
222    @Override public int hashCode() {
223      return f.hashCode() ^ g.hashCode();
224    }
225
226    @Override public String toString() {
227      return g.toString() + "(" + f.toString() + ")";
228    }
229
230    private static final long serialVersionUID = 0;
231  }
232
233  /**
234   * Creates a function that returns the same boolean output as the given predicate for all inputs.
235   *
236   * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
237   * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
238   */
239  public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) {
240    return new PredicateFunction<T>(predicate);
241  }
242
243  /** @see Functions#forPredicate */
244  private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable {
245    private final Predicate<T> predicate;
246
247    private PredicateFunction(Predicate<T> predicate) {
248      this.predicate = checkNotNull(predicate);
249    }
250
251    @Override
252    public Boolean apply(@Nullable T t) {
253      return predicate.apply(t);
254    }
255
256    @Override public boolean equals(@Nullable Object obj) {
257      if (obj instanceof PredicateFunction) {
258        PredicateFunction<?> that = (PredicateFunction<?>) obj;
259        return predicate.equals(that.predicate);
260      }
261      return false;
262    }
263
264    @Override public int hashCode() {
265      return predicate.hashCode();
266    }
267
268    @Override public String toString() {
269      return "forPredicate(" + predicate + ")";
270    }
271
272    private static final long serialVersionUID = 0;
273  }
274
275  /**
276   * Creates a function that returns {@code value} for any input.
277   *
278   * @param value the constant value for the function to return
279   * @return a function that always returns {@code value}
280   */
281  public static <E> Function<Object, E> constant(@Nullable E value) {
282    return new ConstantFunction<E>(value);
283  }
284
285  private static class ConstantFunction<E> implements Function<Object, E>, Serializable {
286    private final E value;
287
288    public ConstantFunction(@Nullable E value) {
289      this.value = value;
290    }
291
292    @Override
293    public E apply(@Nullable Object from) {
294      return value;
295    }
296
297    @Override public boolean equals(@Nullable Object obj) {
298      if (obj instanceof ConstantFunction) {
299        ConstantFunction<?> that = (ConstantFunction<?>) obj;
300        return Objects.equal(value, that.value);
301      }
302      return false;
303    }
304
305    @Override public int hashCode() {
306      return (value == null) ? 0 : value.hashCode();
307    }
308
309    @Override public String toString() {
310      return "constant(" + value + ")";
311    }
312
313    private static final long serialVersionUID = 0;
314  }
315
316  /**
317   * Returns a function that always returns the result of invoking {@link Supplier#get} on {@code
318   * supplier}, regardless of its input.
319   * 
320   * @since 10.0
321   */
322  @Beta
323  public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) {
324    return new SupplierFunction<T>(supplier);
325  }
326
327  /** @see Functions#forSupplier*/
328  private static class SupplierFunction<T> implements Function<Object, T>, Serializable {
329    
330    private final Supplier<T> supplier;
331
332    private SupplierFunction(Supplier<T> supplier) {
333      this.supplier = checkNotNull(supplier);
334    }
335
336    @Override public T apply(@Nullable Object input) {
337      return supplier.get();
338    }
339    
340    @Override public boolean equals(@Nullable Object obj) {
341      if (obj instanceof SupplierFunction) {
342        SupplierFunction<?> that = (SupplierFunction<?>) obj;
343        return this.supplier.equals(that.supplier);
344      }
345      return false;
346    }
347    
348    @Override public int hashCode() {
349      return supplier.hashCode();
350    }
351    
352    @Override public String toString() {
353      return "forSupplier(" + supplier + ")";
354    }
355    
356    private static final long serialVersionUID = 0;
357  }
358}