1 /* 2 * Copyright (C) 2007 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.base; 18 19 import com.google.common.annotations.GwtCompatible; 20 import com.google.common.annotations.VisibleForTesting; 21 22 import java.util.ArrayList; 23 import java.util.Arrays; 24 import java.util.List; 25 26 import javax.annotation.Nullable; 27 28 /** 29 * Helper functions that can operate on any {@code Object}. 30 * 31 * @author Laurence Gonsalves 32 * @since 2010.01.04 <b>stable</b> (imported from Google Collections Library) 33 */ 34 @GwtCompatible 35 public final class Objects { Objects()36 private Objects() {} 37 38 /** 39 * Determines whether two possibly-null objects are equal. Returns: 40 * 41 * <ul> 42 * <li>{@code true} if {@code a} and {@code b} are both null. 43 * <li>{@code true} if {@code a} and {@code b} are both non-null and they are 44 * equal according to {@link Object#equals(Object)}. 45 * <li>{@code false} in all other situations. 46 * </ul> 47 * 48 * <p>This assumes that any non-null objects passed to this function conform 49 * to the {@code equals()} contract. 50 */ equal(@ullable Object a, @Nullable Object b)51 public static boolean equal(@Nullable Object a, @Nullable Object b) { 52 return a == b || (a != null && a.equals(b)); 53 } 54 55 /** 56 * Generates a hash code for multiple values. The hash code is generated by 57 * calling {@link Arrays#hashCode(Object[])}. 58 * 59 * <p>This is useful for implementing {@link Object#hashCode()}. For example, 60 * in an object that has three properties, {@code x}, {@code y}, and 61 * {@code z}, one could write: 62 * <pre> 63 * public int hashCode() { 64 * return Objects.hashCode(getX(), getY(), getZ()); 65 * }</pre> 66 * 67 * <b>Warning</b>: When a single object is supplied, the returned hash code 68 * does not equal the hash code of that object. 69 */ hashCode(Object... objects)70 public static int hashCode(Object... objects) { 71 return Arrays.hashCode(objects); 72 } 73 74 /** 75 * Creates an instance of {@link ToStringHelper}. 76 * 77 * <p>This is helpful for implementing {@link Object#toString()}. For 78 * example, in an object that contains two member variables, {@code x}, 79 * and {@code y}, one could write:<pre> <tt> 80 * public class ClassName { 81 * public String toString() { 82 * return Objects.toStringHelper(this) 83 * .add("x", x) 84 * .add("y", y) 85 * .toString(); 86 * } 87 * }</tt> 88 * </pre> 89 * 90 * Assuming the values of {@code x} and {@code y} are 1 and 2, 91 * this code snippet returns the string <tt>"ClassName{x=1, y=2}"</tt>. 92 * 93 * @since 2010.01.04 <b>tentative</b> 94 */ toStringHelper(Object object)95 public static ToStringHelper toStringHelper(Object object) { 96 return new ToStringHelper(object); 97 } 98 99 /** 100 * Support class for {@link Objects#toStringHelper}. 101 * 102 * @author Jason Lee 103 * @since 2010.01.04 <b>tentative</b> 104 */ 105 public static class ToStringHelper { 106 private final List<String> fieldString = new ArrayList<String>(); 107 private final Object instance; 108 109 /** 110 * Use {@link Objects#toStringHelper(Object)} to create an instance. 111 */ ToStringHelper(Object instance)112 private ToStringHelper(Object instance) { 113 this.instance = Preconditions.checkNotNull(instance); 114 } 115 116 /** 117 * Adds a name/value pair to the formatted output in {@code name=value} 118 * format. If {@code value} is {@code null}, the string {@code "null"} 119 * is used. 120 */ add(String name, @Nullable Object value)121 public ToStringHelper add(String name, @Nullable Object value) { 122 return addValue(Preconditions.checkNotNull(name) + "=" + value); 123 } 124 125 /** 126 * Adds a value to the formatted output in {@code value} format.<p/> 127 * 128 * It is strongly encouraged to use {@link #add(String, Object)} instead and 129 * give value a readable name. 130 */ addValue(@ullable Object value)131 public ToStringHelper addValue(@Nullable Object value) { 132 fieldString.add(String.valueOf(value)); 133 return this; 134 } 135 136 private static final Joiner JOINER = Joiner.on(", "); 137 138 /** 139 * Returns the formatted string. 140 */ toString()141 @Override public String toString() { 142 StringBuilder builder = new StringBuilder(100) 143 .append(simpleName(instance.getClass())) 144 .append('{'); 145 return JOINER.appendTo(builder, fieldString) 146 .append('}') 147 .toString(); 148 } 149 150 /** 151 * {@link Class#getSimpleName()} is not GWT compatible yet, so we 152 * provide our own implementation. 153 */ 154 @VisibleForTesting simpleName(Class<?> clazz)155 static String simpleName(Class<?> clazz) { 156 String name = clazz.getName(); 157 158 // we want the name of the inner class all by its lonesome 159 int start = name.lastIndexOf('$'); 160 161 // if this isn't an inner class, just find the start of the 162 // top level class name. 163 if (start == -1) { 164 start = name.lastIndexOf('.'); 165 } 166 return name.substring(start + 1); 167 } 168 } 169 } 170