JDK-4168079 : Implement toString(), equals() & hashCode() for arrays
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.2.0,1.3.1,1.4.0,5.0
  • Priority: P5
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,windows_2000
  • CPU: generic,x86,sparc
  • Submitted: 1998-08-20
  • Updated: 2017-05-16
  • Resolved: 2003-11-10
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Description

Name: dm26566			Date: 08/20/98


Arrays should provide their own implementations
for toString(), equals() and hashCode() instead
of the default implementations they inherit from
Object.

The toString() method should generate a comma
seperated list of the array elements enclosed in
square brackets. Primitive types should be converted
to strings using the appropriate conversion methods
and objects (including other arrays) should be 
converted as if by String.valueOf(Object)

Examples:
[1, 2, 3] // array of ints
[a, b, c] // array of chars
[MyClass@ABCDEF, null, MyClass@123456] // array of MyClass objects
[] // empty array (zero length)
[[1, 2], [], [3], null] // array of arrays of ints

The equals() method should perform a value comparison
instead of a reference comparison. This will also
require that the hashCode() method be overridden
to return a value based on the array's contents.
I recommend using the formula given for
java.util.List.hashCode(). You'll have to modify
it to handle primitive types as well as object
references.
(Review ID: 37232)
======================================================================

Name: jl125535			Date: 11/28/2001


java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
Java HotSpot(TM) Client VM (build 1.3.1-b24, interpreted mode)

Another reason to support equals for array objects is to allow
java.util.Arrays.equals() to behave correctly when presented with arrays
of arrays.

According to the javadoc, java.util.Arrays.equals() is behaving properly.
In the code below, the unexpected behavior arises from the semantics
of the equals() method for objects that represent arrays.


Actual output:

Arrays.equals() = false
rows1.equals()  = false


Expected output:

Arrays.equals() = true
rows1.equals()  = true


Code:

import java.util.Arrays;

public class ArrayEqualityTest
{
    public static void main(String[] args)
    {
        String[][] rows1 = {
            new String[] { "4", "spank harder" },
            new String[] { "6", "douglas -- gangsta" },
            new String[] { "5", "momma''s revenge" }
        };

        String[][] rows2 = {
            new String[] { "4", "spank harder" },
            new String[] { "6", "douglas -- gangsta" },
            new String[] { "5", "momma''s revenge" }
        };

        System.out.println("Arrays.equals() = " + Arrays.equals(rows1, rows2));
        System.out.println("rows1.equals()  = " + rows1.equals(rows2));
    }
}
(Review ID: 136372)
======================================================================

Comments
WORK AROUND Name: dm26566 Date: 08/20/98 Implement helper methods to accomplish the same thing. ======================================================================
11-06-2004

EVALUATION Not an unreasonable design. One caveat: the toString() method is often used in printing diagnostics. One would have to be careful if very large arrays were involved. The Lisp language deals with this using the print-level/print-length mechanism. Something similar would be needed in Java as well. In practice, the 'toString' method provided in every class should be preferred as the brief option suitable for use in concise diagnostics, and a more verbose representation provided by additional application-specific conversion methods if needed by the application logic. Regardless of its technical merit, however, it is doubtful that we can make such a change at this late date due to compatibility/stability concerns. william.maddox@Eng 1998-08-31 I concur. It would definitely have been the right thing in 1.0, or maybe even 1.1, but it's almost certainly too late for all of these changes except perhaps the toString change. One consolation is that it's amazingly easy to build adapter classes with the desired behavior. Here's an example: public static List intArrayList(final int[] a) { return new AbstractList() { public Object get(int i) {return new Integer(a[i]);} public int size() {return a.length;} public Object set(int i, Object o) { int oldVal = a[i]; a[i] = ((Integer)o).intValue(); return new Integer(oldVal); } }; } It should be noted that these adapters are too inefficient for general use (due to the conversion between primitive and wrapepr objects for elements). Nonetheless, they work fine for occasional use (such as dispaly). joshua.bloch@Eng 1998-09-17
17-09-1998