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