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.checkNotNull;
020
021import com.google.common.annotations.GwtCompatible;
022
023import java.util.Arrays;
024
025import javax.annotation.CheckReturnValue;
026import javax.annotation.Nullable;
027
028/**
029 * Helper functions that can operate on any {@code Object}.
030 *
031 * <p>See the Guava User Guide on <a
032 * href="https://github.com/google/guava/wiki/CommonObjectUtilitiesExplained">writing
033 * {@code Object} methods with {@code Objects}</a>.
034 *
035 * @author Laurence Gonsalves
036 * @since 2.0
037 */
038@GwtCompatible
039public final class Objects {
040  private Objects() {}
041
042  /**
043   * Determines whether two possibly-null objects are equal. Returns:
044   *
045   * <ul>
046   * <li>{@code true} if {@code a} and {@code b} are both null.
047   * <li>{@code true} if {@code a} and {@code b} are both non-null and they are
048   *     equal according to {@link Object#equals(Object)}.
049   * <li>{@code false} in all other situations.
050   * </ul>
051   *
052   * <p>This assumes that any non-null objects passed to this function conform
053   * to the {@code equals()} contract.
054   *
055   * <p><b>Note for Java 7 and later:</b> This method should be treated as
056   * deprecated; use {@link java.util.Objects#equals} instead.
057   */
058  @CheckReturnValue
059  public static boolean equal(@Nullable Object a, @Nullable Object b) {
060    return a == b || (a != null && a.equals(b));
061  }
062
063  /**
064   * Generates a hash code for multiple values. The hash code is generated by
065   * calling {@link Arrays#hashCode(Object[])}. Note that array arguments to
066   * this method, with the exception of a single Object array, do not get any
067   * special handling; their hash codes are based on identity and not contents.
068   *
069   * <p>This is useful for implementing {@link Object#hashCode()}. For example,
070   * in an object that has three properties, {@code x}, {@code y}, and
071   * {@code z}, one could write:
072   * <pre>   {@code
073   *   public int hashCode() {
074   *     return Objects.hashCode(getX(), getY(), getZ());
075   *   }}</pre>
076   *
077   * <p><b>Warning:</b> When a single object is supplied, the returned hash code
078   * does not equal the hash code of that object.
079   *
080   * <p><b>Note for Java 7 and later:</b> This method should be treated as
081   * deprecated; use {@link java.util.Objects#hash} instead.
082   */
083  @CheckReturnValue
084  public static int hashCode(@Nullable Object... objects) {
085    return Arrays.hashCode(objects);
086  }
087
088  /**
089   * Creates an instance of {@link ToStringHelper}.
090   *
091   * <p>This is helpful for implementing {@link Object#toString()}.
092   * Specification by example: <pre>   {@code
093   *   // Returns "ClassName{}"
094   *   Objects.toStringHelper(this)
095   *       .toString();
096   *
097   *   // Returns "ClassName{x=1}"
098   *   Objects.toStringHelper(this)
099   *       .add("x", 1)
100   *       .toString();
101   *
102   *   // Returns "MyObject{x=1}"
103   *   Objects.toStringHelper("MyObject")
104   *       .add("x", 1)
105   *       .toString();
106   *
107   *   // Returns "ClassName{x=1, y=foo}"
108   *   Objects.toStringHelper(this)
109   *       .add("x", 1)
110   *       .add("y", "foo")
111   *       .toString();
112   *
113   *   // Returns "ClassName{x=1}"
114   *   Objects.toStringHelper(this)
115   *       .omitNullValues()
116   *       .add("x", 1)
117   *       .add("y", null)
118   *       .toString();
119   *   }}</pre>
120   *
121   * <p>Note that in GWT, class names are often obfuscated.
122   *
123   * @param self the object to generate the string for (typically {@code this}),
124   *        used only for its class name
125   * @since 2.0
126   * @deprecated Use {@link MoreObjects#toStringHelper(Object)} instead. This
127   *     method is scheduled for removal in June 2016.
128   */
129  @CheckReturnValue
130  @Deprecated
131  public static ToStringHelper toStringHelper(Object self) {
132    return new ToStringHelper(self.getClass().getSimpleName());
133  }
134
135  /**
136   * Creates an instance of {@link ToStringHelper} in the same manner as
137   * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz}
138   * instead of using an instance's {@link Object#getClass()}.
139   *
140   * <p>Note that in GWT, class names are often obfuscated.
141   *
142   * @param clazz the {@link Class} of the instance
143   * @since 7.0 (source-compatible since 2.0)
144   * @deprecated Use {@link MoreObjects#toStringHelper(Class)} instead. This
145   *     method is scheduled for removal in June 2016.
146   */
147  @CheckReturnValue
148  @Deprecated
149  public static ToStringHelper toStringHelper(Class<?> clazz) {
150    return new ToStringHelper(clazz.getSimpleName());
151  }
152
153  /**
154   * Creates an instance of {@link ToStringHelper} in the same manner as
155   * {@link Objects#toStringHelper(Object)}, but using {@code className} instead
156   * of using an instance's {@link Object#getClass()}.
157   *
158   * @param className the name of the instance type
159   * @since 7.0 (source-compatible since 2.0)
160   * @deprecated Use {@link MoreObjects#toStringHelper(String)} instead. This
161   *     method is scheduled for removal in June 2016.
162   */
163  @CheckReturnValue
164  @Deprecated
165  public static ToStringHelper toStringHelper(String className) {
166    return new ToStringHelper(className);
167  }
168
169  /**
170   * Returns the first of two given parameters that is not {@code null}, if
171   * either is, or otherwise throws a {@link NullPointerException}.
172   *
173   * <p><b>Note:</b> if {@code first} is represented as an {@link Optional},
174   * this can be accomplished with
175   * {@linkplain Optional#or(Object) first.or(second)}.
176   * That approach also allows for lazy evaluation of the fallback instance,
177   * using {@linkplain Optional#or(Supplier) first.or(Supplier)}.
178   *
179   * @return {@code first} if {@code first} is not {@code null}, or
180   *     {@code second} if {@code first} is {@code null} and {@code second} is
181   *     not {@code null}
182   * @throws NullPointerException if both {@code first} and {@code second} were
183   *     {@code null}
184   * @since 3.0
185   * @deprecated Use {@link MoreObjects#firstNonNull} instead. This method is
186   *      scheduled for removal in June 2016.
187   */
188  @CheckReturnValue
189  @Deprecated
190  public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
191    return MoreObjects.firstNonNull(first, second);
192  }
193
194  /**
195   * Support class for {@link Objects#toStringHelper}.
196   *
197   * @author Jason Lee
198   * @since 2.0
199   * @deprecated Use {@link MoreObjects.ToStringHelper} instead. This class is
200   *      scheduled for removal in June 2016.
201   */
202  @Deprecated
203  public static final class ToStringHelper {
204    private final String className;
205    private ValueHolder holderHead = new ValueHolder();
206    private ValueHolder holderTail = holderHead;
207    private boolean omitNullValues = false;
208
209    /**
210     * Use {@link Objects#toStringHelper(Object)} to create an instance.
211     */
212    private ToStringHelper(String className) {
213      this.className = checkNotNull(className);
214    }
215
216    /**
217     * Configures the {@link ToStringHelper} so {@link #toString()} will ignore
218     * properties with null value. The order of calling this method, relative
219     * to the {@code add()}/{@code addValue()} methods, is not significant.
220     *
221     * @since 12.0
222     */
223    public ToStringHelper omitNullValues() {
224      omitNullValues = true;
225      return this;
226    }
227
228    /**
229     * Adds a name/value pair to the formatted output in {@code name=value}
230     * format. If {@code value} is {@code null}, the string {@code "null"}
231     * is used, unless {@link #omitNullValues()} is called, in which case this
232     * name/value pair will not be added.
233     */
234    public ToStringHelper add(String name, @Nullable Object value) {
235      return addHolder(name, value);
236    }
237
238    /**
239     * Adds a name/value pair to the formatted output in {@code name=value}
240     * format.
241     *
242     * @since 11.0 (source-compatible since 2.0)
243     */
244    public ToStringHelper add(String name, boolean value) {
245      return addHolder(name, String.valueOf(value));
246    }
247
248    /**
249     * Adds a name/value pair to the formatted output in {@code name=value}
250     * format.
251     *
252     * @since 11.0 (source-compatible since 2.0)
253     */
254    public ToStringHelper add(String name, char value) {
255      return addHolder(name, String.valueOf(value));
256    }
257
258    /**
259     * Adds a name/value pair to the formatted output in {@code name=value}
260     * format.
261     *
262     * @since 11.0 (source-compatible since 2.0)
263     */
264    public ToStringHelper add(String name, double value) {
265      return addHolder(name, String.valueOf(value));
266    }
267
268    /**
269     * Adds a name/value pair to the formatted output in {@code name=value}
270     * format.
271     *
272     * @since 11.0 (source-compatible since 2.0)
273     */
274    public ToStringHelper add(String name, float value) {
275      return addHolder(name, String.valueOf(value));
276    }
277
278    /**
279     * Adds a name/value pair to the formatted output in {@code name=value}
280     * format.
281     *
282     * @since 11.0 (source-compatible since 2.0)
283     */
284    public ToStringHelper add(String name, int value) {
285      return addHolder(name, String.valueOf(value));
286    }
287
288    /**
289     * Adds a name/value pair to the formatted output in {@code name=value}
290     * format.
291     *
292     * @since 11.0 (source-compatible since 2.0)
293     */
294    public ToStringHelper add(String name, long value) {
295      return addHolder(name, String.valueOf(value));
296    }
297
298    /**
299     * Adds an unnamed value to the formatted output.
300     *
301     * <p>It is strongly encouraged to use {@link #add(String, Object)} instead
302     * and give value a readable name.
303     */
304    public ToStringHelper addValue(@Nullable Object value) {
305      return addHolder(value);
306    }
307
308    /**
309     * Adds an unnamed value to the formatted output.
310     *
311     * <p>It is strongly encouraged to use {@link #add(String, boolean)} instead
312     * and give value a readable name.
313     *
314     * @since 11.0 (source-compatible since 2.0)
315     */
316    public ToStringHelper addValue(boolean value) {
317      return addHolder(String.valueOf(value));
318    }
319
320    /**
321     * Adds an unnamed value to the formatted output.
322     *
323     * <p>It is strongly encouraged to use {@link #add(String, char)} instead
324     * and give value a readable name.
325     *
326     * @since 11.0 (source-compatible since 2.0)
327     */
328    public ToStringHelper addValue(char value) {
329      return addHolder(String.valueOf(value));
330    }
331
332    /**
333     * Adds an unnamed value to the formatted output.
334     *
335     * <p>It is strongly encouraged to use {@link #add(String, double)} instead
336     * and give value a readable name.
337     *
338     * @since 11.0 (source-compatible since 2.0)
339     */
340    public ToStringHelper addValue(double value) {
341      return addHolder(String.valueOf(value));
342    }
343
344    /**
345     * Adds an unnamed value to the formatted output.
346     *
347     * <p>It is strongly encouraged to use {@link #add(String, float)} instead
348     * and give value a readable name.
349     *
350     * @since 11.0 (source-compatible since 2.0)
351     */
352    public ToStringHelper addValue(float value) {
353      return addHolder(String.valueOf(value));
354    }
355
356    /**
357     * Adds an unnamed value to the formatted output.
358     *
359     * <p>It is strongly encouraged to use {@link #add(String, int)} instead
360     * and give value a readable name.
361     *
362     * @since 11.0 (source-compatible since 2.0)
363     */
364    public ToStringHelper addValue(int value) {
365      return addHolder(String.valueOf(value));
366    }
367
368    /**
369     * Adds an unnamed value to the formatted output.
370     *
371     * <p>It is strongly encouraged to use {@link #add(String, long)} instead
372     * and give value a readable name.
373     *
374     * @since 11.0 (source-compatible since 2.0)
375     */
376    public ToStringHelper addValue(long value) {
377      return addHolder(String.valueOf(value));
378    }
379
380    /**
381     * Returns a string in the format specified by {@link
382     * Objects#toStringHelper(Object)}.
383     *
384     * <p>After calling this method, you can keep adding more properties to later
385     * call toString() again and get a more complete representation of the
386     * same object; but properties cannot be removed, so this only allows
387     * limited reuse of the helper instance. The helper allows duplication of
388     * properties (multiple name/value pairs with the same name can be added).
389     */
390    @Override
391    public String toString() {
392      // create a copy to keep it consistent in case value changes
393      boolean omitNullValuesSnapshot = omitNullValues;
394      String nextSeparator = "";
395      StringBuilder builder = new StringBuilder(32).append(className).append('{');
396      for (ValueHolder valueHolder = holderHead.next;
397          valueHolder != null;
398          valueHolder = valueHolder.next) {
399        if (!omitNullValuesSnapshot || valueHolder.value != null) {
400          builder.append(nextSeparator);
401          nextSeparator = ", ";
402
403          if (valueHolder.name != null) {
404            builder.append(valueHolder.name).append('=');
405          }
406          builder.append(valueHolder.value);
407        }
408      }
409      return builder.append('}').toString();
410    }
411
412    private ValueHolder addHolder() {
413      ValueHolder valueHolder = new ValueHolder();
414      holderTail = holderTail.next = valueHolder;
415      return valueHolder;
416    }
417
418    private ToStringHelper addHolder(@Nullable Object value) {
419      ValueHolder valueHolder = addHolder();
420      valueHolder.value = value;
421      return this;
422    }
423
424    private ToStringHelper addHolder(String name, @Nullable Object value) {
425      ValueHolder valueHolder = addHolder();
426      valueHolder.value = value;
427      valueHolder.name = checkNotNull(name);
428      return this;
429    }
430
431    private static final class ValueHolder {
432      String name;
433      Object value;
434      ValueHolder next;
435    }
436  }
437}