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 }