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.compatqual.NullableDecl; 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 @NullableDecl 092 public Object apply(@NullableDecl Object o) { 093 return o; 094 } 095 096 @Override 097 public String toString() { 098 return "Functions.identity()"; 099 } 100 } 101 102 /** 103 * Returns a function which performs a map lookup. The returned function throws an {@link 104 * IllegalArgumentException} if given a key that does not exist in the map. See also {@link 105 * #forMap(Map, Object)}, which returns a default value in this case. 106 * 107 * <p>Note: if {@code map} is a {@link com.google.common.collect.BiMap BiMap} (or can be one), you 108 * can use {@link com.google.common.collect.Maps#asConverter Maps.asConverter} instead to get a 109 * function that also supports reverse conversion. 110 * 111 * <p><b>Java 8 users:</b> if you are okay with {@code null} being returned for an unrecognized 112 * key (instead of an exception being thrown), you can use the method reference {@code map::get} 113 * instead. 114 */ 115 public static <K, V> Function<K, V> forMap(Map<K, V> map) { 116 return new FunctionForMapNoDefault<>(map); 117 } 118 119 /** 120 * Returns a function which performs a map lookup with a default value. The function created by 121 * this method returns {@code defaultValue} for all inputs that do not belong to the map's key 122 * set. See also {@link #forMap(Map)}, which throws an exception in this case. 123 * 124 * <p><b>Java 8 users:</b> you can just write the lambda expression {@code k -> 125 * map.getOrDefault(k, defaultValue)} instead. 126 * 127 * @param map source map that determines the function behavior 128 * @param defaultValue the value to return for inputs that aren't map keys 129 * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code 130 * defaultValue} otherwise 131 */ 132 public static <K, V> Function<K, V> forMap( 133 Map<K, ? extends V> map, @NullableDecl V defaultValue) { 134 return new ForMapWithDefault<>(map, defaultValue); 135 } 136 137 private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable { 138 final Map<K, V> map; 139 140 FunctionForMapNoDefault(Map<K, V> map) { 141 this.map = checkNotNull(map); 142 } 143 144 @Override 145 public V apply(@NullableDecl K key) { 146 V result = map.get(key); 147 checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key); 148 return result; 149 } 150 151 @Override 152 public boolean equals(@NullableDecl Object o) { 153 if (o instanceof FunctionForMapNoDefault) { 154 FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o; 155 return map.equals(that.map); 156 } 157 return false; 158 } 159 160 @Override 161 public int hashCode() { 162 return map.hashCode(); 163 } 164 165 @Override 166 public String toString() { 167 return "Functions.forMap(" + map + ")"; 168 } 169 170 private static final long serialVersionUID = 0; 171 } 172 173 private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable { 174 final Map<K, ? extends V> map; 175 @NullableDecl final V defaultValue; 176 177 ForMapWithDefault(Map<K, ? extends V> map, @NullableDecl V defaultValue) { 178 this.map = checkNotNull(map); 179 this.defaultValue = defaultValue; 180 } 181 182 @Override 183 public V apply(@NullableDecl K key) { 184 V result = map.get(key); 185 return (result != null || map.containsKey(key)) ? result : defaultValue; 186 } 187 188 @Override 189 public boolean equals(@NullableDecl Object o) { 190 if (o instanceof ForMapWithDefault) { 191 ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o; 192 return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue); 193 } 194 return false; 195 } 196 197 @Override 198 public int hashCode() { 199 return Objects.hashCode(map, defaultValue); 200 } 201 202 @Override 203 public String toString() { 204 // TODO(cpovirk): maybe remove "defaultValue=" to make this look like the method call does 205 return "Functions.forMap(" + map + ", defaultValue=" + defaultValue + ")"; 206 } 207 208 private static final long serialVersionUID = 0; 209 } 210 211 /** 212 * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition 213 * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}. 214 * 215 * <p><b>Java 8 users:</b> use {@code g.compose(f)} or (probably clearer) {@code f.andThen(g)} 216 * instead. 217 * 218 * @param g the second function to apply 219 * @param f the first function to apply 220 * @return the composition of {@code f} and {@code g} 221 * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a> 222 */ 223 public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) { 224 return new FunctionComposition<>(g, f); 225 } 226 227 private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable { 228 private final Function<B, C> g; 229 private final Function<A, ? extends B> f; 230 231 public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) { 232 this.g = checkNotNull(g); 233 this.f = checkNotNull(f); 234 } 235 236 @Override 237 public C apply(@NullableDecl A a) { 238 return g.apply(f.apply(a)); 239 } 240 241 @Override 242 public boolean equals(@NullableDecl Object obj) { 243 if (obj instanceof FunctionComposition) { 244 FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj; 245 return f.equals(that.f) && g.equals(that.g); 246 } 247 return false; 248 } 249 250 @Override 251 public int hashCode() { 252 return f.hashCode() ^ g.hashCode(); 253 } 254 255 @Override 256 public String toString() { 257 // TODO(cpovirk): maybe make this look like the method call does ("Functions.compose(...)") 258 return g + "(" + f + ")"; 259 } 260 261 private static final long serialVersionUID = 0; 262 } 263 264 /** 265 * Creates a function that returns the same boolean output as the given predicate for all inputs. 266 * 267 * <p>The returned function is <i>consistent with equals</i> (as documented at {@link 268 * Function#apply}) if and only if {@code predicate} is itself consistent with equals. 269 * 270 * <p><b>Java 8 users:</b> use the method reference {@code predicate::test} instead. 271 */ 272 public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) { 273 return new PredicateFunction<T>(predicate); 274 } 275 276 /** @see Functions#forPredicate */ 277 private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable { 278 private final Predicate<T> predicate; 279 280 private PredicateFunction(Predicate<T> predicate) { 281 this.predicate = checkNotNull(predicate); 282 } 283 284 @Override 285 public Boolean apply(@NullableDecl T t) { 286 return predicate.apply(t); 287 } 288 289 @Override 290 public boolean equals(@NullableDecl Object obj) { 291 if (obj instanceof PredicateFunction) { 292 PredicateFunction<?> that = (PredicateFunction<?>) obj; 293 return predicate.equals(that.predicate); 294 } 295 return false; 296 } 297 298 @Override 299 public int hashCode() { 300 return predicate.hashCode(); 301 } 302 303 @Override 304 public String toString() { 305 return "Functions.forPredicate(" + predicate + ")"; 306 } 307 308 private static final long serialVersionUID = 0; 309 } 310 311 /** 312 * Returns a function that ignores its input and always returns {@code value}. 313 * 314 * <p><b>Java 8 users:</b> use the lambda expression {@code o -> value} instead. 315 * 316 * @param value the constant value for the function to return 317 * @return a function that always returns {@code value} 318 */ 319 public static <E> Function<Object, E> constant(@NullableDecl E value) { 320 return new ConstantFunction<E>(value); 321 } 322 323 private static class ConstantFunction<E> implements Function<Object, E>, Serializable { 324 @NullableDecl private final E value; 325 326 public ConstantFunction(@NullableDecl E value) { 327 this.value = value; 328 } 329 330 @Override 331 public E apply(@NullableDecl Object from) { 332 return value; 333 } 334 335 @Override 336 public boolean equals(@NullableDecl Object obj) { 337 if (obj instanceof ConstantFunction) { 338 ConstantFunction<?> that = (ConstantFunction<?>) obj; 339 return Objects.equal(value, that.value); 340 } 341 return false; 342 } 343 344 @Override 345 public int hashCode() { 346 return (value == null) ? 0 : value.hashCode(); 347 } 348 349 @Override 350 public String toString() { 351 return "Functions.constant(" + value + ")"; 352 } 353 354 private static final long serialVersionUID = 0; 355 } 356 357 /** 358 * Returns a function that ignores its input and returns the result of {@code supplier.get()}. 359 * 360 * <p><b>Java 8 users:</b> use the lambda expression {@code o -> supplier.get()} instead. 361 * 362 * @since 10.0 363 */ 364 public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) { 365 return new SupplierFunction<T>(supplier); 366 } 367 368 /** @see Functions#forSupplier */ 369 private static class SupplierFunction<T> implements Function<Object, T>, Serializable { 370 371 private final Supplier<T> supplier; 372 373 private SupplierFunction(Supplier<T> supplier) { 374 this.supplier = checkNotNull(supplier); 375 } 376 377 @Override 378 public T apply(@NullableDecl Object input) { 379 return supplier.get(); 380 } 381 382 @Override 383 public boolean equals(@NullableDecl Object obj) { 384 if (obj instanceof SupplierFunction) { 385 SupplierFunction<?> that = (SupplierFunction<?>) obj; 386 return this.supplier.equals(that.supplier); 387 } 388 return false; 389 } 390 391 @Override 392 public int hashCode() { 393 return supplier.hashCode(); 394 } 395 396 @Override 397 public String toString() { 398 return "Functions.forSupplier(" + supplier + ")"; 399 } 400 401 private static final long serialVersionUID = 0; 402 } 403}