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="http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained">writing
033 * {@code Object} methods with {@code Objects}</a>.
034 *
035 * @author Laurence Gonsalves
036 * @since 2.0 (imported from Google Collections Library)
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  public static int hashCode(@Nullable Object... objects) {
084    return Arrays.hashCode(objects);
085  }
086
087  /**
088   * Creates an instance of {@link ToStringHelper}.
089   *
090   * <p>This is helpful for implementing {@link Object#toString()}.
091   * Specification by example: <pre>   {@code
092   *   // Returns "ClassName{}"
093   *   Objects.toStringHelper(this)
094   *       .toString();
095   *
096   *   // Returns "ClassName{x=1}"
097   *   Objects.toStringHelper(this)
098   *       .add("x", 1)
099   *       .toString();
100   *
101   *   // Returns "MyObject{x=1}"
102   *   Objects.toStringHelper("MyObject")
103   *       .add("x", 1)
104   *       .toString();
105   *
106   *   // Returns "ClassName{x=1, y=foo}"
107   *   Objects.toStringHelper(this)
108   *       .add("x", 1)
109   *       .add("y", "foo")
110   *       .toString();
111   *
112   *   // Returns "ClassName{x=1}"
113   *   Objects.toStringHelper(this)
114   *       .omitNullValues()
115   *       .add("x", 1)
116   *       .add("y", null)
117   *       .toString();
118   *   }}</pre>
119   *
120   * <p>Note that in GWT, class names are often obfuscated.
121   *
122   * @param self the object to generate the string for (typically {@code this}),
123   *        used only for its class name
124   * @since 2.0
125   * @deprecated Use {@link MoreObjects#toStringHelper(Object)} instead. This
126   *     method is scheduled for removal in June 2016.
127   */
128  @Deprecated
129  public static ToStringHelper toStringHelper(Object self) {
130    return new ToStringHelper(MoreObjects.simpleName(self.getClass()));
131  }
132
133  /**
134   * Creates an instance of {@link ToStringHelper} in the same manner as
135   * {@link Objects#toStringHelper(Object)}, but using the name of {@code clazz}
136   * instead of using an instance's {@link Object#getClass()}.
137   *
138   * <p>Note that in GWT, class names are often obfuscated.
139   *
140   * @param clazz the {@link Class} of the instance
141   * @since 7.0 (source-compatible since 2.0)
142   * @deprecated Use {@link MoreObjects#toStringHelper(Class)} instead. This
143   *     method is scheduled for removal in June 2016.
144   */
145  @Deprecated
146  public static ToStringHelper toStringHelper(Class<?> clazz) {
147    return new ToStringHelper(MoreObjects.simpleName(clazz));
148  }
149
150  /**
151   * Creates an instance of {@link ToStringHelper} in the same manner as
152   * {@link Objects#toStringHelper(Object)}, but using {@code className} instead
153   * of using an instance's {@link Object#getClass()}.
154   *
155   * @param className the name of the instance type
156   * @since 7.0 (source-compatible since 2.0)
157   * @deprecated Use {@link MoreObjects#toStringHelper(String)} instead. This
158   *     method is scheduled for removal in June 2016.
159   */
160  @Deprecated
161  public static ToStringHelper toStringHelper(String className) {
162    return new ToStringHelper(className);
163  }
164
165  /**
166   * Returns the first of two given parameters that is not {@code null}, if
167   * either is, or otherwise throws a {@link NullPointerException}.
168   *
169   * <p><b>Note:</b> if {@code first} is represented as an {@link Optional},
170   * this can be accomplished with
171   * {@linkplain Optional#or(Object) first.or(second)}.
172   * That approach also allows for lazy evaluation of the fallback instance,
173   * using {@linkplain Optional#or(Supplier) first.or(Supplier)}.
174   *
175   * @return {@code first} if {@code first} is not {@code null}, or
176   *     {@code second} if {@code first} is {@code null} and {@code second} is
177   *     not {@code null}
178   * @throws NullPointerException if both {@code first} and {@code second} were
179   *     {@code null}
180   * @since 3.0
181   * @deprecated Use {@link MoreObjects#firstNonNull} instead. This method is
182   *      scheduled for removal in June 2016.
183   */
184  @Deprecated
185  public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
186    return MoreObjects.firstNonNull(first, second);
187  }
188
189  /**
190   * Support class for {@link Objects#toStringHelper}.
191   *
192   * @author Jason Lee
193   * @since 2.0
194   * @deprecated Use {@link MoreObjects.ToStringHelper} instead. This class is
195   *      scheduled for removal in June 2016.
196   */
197  @Deprecated
198  public static final class ToStringHelper {
199    private final String className;
200    private ValueHolder holderHead = new ValueHolder();
201    private ValueHolder holderTail = holderHead;
202    private boolean omitNullValues = false;
203
204    /**
205     * Use {@link Objects#toStringHelper(Object)} to create an instance.
206     */
207    private ToStringHelper(String className) {
208      this.className = checkNotNull(className);
209    }
210
211    /**
212     * Configures the {@link ToStringHelper} so {@link #toString()} will ignore
213     * properties with null value. The order of calling this method, relative
214     * to the {@code add()}/{@code addValue()} methods, is not significant.
215     *
216     * @since 12.0
217     */
218    public ToStringHelper omitNullValues() {
219      omitNullValues = true;
220      return this;
221    }
222
223    /**
224     * Adds a name/value pair to the formatted output in {@code name=value}
225     * format. If {@code value} is {@code null}, the string {@code "null"}
226     * is used, unless {@link #omitNullValues()} is called, in which case this
227     * name/value pair will not be added.
228     */
229    public ToStringHelper add(String name, @Nullable Object value) {
230      return addHolder(name, value);
231    }
232
233    /**
234     * Adds a name/value pair to the formatted output in {@code name=value}
235     * format.
236     *
237     * @since 11.0 (source-compatible since 2.0)
238     */
239    public ToStringHelper add(String name, boolean value) {
240      return addHolder(name, String.valueOf(value));
241    }
242
243    /**
244     * Adds a name/value pair to the formatted output in {@code name=value}
245     * format.
246     *
247     * @since 11.0 (source-compatible since 2.0)
248     */
249    public ToStringHelper add(String name, char value) {
250      return addHolder(name, String.valueOf(value));
251    }
252
253    /**
254     * Adds a name/value pair to the formatted output in {@code name=value}
255     * format.
256     *
257     * @since 11.0 (source-compatible since 2.0)
258     */
259    public ToStringHelper add(String name, double value) {
260      return addHolder(name, String.valueOf(value));
261    }
262
263    /**
264     * Adds a name/value pair to the formatted output in {@code name=value}
265     * format.
266     *
267     * @since 11.0 (source-compatible since 2.0)
268     */
269    public ToStringHelper add(String name, float value) {
270      return addHolder(name, String.valueOf(value));
271    }
272
273    /**
274     * Adds a name/value pair to the formatted output in {@code name=value}
275     * format.
276     *
277     * @since 11.0 (source-compatible since 2.0)
278     */
279    public ToStringHelper add(String name, int value) {
280      return addHolder(name, String.valueOf(value));
281    }
282
283    /**
284     * Adds a name/value pair to the formatted output in {@code name=value}
285     * format.
286     *
287     * @since 11.0 (source-compatible since 2.0)
288     */
289    public ToStringHelper add(String name, long value) {
290      return addHolder(name, String.valueOf(value));
291    }
292
293    /**
294     * Adds an unnamed value to the formatted output.
295     *
296     * <p>It is strongly encouraged to use {@link #add(String, Object)} instead
297     * and give value a readable name.
298     */
299    public ToStringHelper addValue(@Nullable Object value) {
300      return addHolder(value);
301    }
302
303    /**
304     * Adds an unnamed value to the formatted output.
305     *
306     * <p>It is strongly encouraged to use {@link #add(String, boolean)} instead
307     * and give value a readable name.
308     *
309     * @since 11.0 (source-compatible since 2.0)
310     */
311    public ToStringHelper addValue(boolean value) {
312      return addHolder(String.valueOf(value));
313    }
314
315    /**
316     * Adds an unnamed value to the formatted output.
317     *
318     * <p>It is strongly encouraged to use {@link #add(String, char)} instead
319     * and give value a readable name.
320     *
321     * @since 11.0 (source-compatible since 2.0)
322     */
323    public ToStringHelper addValue(char value) {
324      return addHolder(String.valueOf(value));
325    }
326
327    /**
328     * Adds an unnamed value to the formatted output.
329     *
330     * <p>It is strongly encouraged to use {@link #add(String, double)} instead
331     * and give value a readable name.
332     *
333     * @since 11.0 (source-compatible since 2.0)
334     */
335    public ToStringHelper addValue(double value) {
336      return addHolder(String.valueOf(value));
337    }
338
339    /**
340     * Adds an unnamed value to the formatted output.
341     *
342     * <p>It is strongly encouraged to use {@link #add(String, float)} instead
343     * and give value a readable name.
344     *
345     * @since 11.0 (source-compatible since 2.0)
346     */
347    public ToStringHelper addValue(float value) {
348      return addHolder(String.valueOf(value));
349    }
350
351    /**
352     * Adds an unnamed value to the formatted output.
353     *
354     * <p>It is strongly encouraged to use {@link #add(String, int)} instead
355     * and give value a readable name.
356     *
357     * @since 11.0 (source-compatible since 2.0)
358     */
359    public ToStringHelper addValue(int value) {
360      return addHolder(String.valueOf(value));
361    }
362
363    /**
364     * Adds an unnamed value to the formatted output.
365     *
366     * <p>It is strongly encouraged to use {@link #add(String, long)} instead
367     * and give value a readable name.
368     *
369     * @since 11.0 (source-compatible since 2.0)
370     */
371    public ToStringHelper addValue(long value) {
372      return addHolder(String.valueOf(value));
373    }
374
375    /**
376     * Returns a string in the format specified by {@link
377     * Objects#toStringHelper(Object)}.
378     *
379     * <p>After calling this method, you can keep adding more properties to later
380     * call toString() again and get a more complete representation of the
381     * same object; but properties cannot be removed, so this only allows
382     * limited reuse of the helper instance. The helper allows duplication of
383     * properties (multiple name/value pairs with the same name can be added).
384     */
385    @Override public String toString() {
386      // create a copy to keep it consistent in case value changes
387      boolean omitNullValuesSnapshot = omitNullValues;
388      String nextSeparator = "";
389      StringBuilder builder = new StringBuilder(32).append(className)
390          .append('{');
391      for (ValueHolder valueHolder = holderHead.next; valueHolder != null;
392          valueHolder = valueHolder.next) {
393        if (!omitNullValuesSnapshot || valueHolder.value != null) {
394          builder.append(nextSeparator);
395          nextSeparator = ", ";
396
397          if (valueHolder.name != null) {
398            builder.append(valueHolder.name).append('=');
399          }
400          builder.append(valueHolder.value);
401        }
402      }
403      return builder.append('}').toString();
404    }
405
406    private ValueHolder addHolder() {
407      ValueHolder valueHolder = new ValueHolder();
408      holderTail = holderTail.next = valueHolder;
409      return valueHolder;
410    }
411
412    private ToStringHelper addHolder(@Nullable Object value) {
413      ValueHolder valueHolder = addHolder();
414      valueHolder.value = value;
415      return this;
416    }
417
418    private ToStringHelper addHolder(String name, @Nullable Object value) {
419      ValueHolder valueHolder = addHolder();
420      valueHolder.value = value;
421      valueHolder.name = checkNotNull(name);
422      return this;
423    }
424
425    private static final class ValueHolder {
426      String name;
427      Object value;
428      ValueHolder next;
429    }
430  }
431}