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 017 package com.google.common.base; 018 019 import static com.google.common.base.Preconditions.checkArgument; 020 import static com.google.common.base.Preconditions.checkNotNull; 021 022 import com.google.common.annotations.GwtCompatible; 023 024 import java.io.Serializable; 025 import java.util.Map; 026 027 import javax.annotation.Nullable; 028 029 /** 030 * Static utility methods pertaining to {@code Function} instances. 031 * 032 * <p>All methods returns serializable functions as long as they're given serializable parameters. 033 * 034 * @author Mike Bostock 035 * @author Jared Levy 036 * @since 2 (imported from Google Collections Library) 037 */ 038 @GwtCompatible 039 public final class Functions { 040 private Functions() {} 041 042 /** 043 * Returns a function that calls {@code toString()} on its argument. The function does not accept 044 * nulls; it will throw a {@link NullPointerException} when applied to {@code null}. 045 * 046 * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as 047 * documented at {@link Function#apply}). For example, this function yields different results for 048 * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}. 049 */ 050 public static Function<Object, String> toStringFunction() { 051 return ToStringFunction.INSTANCE; 052 } 053 054 // enum singleton pattern 055 private enum ToStringFunction implements Function<Object, String> { 056 INSTANCE; 057 058 @Override 059 public String apply(Object o) { 060 checkNotNull(o); // eager for GWT. 061 return o.toString(); 062 } 063 064 @Override public String toString() { 065 return "toString"; 066 } 067 } 068 069 /** 070 * Returns the identity function. 071 */ 072 @SuppressWarnings("unchecked") 073 public static <E> Function<E, E> identity() { 074 return (Function<E, E>) IdentityFunction.INSTANCE; 075 } 076 077 // enum singleton pattern 078 private enum IdentityFunction implements Function<Object, Object> { 079 INSTANCE; 080 081 @Override 082 public Object apply(Object o) { 083 return o; 084 } 085 086 @Override public String toString() { 087 return "identity"; 088 } 089 } 090 091 /** 092 * Returns a function which performs a map lookup. The returned function throws an {@link 093 * IllegalArgumentException} if given a key that does not exist in the map. 094 */ 095 public static <K, V> Function<K, V> forMap(Map<K, V> map) { 096 return new FunctionForMapNoDefault<K, V>(map); 097 } 098 099 private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable { 100 final Map<K, V> map; 101 102 FunctionForMapNoDefault(Map<K, V> map) { 103 this.map = checkNotNull(map); 104 } 105 106 @Override 107 public V apply(K key) { 108 V result = map.get(key); 109 checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key); 110 return result; 111 } 112 113 @Override public boolean equals(@Nullable Object o) { 114 if (o instanceof FunctionForMapNoDefault) { 115 FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o; 116 return map.equals(that.map); 117 } 118 return false; 119 } 120 121 @Override public int hashCode() { 122 return map.hashCode(); 123 } 124 125 @Override public String toString() { 126 return "forMap(" + map + ")"; 127 } 128 129 private static final long serialVersionUID = 0; 130 } 131 132 /** 133 * Returns a function which performs a map lookup with a default value. The function created by 134 * this method returns {@code defaultValue} for all inputs that do not belong to the map's key 135 * set. 136 * 137 * @param map source map that determines the function behavior 138 * @param defaultValue the value to return for inputs that aren't map keys 139 * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code 140 * defaultValue} otherwise 141 */ 142 public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) { 143 return new ForMapWithDefault<K, V>(map, defaultValue); 144 } 145 146 private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable { 147 final Map<K, ? extends V> map; 148 final V defaultValue; 149 150 ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) { 151 this.map = checkNotNull(map); 152 this.defaultValue = defaultValue; 153 } 154 155 @Override 156 public V apply(K key) { 157 V result = map.get(key); 158 return (result != null || map.containsKey(key)) ? result : defaultValue; 159 } 160 161 @Override public boolean equals(@Nullable Object o) { 162 if (o instanceof ForMapWithDefault) { 163 ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o; 164 return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue); 165 } 166 return false; 167 } 168 169 @Override public int hashCode() { 170 return Objects.hashCode(map, defaultValue); 171 } 172 173 @Override public String toString() { 174 return "forMap(" + map + ", defaultValue=" + defaultValue + ")"; 175 } 176 177 private static final long serialVersionUID = 0; 178 } 179 180 /** 181 * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition 182 * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}. 183 * 184 * @param g the second function to apply 185 * @param f the first function to apply 186 * @return the composition of {@code f} and {@code g} 187 * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a> 188 */ 189 public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) { 190 return new FunctionComposition<A, B, C>(g, f); 191 } 192 193 private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable { 194 private final Function<B, C> g; 195 private final Function<A, ? extends B> f; 196 197 public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) { 198 this.g = checkNotNull(g); 199 this.f = checkNotNull(f); 200 } 201 202 @Override 203 public C apply(A a) { 204 return g.apply(f.apply(a)); 205 } 206 207 @Override public boolean equals(@Nullable Object obj) { 208 if (obj instanceof FunctionComposition) { 209 FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj; 210 return f.equals(that.f) && g.equals(that.g); 211 } 212 return false; 213 } 214 215 @Override public int hashCode() { 216 return f.hashCode() ^ g.hashCode(); 217 } 218 219 @Override public String toString() { 220 return g.toString() + "(" + f.toString() + ")"; 221 } 222 223 private static final long serialVersionUID = 0; 224 } 225 226 /** 227 * Creates a function that returns the same boolean output as the given predicate for all inputs. 228 * 229 * <p>The returned function is <i>consistent with equals</i> (as documented at {@link 230 * Function#apply}) if and only if {@code predicate} is itself consistent with equals. 231 */ 232 public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) { 233 return new PredicateFunction<T>(predicate); 234 } 235 236 /** @see Functions#forPredicate */ 237 private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable { 238 private final Predicate<T> predicate; 239 240 private PredicateFunction(Predicate<T> predicate) { 241 this.predicate = checkNotNull(predicate); 242 } 243 244 @Override 245 public Boolean apply(T t) { 246 return predicate.apply(t); 247 } 248 249 @Override public boolean equals(@Nullable Object obj) { 250 if (obj instanceof PredicateFunction) { 251 PredicateFunction<?> that = (PredicateFunction<?>) obj; 252 return predicate.equals(that.predicate); 253 } 254 return false; 255 } 256 257 @Override public int hashCode() { 258 return predicate.hashCode(); 259 } 260 261 @Override public String toString() { 262 return "forPredicate(" + predicate + ")"; 263 } 264 265 private static final long serialVersionUID = 0; 266 } 267 268 /** 269 * Creates a function that returns {@code value} for any input. 270 * 271 * @param value the constant value for the function to return 272 * @return a function that always returns {@code value} 273 */ 274 public static <E> Function<Object, E> constant(@Nullable E value) { 275 return new ConstantFunction<E>(value); 276 } 277 278 private static class ConstantFunction<E> implements Function<Object, E>, Serializable { 279 private final E value; 280 281 public ConstantFunction(@Nullable E value) { 282 this.value = value; 283 } 284 285 @Override 286 public E apply(@Nullable Object from) { 287 return value; 288 } 289 290 @Override public boolean equals(@Nullable Object obj) { 291 if (obj instanceof ConstantFunction) { 292 ConstantFunction<?> that = (ConstantFunction<?>) obj; 293 return Objects.equal(value, that.value); 294 } 295 return false; 296 } 297 298 @Override public int hashCode() { 299 return (value == null) ? 0 : value.hashCode(); 300 } 301 302 @Override public String toString() { 303 return "constant(" + value + ")"; 304 } 305 306 private static final long serialVersionUID = 0; 307 } 308 }