001 /*
002 * Copyright (C) 2007 Google Inc.
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 com.google.common.annotations.GwtCompatible;
020 import com.google.common.annotations.VisibleForTesting;
021
022 import java.util.ArrayList;
023 import java.util.Arrays;
024 import java.util.List;
025
026 import javax.annotation.Nullable;
027
028 /**
029 * Helper functions that can operate on any {@code Object}.
030 *
031 * @author Laurence Gonsalves
032 * @since 2 (imported from Google Collections Library)
033 */
034 @GwtCompatible
035 public final class Objects {
036 private Objects() {}
037
038 /**
039 * Determines whether two possibly-null objects are equal. Returns:
040 *
041 * <ul>
042 * <li>{@code true} if {@code a} and {@code b} are both null.
043 * <li>{@code true} if {@code a} and {@code b} are both non-null and they are
044 * equal according to {@link Object#equals(Object)}.
045 * <li>{@code false} in all other situations.
046 * </ul>
047 *
048 * <p>This assumes that any non-null objects passed to this function conform
049 * to the {@code equals()} contract.
050 */
051 public static boolean equal(@Nullable Object a, @Nullable Object b) {
052 return a == b || (a != null && a.equals(b));
053 }
054
055 /**
056 * Generates a hash code for multiple values. The hash code is generated by
057 * calling {@link Arrays#hashCode(Object[])}.
058 *
059 * <p>This is useful for implementing {@link Object#hashCode()}. For example,
060 * in an object that has three properties, {@code x}, {@code y}, and
061 * {@code z}, one could write:
062 * <pre>
063 * public int hashCode() {
064 * return Objects.hashCode(getX(), getY(), getZ());
065 * }</pre>
066 *
067 * <b>Warning</b>: When a single object is supplied, the returned hash code
068 * does not equal the hash code of that object.
069 */
070 public static int hashCode(Object... objects) {
071 return Arrays.hashCode(objects);
072 }
073
074 /**
075 * Creates an instance of {@link ToStringHelper}.
076 *
077 * <p>This is helpful for implementing {@link Object#toString()}. For
078 * example, in an object that contains two member variables, {@code x},
079 * and {@code y}, one could write:<pre> <tt>
080 * public class ClassName {
081 * public String toString() {
082 * return Objects.toStringHelper(this)
083 * .add("x", x)
084 * .add("y", y)
085 * .toString();
086 * }
087 * }</tt>
088 * </pre>
089 *
090 * Assuming the values of {@code x} and {@code y} are 1 and 2,
091 * this code snippet returns the string <tt>"ClassName{x=1, y=2}"</tt>.
092 *
093 * @param self the object to generate the string for (typically {@code this}),
094 * used only for its class name
095 * @since 2
096 */
097 public static ToStringHelper toStringHelper(Object self) {
098 return new ToStringHelper(self);
099 }
100
101 /**
102 * Returns the first of two given parameters that is not {@code null}, if
103 * either is, or otherwise throws a {@link NullPointerException}.
104 *
105 * @return {@code first} if {@code first} is not {@code null}, or
106 * {@code second} if {@code first} is {@code null} and {@code second} is
107 * not {@code null}
108 * @throws NullPointerException if both {@code first} and {@code second} were
109 * {@code null}
110 * @since 3
111 */
112 public static <T> T firstNonNull(@Nullable T first, @Nullable T second) {
113 return first != null ? first : Preconditions.checkNotNull(second);
114 }
115
116 /**
117 * Support class for {@link Objects#toStringHelper}.
118 *
119 * @author Jason Lee
120 * @since 2
121 */
122 public static class ToStringHelper {
123 private final List<String> fieldString = new ArrayList<String>();
124 private final Object instance;
125
126 /**
127 * Use {@link Objects#toStringHelper(Object)} to create an instance.
128 */
129 private ToStringHelper(Object instance) {
130 this.instance = Preconditions.checkNotNull(instance);
131 }
132
133 /**
134 * Adds a name/value pair to the formatted output in {@code name=value}
135 * format. If {@code value} is {@code null}, the string {@code "null"}
136 * is used.
137 */
138 public ToStringHelper add(String name, @Nullable Object value) {
139 return addValue(Preconditions.checkNotNull(name) + "=" + value);
140 }
141
142 /**
143 * Adds a value to the formatted output in {@code value} format.<p/>
144 *
145 * It is strongly encouraged to use {@link #add(String, Object)} instead and
146 * give value a readable name.
147 */
148 public ToStringHelper addValue(@Nullable Object value) {
149 fieldString.add(String.valueOf(value));
150 return this;
151 }
152
153 private static final Joiner JOINER = Joiner.on(", ");
154
155 /**
156 * Returns the formatted string.
157 */
158 @Override public String toString() {
159 StringBuilder builder = new StringBuilder(100)
160 .append(simpleName(instance.getClass()))
161 .append('{');
162 return JOINER.appendTo(builder, fieldString)
163 .append('}')
164 .toString();
165 }
166
167 /**
168 * {@link Class#getSimpleName()} is not GWT compatible yet, so we
169 * provide our own implementation.
170 */
171 @VisibleForTesting
172 static String simpleName(Class<?> clazz) {
173 String name = clazz.getName();
174
175 // we want the name of the inner class all by its lonesome
176 int start = name.lastIndexOf('$');
177
178 // if this isn't an inner class, just find the start of the
179 // top level class name.
180 if (start == -1) {
181 start = name.lastIndexOf('.');
182 }
183 return name.substring(start + 1);
184 }
185 }
186 }