6891113
: More methods for java.util.Objects: deepEquals, hash, toString with default
Reviewed-by: alanb, gafter
This commit is contained in:
parent
5e235aa57e
commit
0452077b9a
@ -3928,6 +3928,7 @@ public class Arrays {
|
||||
* @param a2 the other array to be tested for equality
|
||||
* @return <tt>true</tt> if the two arrays are equal
|
||||
* @see #equals(Object[],Object[])
|
||||
* @see Objects#deepEquals(Object, Object)
|
||||
* @since 1.5
|
||||
*/
|
||||
public static boolean deepEquals(Object[] a1, Object[] a2) {
|
||||
@ -3949,27 +3950,7 @@ public class Arrays {
|
||||
return false;
|
||||
|
||||
// Figure out whether the two elements are equal
|
||||
boolean eq;
|
||||
if (e1 instanceof Object[] && e2 instanceof Object[])
|
||||
eq = deepEquals ((Object[]) e1, (Object[]) e2);
|
||||
else if (e1 instanceof byte[] && e2 instanceof byte[])
|
||||
eq = equals((byte[]) e1, (byte[]) e2);
|
||||
else if (e1 instanceof short[] && e2 instanceof short[])
|
||||
eq = equals((short[]) e1, (short[]) e2);
|
||||
else if (e1 instanceof int[] && e2 instanceof int[])
|
||||
eq = equals((int[]) e1, (int[]) e2);
|
||||
else if (e1 instanceof long[] && e2 instanceof long[])
|
||||
eq = equals((long[]) e1, (long[]) e2);
|
||||
else if (e1 instanceof char[] && e2 instanceof char[])
|
||||
eq = equals((char[]) e1, (char[]) e2);
|
||||
else if (e1 instanceof float[] && e2 instanceof float[])
|
||||
eq = equals((float[]) e1, (float[]) e2);
|
||||
else if (e1 instanceof double[] && e2 instanceof double[])
|
||||
eq = equals((double[]) e1, (double[]) e2);
|
||||
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
|
||||
eq = equals((boolean[]) e1, (boolean[]) e2);
|
||||
else
|
||||
eq = e1.equals(e2);
|
||||
boolean eq = deepEquals0(e1, e2);
|
||||
|
||||
if (!eq)
|
||||
return false;
|
||||
@ -3977,6 +3958,32 @@ public class Arrays {
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean deepEquals0(Object e1, Object e2) {
|
||||
assert e1 != null;
|
||||
boolean eq;
|
||||
if (e1 instanceof Object[] && e2 instanceof Object[])
|
||||
eq = deepEquals ((Object[]) e1, (Object[]) e2);
|
||||
else if (e1 instanceof byte[] && e2 instanceof byte[])
|
||||
eq = equals((byte[]) e1, (byte[]) e2);
|
||||
else if (e1 instanceof short[] && e2 instanceof short[])
|
||||
eq = equals((short[]) e1, (short[]) e2);
|
||||
else if (e1 instanceof int[] && e2 instanceof int[])
|
||||
eq = equals((int[]) e1, (int[]) e2);
|
||||
else if (e1 instanceof long[] && e2 instanceof long[])
|
||||
eq = equals((long[]) e1, (long[]) e2);
|
||||
else if (e1 instanceof char[] && e2 instanceof char[])
|
||||
eq = equals((char[]) e1, (char[]) e2);
|
||||
else if (e1 instanceof float[] && e2 instanceof float[])
|
||||
eq = equals((float[]) e1, (float[]) e2);
|
||||
else if (e1 instanceof double[] && e2 instanceof double[])
|
||||
eq = equals((double[]) e1, (double[]) e2);
|
||||
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
|
||||
eq = equals((boolean[]) e1, (boolean[]) e2);
|
||||
else
|
||||
eq = e1.equals(e2);
|
||||
return eq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the contents of the specified array.
|
||||
* The string representation consists of a list of the array's elements,
|
||||
|
@ -33,7 +33,7 @@ package java.util;
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public class Objects {
|
||||
public final class Objects {
|
||||
private Objects() {
|
||||
throw new AssertionError("No java.util.Objects instances for you!");
|
||||
}
|
||||
@ -57,6 +57,32 @@ public class Objects {
|
||||
return (a == b) || (a != null && a.equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the arguments are deeply equal to each other
|
||||
* and {@code false} otherwise.
|
||||
*
|
||||
* Two {@code null} values are deeply equal. If both arguments are
|
||||
* arrays, the algorithm in {@link Arrays#deepEquals(Object[],
|
||||
* Object[]) Arrays.deepEquals} is used to determine equality.
|
||||
* Otherwise, equality is determined by using the {@link
|
||||
* Object#equals equals} method of the first argument.
|
||||
*
|
||||
* @param a an object
|
||||
* @param b an object to be compared with {@code a} for deep equality
|
||||
* @return {@code true} if the arguments are deeply equal to each other
|
||||
* and {@code false} otherwise
|
||||
* @see Arrays#deepEquals(Object[], Object[])
|
||||
* @see Objects#equals(Object, Object)
|
||||
*/
|
||||
public static boolean deepEquals(Object a, Object b) {
|
||||
if (a == b)
|
||||
return true;
|
||||
else if (a == null || b == null)
|
||||
return false;
|
||||
else
|
||||
return Arrays.deepEquals0(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code of a non-{@code null} argument and 0 for
|
||||
* a {@code null} argument.
|
||||
@ -70,6 +96,36 @@ public class Objects {
|
||||
return o != null ? o.hashCode() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a hash code for a sequence of input values. The hash
|
||||
* code is generated as if all the input values were placed into an
|
||||
* array, and that array were hashed by calling {@link
|
||||
* Arrays#hashCode(Object[])}.
|
||||
*
|
||||
* <p>This method is useful for implementing {@link
|
||||
* Object#hashCode()} on objects containing multiple fields. For
|
||||
* example, if an object that has three fields, {@code x}, {@code
|
||||
* y}, and {@code z}, one could write:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* @Override public int hashCode() {
|
||||
* return Objects.hash(x, y, z);
|
||||
* }
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* <b>Warning: When a single object reference is supplied, the returned
|
||||
* value does not equal the hash code of that object reference.</b> This
|
||||
* value can be computed by calling {@link #hashCode(Object)}.
|
||||
*
|
||||
* @param values the values to be hashed
|
||||
* @return a hash value of the sequence of input values
|
||||
* @see Arrays#hashCode
|
||||
* @see List#hashCode
|
||||
*/
|
||||
public static int hash(Object... values) {
|
||||
return Arrays.hashCode(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of calling {@code toString} for a non-{@code
|
||||
* null} argument and {@code "null"} for a {@code null} argument.
|
||||
@ -84,6 +140,23 @@ public class Objects {
|
||||
return String.valueOf(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of calling {@code toString} on the first
|
||||
* argument if the first argument is not {@code null} and returns
|
||||
* the second argument otherwise.
|
||||
*
|
||||
* @param o an object
|
||||
* @param nullDefault string to return if the first argument is
|
||||
* {@code null}
|
||||
* @return the result of calling {@code toString} on the first
|
||||
* argument if it is not {@code null} and the second argument
|
||||
* otherwise.
|
||||
* @see Objects#toString(Object)
|
||||
*/
|
||||
public static String toString(Object o, String nullDefault) {
|
||||
return (o != null) ? o.toString() : nullDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 0 if the arguments are identical and {@code
|
||||
* c.compare(a, b)} otherwise.
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6797535
|
||||
* @bug 6797535 6889858 6891113
|
||||
* @summary Basic tests for methods in java.util.Objects
|
||||
* @author Joseph D. Darcy
|
||||
*/
|
||||
@ -34,8 +34,11 @@ public class BasicObjectsTest {
|
||||
public static void main(String... args) {
|
||||
int errors = 0;
|
||||
errors += testEquals();
|
||||
errors += testDeepEquals();
|
||||
errors += testHashCode();
|
||||
errors += testHash();
|
||||
errors += testToString();
|
||||
errors += testToString2();
|
||||
errors += testCompare();
|
||||
errors += testNonNull();
|
||||
if (errors > 0 )
|
||||
@ -60,6 +63,36 @@ public class BasicObjectsTest {
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testDeepEquals() {
|
||||
int errors = 0;
|
||||
Object[] values = {null,
|
||||
null, // Change to values later
|
||||
new byte[] {(byte)1},
|
||||
new short[] {(short)1},
|
||||
new int[] {1},
|
||||
new long[] {1L},
|
||||
new char[] {(char)1},
|
||||
new float[] {1.0f},
|
||||
new double[]{1.0d},
|
||||
new String[]{"one"}};
|
||||
values[1] = values;
|
||||
|
||||
for(int i = 0; i < values.length; i++)
|
||||
for(int j = 0; j < values.length; j++) {
|
||||
boolean expected = (i == j);
|
||||
Object a = values[i];
|
||||
Object b = values[j];
|
||||
boolean result = Objects.deepEquals(a, b);
|
||||
if (result != expected) {
|
||||
errors++;
|
||||
System.err.printf("When equating %s to %s, got %b instead of %b%n.",
|
||||
a, b, result, expected);
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testHashCode() {
|
||||
int errors = 0;
|
||||
errors += (Objects.hashCode(null) == 0 ) ? 0 : 1;
|
||||
@ -68,6 +101,19 @@ public class BasicObjectsTest {
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testHash() {
|
||||
int errors = 0;
|
||||
|
||||
Object[] data = new String[]{"perfect", "ham", "THC"};
|
||||
|
||||
errors += ((Objects.hash((Object[])null) == 0) ? 0 : 1);
|
||||
|
||||
errors += (Objects.hash("perfect", "ham", "THC") ==
|
||||
Arrays.hashCode(data)) ? 0 : 1;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testToString() {
|
||||
int errors = 0;
|
||||
errors += ("null".equals(Objects.toString(null)) ) ? 0 : 1;
|
||||
@ -76,6 +122,14 @@ public class BasicObjectsTest {
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testToString2() {
|
||||
int errors = 0;
|
||||
String s = "not the default";
|
||||
errors += (s.equals(Objects.toString(null, s)) ) ? 0 : 1;
|
||||
errors += (s.equals(Objects.toString(s, "another string")) ) ? 0 : 1;
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testCompare() {
|
||||
int errors = 0;
|
||||
String[] values = {"e. e. cummings", "zzz"};
|
||||
|
Loading…
Reference in New Issue
Block a user