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