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 }