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