001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.base; 018 019import static com.google.common.base.Preconditions.checkArgument; 020import static com.google.common.base.Preconditions.checkNotNull; 021 022import com.google.common.annotations.Beta; 023import com.google.common.annotations.GwtCompatible; 024 025import java.io.Serializable; 026import java.util.Map; 027 028import javax.annotation.CheckReturnValue; 029import javax.annotation.Nullable; 030 031/** 032 * Static utility methods pertaining to {@code Function} instances. 033 * 034 * <p>All methods return serializable functions as long as they're given serializable parameters. 035 * 036 * <p>See the Guava User Guide article on <a href= 037 * "https://github.com/google/guava/wiki/FunctionalExplained">the use of {@code 038 * Function}</a>. 039 * 040 * @author Mike Bostock 041 * @author Jared Levy 042 * @since 2.0 043 */ 044@GwtCompatible 045@CheckReturnValue 046public final class Functions { 047 private Functions() {} 048 049 /** 050 * Returns a function that calls {@code toString()} on its argument. The function does not accept 051 * nulls; it will throw a {@link NullPointerException} when applied to {@code null}. 052 * 053 * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as 054 * documented at {@link Function#apply}). For example, this function yields different results for 055 * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}. 056 */ 057 public static Function<Object, String> toStringFunction() { 058 return ToStringFunction.INSTANCE; 059 } 060 061 // enum singleton pattern 062 private enum ToStringFunction implements Function<Object, String> { 063 INSTANCE; 064 065 @Override 066 public String apply(Object o) { 067 checkNotNull(o); // eager for GWT. 068 return o.toString(); 069 } 070 071 @Override 072 public String toString() { 073 return "Functions.toStringFunction()"; 074 } 075 } 076 077 /** 078 * Returns the identity function. 079 */ 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 @Nullable 092 public Object apply(@Nullable 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 public static <K, V> Function<K, V> forMap(Map<K, V> map) { 112 return new FunctionForMapNoDefault<K, V>(map); 113 } 114 115 private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable { 116 final Map<K, V> map; 117 118 FunctionForMapNoDefault(Map<K, V> map) { 119 this.map = checkNotNull(map); 120 } 121 122 @Override 123 public V apply(@Nullable K key) { 124 V result = map.get(key); 125 checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key); 126 return result; 127 } 128 129 @Override 130 public boolean equals(@Nullable Object o) { 131 if (o instanceof FunctionForMapNoDefault) { 132 FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o; 133 return map.equals(that.map); 134 } 135 return false; 136 } 137 138 @Override 139 public int hashCode() { 140 return map.hashCode(); 141 } 142 143 @Override 144 public String toString() { 145 return "Functions.forMap(" + map + ")"; 146 } 147 148 private static final long serialVersionUID = 0; 149 } 150 151 /** 152 * Returns a function which performs a map lookup with a default value. The function created by 153 * this method returns {@code defaultValue} for all inputs that do not belong to the map's key 154 * set. See also {@link #forMap(Map)}, which throws an exception in this case. 155 * 156 * @param map source map that determines the function behavior 157 * @param defaultValue the value to return for inputs that aren't map keys 158 * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code 159 * defaultValue} otherwise 160 */ 161 public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) { 162 return new ForMapWithDefault<K, V>(map, defaultValue); 163 } 164 165 private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable { 166 final Map<K, ? extends V> map; 167 final V defaultValue; 168 169 ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) { 170 this.map = checkNotNull(map); 171 this.defaultValue = defaultValue; 172 } 173 174 @Override 175 public V apply(@Nullable K key) { 176 V result = map.get(key); 177 return (result != null || map.containsKey(key)) ? result : defaultValue; 178 } 179 180 @Override 181 public boolean equals(@Nullable Object o) { 182 if (o instanceof ForMapWithDefault) { 183 ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o; 184 return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue); 185 } 186 return false; 187 } 188 189 @Override 190 public int hashCode() { 191 return Objects.hashCode(map, defaultValue); 192 } 193 194 @Override 195 public String toString() { 196 // TODO(cpovirk): maybe remove "defaultValue=" to make this look like the method call does 197 return "Functions.forMap(" + map + ", defaultValue=" + defaultValue + ")"; 198 } 199 200 private static final long serialVersionUID = 0; 201 } 202 203 /** 204 * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition 205 * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}. 206 * 207 * @param g the second function to apply 208 * @param f the first function to apply 209 * @return the composition of {@code f} and {@code g} 210 * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a> 211 */ 212 public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) { 213 return new FunctionComposition<A, B, C>(g, f); 214 } 215 216 private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable { 217 private final Function<B, C> g; 218 private final Function<A, ? extends B> f; 219 220 public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) { 221 this.g = checkNotNull(g); 222 this.f = checkNotNull(f); 223 } 224 225 @Override 226 public C apply(@Nullable A a) { 227 return g.apply(f.apply(a)); 228 } 229 230 @Override 231 public boolean equals(@Nullable Object obj) { 232 if (obj instanceof FunctionComposition) { 233 FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj; 234 return f.equals(that.f) && g.equals(that.g); 235 } 236 return false; 237 } 238 239 @Override 240 public int hashCode() { 241 return f.hashCode() ^ g.hashCode(); 242 } 243 244 @Override 245 public String toString() { 246 // TODO(cpovirk): maybe make this look like the method call does ("Functions.compose(...)") 247 return g + "(" + f + ")"; 248 } 249 250 private static final long serialVersionUID = 0; 251 } 252 253 /** 254 * Creates a function that returns the same boolean output as the given predicate for all inputs. 255 * 256 * <p>The returned function is <i>consistent with equals</i> (as documented at {@link 257 * Function#apply}) if and only if {@code predicate} is itself consistent with equals. 258 */ 259 public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) { 260 return new PredicateFunction<T>(predicate); 261 } 262 263 /** @see Functions#forPredicate */ 264 private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable { 265 private final Predicate<T> predicate; 266 267 private PredicateFunction(Predicate<T> predicate) { 268 this.predicate = checkNotNull(predicate); 269 } 270 271 @Override 272 public Boolean apply(@Nullable T t) { 273 return predicate.apply(t); 274 } 275 276 @Override 277 public boolean equals(@Nullable Object obj) { 278 if (obj instanceof PredicateFunction) { 279 PredicateFunction<?> that = (PredicateFunction<?>) obj; 280 return predicate.equals(that.predicate); 281 } 282 return false; 283 } 284 285 @Override 286 public int hashCode() { 287 return predicate.hashCode(); 288 } 289 290 @Override 291 public String toString() { 292 return "Functions.forPredicate(" + predicate + ")"; 293 } 294 295 private static final long serialVersionUID = 0; 296 } 297 298 /** 299 * Creates a function that returns {@code value} for any input. 300 * 301 * @param value the constant value for the function to return 302 * @return a function that always returns {@code value} 303 */ 304 public static <E> Function<Object, E> constant(@Nullable E value) { 305 return new ConstantFunction<E>(value); 306 } 307 308 private static class ConstantFunction<E> implements Function<Object, E>, Serializable { 309 private final E value; 310 311 public ConstantFunction(@Nullable E value) { 312 this.value = value; 313 } 314 315 @Override 316 public E apply(@Nullable Object from) { 317 return value; 318 } 319 320 @Override 321 public boolean equals(@Nullable Object obj) { 322 if (obj instanceof ConstantFunction) { 323 ConstantFunction<?> that = (ConstantFunction<?>) obj; 324 return Objects.equal(value, that.value); 325 } 326 return false; 327 } 328 329 @Override 330 public int hashCode() { 331 return (value == null) ? 0 : value.hashCode(); 332 } 333 334 @Override 335 public String toString() { 336 return "Functions.constant(" + value + ")"; 337 } 338 339 private static final long serialVersionUID = 0; 340 } 341 342 /** 343 * Returns a function that always returns the result of invoking {@link Supplier#get} on {@code 344 * supplier}, regardless of its input. 345 * 346 * @since 10.0 347 */ 348 @Beta 349 public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) { 350 return new SupplierFunction<T>(supplier); 351 } 352 353 /** @see Functions#forSupplier*/ 354 private static class SupplierFunction<T> implements Function<Object, T>, Serializable { 355 356 private final Supplier<T> supplier; 357 358 private SupplierFunction(Supplier<T> supplier) { 359 this.supplier = checkNotNull(supplier); 360 } 361 362 @Override 363 public T apply(@Nullable Object input) { 364 return supplier.get(); 365 } 366 367 @Override 368 public boolean equals(@Nullable Object obj) { 369 if (obj instanceof SupplierFunction) { 370 SupplierFunction<?> that = (SupplierFunction<?>) obj; 371 return this.supplier.equals(that.supplier); 372 } 373 return false; 374 } 375 376 @Override 377 public int hashCode() { 378 return supplier.hashCode(); 379 } 380 381 @Override 382 public String toString() { 383 return "Functions.forSupplier(" + supplier + ")"; 384 } 385 386 private static final long serialVersionUID = 0; 387 } 388}