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  @SuppressWarnings("unchecked")
078  public static <E> Function<E, E> identity() {
079    return (Function<E, E>) IdentityFunction.INSTANCE;
080  }
081
082  // enum singleton pattern
083  private enum IdentityFunction implements Function<Object, Object> {
084    INSTANCE;
085
086    @Override
087    @Nullable
088    public Object apply(@Nullable Object o) {
089      return o;
090    }
091
092    @Override public String toString() {
093      return "identity";
094    }
095  }
096
097  /**
098   * Returns a function which performs a map lookup. The returned function throws an {@link
099   * IllegalArgumentException} if given a key that does not exist in the map.
100   */
101  public static <K, V> Function<K, V> forMap(Map<K, V> map) {
102    return new FunctionForMapNoDefault<K, V>(map);
103  }
104
105  private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable {
106    final Map<K, V> map;
107
108    FunctionForMapNoDefault(Map<K, V> map) {
109      this.map = checkNotNull(map);
110    }
111
112    @Override
113    public V apply(@Nullable K key) {
114      V result = map.get(key);
115      checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
116      return result;
117    }
118
119    @Override public boolean equals(@Nullable Object o) {
120      if (o instanceof FunctionForMapNoDefault) {
121        FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
122        return map.equals(that.map);
123      }
124      return false;
125    }
126
127    @Override public int hashCode() {
128      return map.hashCode();
129    }
130
131    @Override public String toString() {
132      return "forMap(" + map + ")";
133    }
134
135    private static final long serialVersionUID = 0;
136  }
137
138  /**
139   * Returns a function which performs a map lookup with a default value. The function created by
140   * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
141   * set.
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, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) {
149    return new ForMapWithDefault<K, V>(map, defaultValue);
150  }
151
152  private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable {
153    final Map<K, ? extends V> map;
154    final V defaultValue;
155
156    ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) {
157      this.map = checkNotNull(map);
158      this.defaultValue = defaultValue;
159    }
160
161    @Override
162    public V apply(@Nullable K key) {
163      V result = map.get(key);
164      return (result != null || map.containsKey(key)) ? result : defaultValue;
165    }
166
167    @Override public boolean equals(@Nullable Object o) {
168      if (o instanceof ForMapWithDefault) {
169        ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
170        return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
171      }
172      return false;
173    }
174
175    @Override public int hashCode() {
176      return Objects.hashCode(map, defaultValue);
177    }
178
179    @Override public String toString() {
180      return "forMap(" + map + ", defaultValue=" + defaultValue + ")";
181    }
182
183    private static final long serialVersionUID = 0;
184  }
185
186  /**
187   * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
188   * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
189   *
190   * @param g the second function to apply
191   * @param f the first function to apply
192   * @return the composition of {@code f} and {@code g}
193   * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
194   */
195  public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
196    return new FunctionComposition<A, B, C>(g, f);
197  }
198
199  private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
200    private final Function<B, C> g;
201    private final Function<A, ? extends B> f;
202
203    public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
204      this.g = checkNotNull(g);
205      this.f = checkNotNull(f);
206    }
207
208    @Override
209    public C apply(@Nullable A a) {
210      return g.apply(f.apply(a));
211    }
212
213    @Override public boolean equals(@Nullable Object obj) {
214      if (obj instanceof FunctionComposition) {
215        FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
216        return f.equals(that.f) && g.equals(that.g);
217      }
218      return false;
219    }
220
221    @Override public int hashCode() {
222      return f.hashCode() ^ g.hashCode();
223    }
224
225    @Override public String toString() {
226      return g.toString() + "(" + f.toString() + ")";
227    }
228
229    private static final long serialVersionUID = 0;
230  }
231
232  /**
233   * Creates a function that returns the same boolean output as the given predicate for all inputs.
234   *
235   * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
236   * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
237   */
238  public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) {
239    return new PredicateFunction<T>(predicate);
240  }
241
242  /** @see Functions#forPredicate */
243  private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable {
244    private final Predicate<T> predicate;
245
246    private PredicateFunction(Predicate<T> predicate) {
247      this.predicate = checkNotNull(predicate);
248    }
249
250    @Override
251    public Boolean apply(@Nullable T t) {
252      return predicate.apply(t);
253    }
254
255    @Override public boolean equals(@Nullable Object obj) {
256      if (obj instanceof PredicateFunction) {
257        PredicateFunction<?> that = (PredicateFunction<?>) obj;
258        return predicate.equals(that.predicate);
259      }
260      return false;
261    }
262
263    @Override public int hashCode() {
264      return predicate.hashCode();
265    }
266
267    @Override public String toString() {
268      return "forPredicate(" + predicate + ")";
269    }
270
271    private static final long serialVersionUID = 0;
272  }
273
274  /**
275   * Creates a function that returns {@code value} for any input.
276   *
277   * @param value the constant value for the function to return
278   * @return a function that always returns {@code value}
279   */
280  public static <E> Function<Object, E> constant(@Nullable E value) {
281    return new ConstantFunction<E>(value);
282  }
283
284  private static class ConstantFunction<E> implements Function<Object, E>, Serializable {
285    private final E value;
286
287    public ConstantFunction(@Nullable E value) {
288      this.value = value;
289    }
290
291    @Override
292    public E apply(@Nullable Object from) {
293      return value;
294    }
295
296    @Override public boolean equals(@Nullable Object obj) {
297      if (obj instanceof ConstantFunction) {
298        ConstantFunction<?> that = (ConstantFunction<?>) obj;
299        return Objects.equal(value, that.value);
300      }
301      return false;
302    }
303
304    @Override public int hashCode() {
305      return (value == null) ? 0 : value.hashCode();
306    }
307
308    @Override public String toString() {
309      return "constant(" + value + ")";
310    }
311
312    private static final long serialVersionUID = 0;
313  }
314
315  /**
316   * Returns a function that always returns the result of invoking {@link Supplier#get} on {@code
317   * supplier}, regardless of its input.
318   * 
319   * @since 10.0
320   */
321  @Beta
322  public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) {
323    return new SupplierFunction<T>(supplier);
324  }
325
326  /** @see Functions#forSupplier*/
327  private static class SupplierFunction<T> implements Function<Object, T>, Serializable {
328    
329    private final Supplier<T> supplier;
330
331    private SupplierFunction(Supplier<T> supplier) {
332      this.supplier = checkNotNull(supplier);
333    }
334
335    @Override public T apply(@Nullable Object input) {
336      return supplier.get();
337    }
338    
339    @Override public boolean equals(@Nullable Object obj) {
340      if (obj instanceof SupplierFunction) {
341        SupplierFunction<?> that = (SupplierFunction<?>) obj;
342        return this.supplier.equals(that.supplier);
343      }
344      return false;
345    }
346    
347    @Override public int hashCode() {
348      return supplier.hashCode();
349    }
350    
351    @Override public String toString() {
352      return "forSupplier(" + supplier + ")";
353    }
354    
355    private static final long serialVersionUID = 0;
356  }
357}