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