001    /*
002     * Copyright (C) 2007 Google Inc.
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    
015    package com.google.common.base;
016    
017    import static com.google.common.base.Preconditions.checkArgument;
018    import static com.google.common.base.Preconditions.checkNotNull;
019    
020    import com.google.common.annotations.GwtCompatible;
021    
022    import java.io.Serializable;
023    import java.util.Map;
024    
025    import javax.annotation.Nullable;
026    
027    /**
028     * Static utility methods pertaining to {@code Function} instances.
029     *
030     * <p>All methods returns serializable functions as long as they're given serializable parameters.
031     *
032     * @author Mike Bostock
033     * @author Jared Levy
034     * @since 2 (imported from Google Collections Library)
035     */
036    @GwtCompatible
037    public final class Functions {
038      private Functions() {}
039    
040      /**
041       * Returns a function that calls {@code toString()} on its argument. The function does not accept
042       * nulls; it will throw a {@link NullPointerException} when applied to {@code null}.
043       *
044       * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
045       * documented at {@link Function#apply}). For example, this function yields different results for
046       * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
047       */
048      public static Function<Object, String> toStringFunction() {
049        return ToStringFunction.INSTANCE;
050      }
051    
052      // enum singleton pattern
053      private enum ToStringFunction implements Function<Object, String> {
054        INSTANCE;
055    
056        public String apply(Object o) {
057          checkNotNull(o);  // eager for GWT.
058          return o.toString();
059        }
060    
061        @Override public String toString() {
062          return "toString";
063        }
064      }
065    
066      /**
067       * Returns the identity function.
068       */
069      @SuppressWarnings("unchecked")
070      public static <E> Function<E, E> identity() {
071        return (Function<E, E>) IdentityFunction.INSTANCE;
072      }
073    
074      // enum singleton pattern
075      private enum IdentityFunction implements Function<Object, Object> {
076        INSTANCE;
077    
078        public Object apply(Object o) {
079          return o;
080        }
081    
082        @Override public String toString() {
083          return "identity";
084        }
085      }
086    
087      /**
088       * Returns a function which performs a map lookup. The returned function throws an {@link
089       * IllegalArgumentException} if given a key that does not exist in the map.
090       */
091      public static <K, V> Function<K, V> forMap(Map<K, V> map) {
092        return new FunctionForMapNoDefault<K, V>(map);
093      }
094    
095      private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable {
096        final Map<K, V> map;
097    
098        FunctionForMapNoDefault(Map<K, V> map) {
099          this.map = checkNotNull(map);
100        }
101    
102        public V apply(K key) {
103          V result = map.get(key);
104          checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
105          return result;
106        }
107    
108        @Override public boolean equals(@Nullable Object o) {
109          if (o instanceof FunctionForMapNoDefault) {
110            FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
111            return map.equals(that.map);
112          }
113          return false;
114        }
115    
116        @Override public int hashCode() {
117          return map.hashCode();
118        }
119    
120        @Override public String toString() {
121          return "forMap(" + map + ")";
122        }
123    
124        private static final long serialVersionUID = 0;
125      }
126    
127      /**
128       * Returns a function which performs a map lookup with a default value. The function created by
129       * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
130       * set.
131       *
132       * @param map source map that determines the function behavior
133       * @param defaultValue the value to return for inputs that aren't map keys
134       * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
135       *         defaultValue} otherwise
136       */
137      public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) {
138        return new ForMapWithDefault<K, V>(map, defaultValue);
139      }
140    
141      private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable {
142        final Map<K, ? extends V> map;
143        final V defaultValue;
144    
145        ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) {
146          this.map = checkNotNull(map);
147          this.defaultValue = defaultValue;
148        }
149    
150        public V apply(K key) {
151          V result = map.get(key);
152          return (result != null || map.containsKey(key)) ? result : defaultValue;
153        }
154    
155        @Override public boolean equals(@Nullable Object o) {
156          if (o instanceof ForMapWithDefault) {
157            ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
158            return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
159          }
160          return false;
161        }
162    
163        @Override public int hashCode() {
164          return Objects.hashCode(map, defaultValue);
165        }
166    
167        @Override public String toString() {
168          return "forMap(" + map + ", defaultValue=" + defaultValue + ")";
169        }
170    
171        private static final long serialVersionUID = 0;
172      }
173    
174      /**
175       * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
176       * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
177       *
178       * @param g the second function to apply
179       * @param f the first function to apply
180       * @return the composition of {@code f} and {@code g}
181       * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
182       */
183      public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
184        return new FunctionComposition<A, B, C>(g, f);
185      }
186    
187      private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
188        private final Function<B, C> g;
189        private final Function<A, ? extends B> f;
190    
191        public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
192          this.g = checkNotNull(g);
193          this.f = checkNotNull(f);
194        }
195    
196        public C apply(A a) {
197          return g.apply(f.apply(a));
198        }
199    
200        @Override public boolean equals(@Nullable Object obj) {
201          if (obj instanceof FunctionComposition) {
202            FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
203            return f.equals(that.f) && g.equals(that.g);
204          }
205          return false;
206        }
207    
208        @Override public int hashCode() {
209          return f.hashCode() ^ g.hashCode();
210        }
211    
212        @Override public String toString() {
213          return g.toString() + "(" + f.toString() + ")";
214        }
215    
216        private static final long serialVersionUID = 0;
217      }
218    
219      /**
220       * Creates a function that returns the same boolean output as the given predicate for all inputs.
221       *
222       * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
223       * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
224       */
225      public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) {
226        return new PredicateFunction<T>(predicate);
227      }
228    
229      /** @see Functions#forPredicate */
230      private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable {
231        private final Predicate<T> predicate;
232    
233        private PredicateFunction(Predicate<T> predicate) {
234          this.predicate = checkNotNull(predicate);
235        }
236    
237        public Boolean apply(T t) {
238          return predicate.apply(t);
239        }
240    
241        @Override public boolean equals(@Nullable Object obj) {
242          if (obj instanceof PredicateFunction) {
243            PredicateFunction<?> that = (PredicateFunction<?>) obj;
244            return predicate.equals(that.predicate);
245          }
246          return false;
247        }
248    
249        @Override public int hashCode() {
250          return predicate.hashCode();
251        }
252    
253        @Override public String toString() {
254          return "forPredicate(" + predicate + ")";
255        }
256    
257        private static final long serialVersionUID = 0;
258      }
259    
260      /**
261       * Creates a function that returns {@code value} for any input.
262       *
263       * @param value the constant value for the function to return
264       * @return a function that always returns {@code value}
265       */
266      public static <E> Function<Object, E> constant(@Nullable E value) {
267        return new ConstantFunction<E>(value);
268      }
269    
270      private static class ConstantFunction<E> implements Function<Object, E>, Serializable {
271        private final E value;
272    
273        public ConstantFunction(@Nullable E value) {
274          this.value = value;
275        }
276    
277        public E apply(@Nullable Object from) {
278          return value;
279        }
280    
281        @Override public boolean equals(@Nullable Object obj) {
282          if (obj instanceof ConstantFunction) {
283            ConstantFunction<?> that = (ConstantFunction<?>) obj;
284            return Objects.equal(value, that.value);
285          }
286          return false;
287        }
288    
289        @Override public int hashCode() {
290          return (value == null) ? 0 : value.hashCode();
291        }
292    
293        @Override public String toString() {
294          return "constant(" + value + ")";
295        }
296    
297        private static final long serialVersionUID = 0;
298      }
299    }