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