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 }