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