001/* 002 * Copyright (C) 2007 The Guava Authors 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 015package com.google.common.base; 016 017import static com.google.common.base.Preconditions.checkArgument; 018import static com.google.common.base.Preconditions.checkNotNull; 019 020import com.google.common.annotations.GwtCompatible; 021import java.io.Serializable; 022import java.util.Map; 023import javax.annotation.Nullable; 024 025/** 026 * Static utility methods pertaining to {@code com.google.common.base.Function} instances; see that 027 * class for information about migrating to {@code java.util.function}. 028 * 029 * <p>All methods return serializable functions as long as they're given serializable parameters. 030 * 031 * <p>See the Guava User Guide article on 032 * <a href="https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code 033 * Function}</a>. 034 * 035 * @author Mike Bostock 036 * @author Jared Levy 037 * @since 2.0 038 */ 039@GwtCompatible 040public final class Functions { 041 private Functions() {} 042 043 /** 044 * A function equivalent to the method reference {@code Object::toString}, for users not yet using 045 * Java 8. The function simply invokes {@code toString} on its argument and returns the result. It 046 * throws a {@link NullPointerException} on null input. 047 * 048 * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as 049 * documented at {@link Function#apply}). For example, this function yields different results for 050 * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}. 051 * 052 * <p><b>Warning:</b> as with all function types in this package, avoid depending on the specific 053 * {@code equals}, {@code hashCode} or {@code toString} behavior of the returned function. A 054 * future migration to {@code java.util.function} will not preserve this behavior. 055 * 056 * <p><b>For Java 8 users:</b> use the method reference {@code Object::toString} instead. In the 057 * future, when this class requires Java 8, this method will be deprecated. See {@link Function} 058 * for more important information about the Java 8 transition. 059 */ 060 public static Function<Object, String> toStringFunction() { 061 return ToStringFunction.INSTANCE; 062 } 063 064 // enum singleton pattern 065 private enum ToStringFunction implements Function<Object, String> { 066 INSTANCE; 067 068 @Override 069 public String apply(Object o) { 070 checkNotNull(o); // eager for GWT. 071 return o.toString(); 072 } 073 074 @Override 075 public String toString() { 076 return "Functions.toStringFunction()"; 077 } 078 } 079 080 /** 081 * Returns the identity function. 082 */ 083 // implementation is "fully variant"; E has become a "pass-through" type 084 @SuppressWarnings("unchecked") 085 public static <E> Function<E, E> identity() { 086 return (Function<E, E>) IdentityFunction.INSTANCE; 087 } 088 089 // enum singleton pattern 090 private enum IdentityFunction implements Function<Object, Object> { 091 INSTANCE; 092 093 @Override 094 @Nullable 095 public Object apply(@Nullable Object o) { 096 return o; 097 } 098 099 @Override 100 public String toString() { 101 return "Functions.identity()"; 102 } 103 } 104 105 /** 106 * Returns a function which performs a map lookup. The returned function throws an 107 * {@link IllegalArgumentException} if given a key that does not exist in the map. See also 108 * {@link #forMap(Map, Object)}, which returns a default value in this case. 109 * 110 * <p>Note: if {@code map} is a {@link com.google.common.collect.BiMap BiMap} (or can be one), you 111 * can use {@link com.google.common.collect.Maps#asConverter Maps.asConverter} instead to get a 112 * function that also supports reverse conversion. 113 * 114 * <p><b>Java 8 users:</b> if you are okay with {@code null} being returned for an unrecognized 115 * key (instead of an exception being thrown), you can use the method reference {@code map::get} 116 * instead. 117 */ 118 public static <K, V> Function<K, V> forMap(Map<K, V> map) { 119 return new FunctionForMapNoDefault<K, V>(map); 120 } 121 122 private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable { 123 final Map<K, V> map; 124 125 FunctionForMapNoDefault(Map<K, V> map) { 126 this.map = checkNotNull(map); 127 } 128 129 @Override 130 public V apply(@Nullable K key) { 131 V result = map.get(key); 132 checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key); 133 return result; 134 } 135 136 @Override 137 public boolean equals(@Nullable Object o) { 138 if (o instanceof FunctionForMapNoDefault) { 139 FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o; 140 return map.equals(that.map); 141 } 142 return false; 143 } 144 145 @Override 146 public int hashCode() { 147 return map.hashCode(); 148 } 149 150 @Override 151 public String toString() { 152 return "Functions.forMap(" + map + ")"; 153 } 154 155 private static final long serialVersionUID = 0; 156 } 157 158 /** 159 * Returns a function which performs a map lookup with a default value. The function created by 160 * this method returns {@code defaultValue} for all inputs that do not belong to the map's key 161 * set. See also {@link #forMap(Map)}, which throws an exception in this case. 162 * 163 * <p><b>Java 8 users:</b> you can just write the lambda expression {@code k -> 164 * map.getWithDefault(k, defaultValue)} instead. 165 * 166 * @param map source map that determines the function behavior 167 * @param defaultValue the value to return for inputs that aren't map keys 168 * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code 169 * defaultValue} otherwise 170 */ 171 public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) { 172 return new ForMapWithDefault<K, V>(map, defaultValue); 173 } 174 175 private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable { 176 final Map<K, ? extends V> map; 177 final V defaultValue; 178 179 ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) { 180 this.map = checkNotNull(map); 181 this.defaultValue = defaultValue; 182 } 183 184 @Override 185 public V apply(@Nullable K key) { 186 V result = map.get(key); 187 return (result != null || map.containsKey(key)) ? result : defaultValue; 188 } 189 190 @Override 191 public boolean equals(@Nullable Object o) { 192 if (o instanceof ForMapWithDefault) { 193 ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o; 194 return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue); 195 } 196 return false; 197 } 198 199 @Override 200 public int hashCode() { 201 return Objects.hashCode(map, defaultValue); 202 } 203 204 @Override 205 public String toString() { 206 // TODO(cpovirk): maybe remove "defaultValue=" to make this look like the method call does 207 return "Functions.forMap(" + map + ", defaultValue=" + defaultValue + ")"; 208 } 209 210 private static final long serialVersionUID = 0; 211 } 212 213 /** 214 * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition 215 * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}. 216 * 217 * <p><b>Java 8 users:</b> use {@code g.compose(f)} or (probably clearer) {@code f.andThen(g)} 218 * instead. 219 * 220 * @param g the second function to apply 221 * @param f the first function to apply 222 * @return the composition of {@code f} and {@code g} 223 * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a> 224 */ 225 public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) { 226 return new FunctionComposition<A, B, C>(g, f); 227 } 228 229 private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable { 230 private final Function<B, C> g; 231 private final Function<A, ? extends B> f; 232 233 public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) { 234 this.g = checkNotNull(g); 235 this.f = checkNotNull(f); 236 } 237 238 @Override 239 public C apply(@Nullable A a) { 240 return g.apply(f.apply(a)); 241 } 242 243 @Override 244 public boolean equals(@Nullable Object obj) { 245 if (obj instanceof FunctionComposition) { 246 FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj; 247 return f.equals(that.f) && g.equals(that.g); 248 } 249 return false; 250 } 251 252 @Override 253 public int hashCode() { 254 return f.hashCode() ^ g.hashCode(); 255 } 256 257 @Override 258 public String toString() { 259 // TODO(cpovirk): maybe make this look like the method call does ("Functions.compose(...)") 260 return g + "(" + f + ")"; 261 } 262 263 private static final long serialVersionUID = 0; 264 } 265 266 /** 267 * Creates a function that returns the same boolean output as the given predicate for all inputs. 268 * 269 * <p>The returned function is <i>consistent with equals</i> (as documented at 270 * {@link Function#apply}) if and only if {@code predicate} is itself consistent with equals. 271 * 272 * <p><b>Java 8 users:</b> use the method reference {@code predicate::test} instead. 273 */ 274 public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) { 275 return new PredicateFunction<T>(predicate); 276 } 277 278 /** @see Functions#forPredicate */ 279 private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable { 280 private final Predicate<T> predicate; 281 282 private PredicateFunction(Predicate<T> predicate) { 283 this.predicate = checkNotNull(predicate); 284 } 285 286 @Override 287 public Boolean apply(@Nullable T t) { 288 return predicate.apply(t); 289 } 290 291 @Override 292 public boolean equals(@Nullable Object obj) { 293 if (obj instanceof PredicateFunction) { 294 PredicateFunction<?> that = (PredicateFunction<?>) obj; 295 return predicate.equals(that.predicate); 296 } 297 return false; 298 } 299 300 @Override 301 public int hashCode() { 302 return predicate.hashCode(); 303 } 304 305 @Override 306 public String toString() { 307 return "Functions.forPredicate(" + predicate + ")"; 308 } 309 310 private static final long serialVersionUID = 0; 311 } 312 313 /** 314 * Returns a function that ignores its input and always returns {@code value}. 315 * 316 * <p><b>Java 8 users:</b> use the lambda expression {@code o -> value} instead. 317 * 318 * @param value the constant value for the function to return 319 * @return a function that always returns {@code value} 320 */ 321 public static <E> Function<Object, E> constant(@Nullable E value) { 322 return new ConstantFunction<E>(value); 323 } 324 325 private static class ConstantFunction<E> implements Function<Object, E>, Serializable { 326 private final E value; 327 328 public ConstantFunction(@Nullable E value) { 329 this.value = value; 330 } 331 332 @Override 333 public E apply(@Nullable Object from) { 334 return value; 335 } 336 337 @Override 338 public boolean equals(@Nullable Object obj) { 339 if (obj instanceof ConstantFunction) { 340 ConstantFunction<?> that = (ConstantFunction<?>) obj; 341 return Objects.equal(value, that.value); 342 } 343 return false; 344 } 345 346 @Override 347 public int hashCode() { 348 return (value == null) ? 0 : value.hashCode(); 349 } 350 351 @Override 352 public String toString() { 353 return "Functions.constant(" + value + ")"; 354 } 355 356 private static final long serialVersionUID = 0; 357 } 358 359 /** 360 * Returns a function that ignores its input and returns the result of {@code supplier.get()}. 361 * 362 * <p><b>Java 8 users:</b> use the lambda expression {@code o -> supplier.get()} instead. 363 * 364 * @since 10.0 365 */ 366 public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) { 367 return new SupplierFunction<T>(supplier); 368 } 369 370 /** @see Functions#forSupplier */ 371 private static class SupplierFunction<T> implements Function<Object, T>, Serializable { 372 373 private final Supplier<T> supplier; 374 375 private SupplierFunction(Supplier<T> supplier) { 376 this.supplier = checkNotNull(supplier); 377 } 378 379 @Override 380 public T apply(@Nullable Object input) { 381 return supplier.get(); 382 } 383 384 @Override 385 public boolean equals(@Nullable Object obj) { 386 if (obj instanceof SupplierFunction) { 387 SupplierFunction<?> that = (SupplierFunction<?>) obj; 388 return this.supplier.equals(that.supplier); 389 } 390 return false; 391 } 392 393 @Override 394 public int hashCode() { 395 return supplier.hashCode(); 396 } 397 398 @Override 399 public String toString() { 400 return "Functions.forSupplier(" + supplier + ")"; 401 } 402 403 private static final long serialVersionUID = 0; 404 } 405}