Le 12/10/2009 20:41, Joseph D. Darcy a écrit :
Rémi Forax wrote:
Le 12/10/2009 19:25, Joseph D. Darcy a écrit :
Joshua Bloch wrote:
Joe,

I'm not sure I like this idea. My one experience with forcing an array method to do double duty as varargs method was a disaster. The method was Arrays.asList, and the result was Puzzler # 7 from "The Continuing Adventures of Java™Puzzlers: Tiger Traps." Here it is:

*7. “Fib O’Nacci”*

public class Fibonacci {
    private static final int LENGTH = 7;
    public static void main(String[] args) {
        int[] fib = new int[LENGTH];
        fib[0] = fib[1] = 1; // First 2 Fibonacci numbers
        for (inti = 2; i < LENGTH; i++)
            fib[i] = fib[i -2] + fib[i -1];
        System.out.println(Arrays.asList(fib));
    }
}

The main moral of the puzzle was:

Use varargssparingly in your APIs
    •It can hide errors and cause confusion
    •This program wouldn't compile under 1.4

Arrays.hashCode, equals, and toString are already overloaded out the wazoo; adding varargs to the mix could be deadly. Also, Arrays is not the place where people would go looking for what is essentially a hashing utility. So I'm not in favor of varargifying the existing methods in Arrays, but I am in favor of adding a convenience method like this somewhere:

         /**
* 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/>
* <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:
     * <pre>
     * &#064;Override public int hashCode() {
     *     return Objects.hashCode(x, y, z);
     * }
     * </pre>
* <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)}.
     */
    public static int hash(Object... components) {
        return Arrays.hashCode(components);
    }

Viewed in isolation, it's simple, straightforward, and will help people write high quality hashCode methods. I don't think Objects is a bad place for it, but you could put it is a "hash utility" class if we wrote such a thing.


Okay; unless and until a hash utility is added somewhere, this hash(Object ...) can live in Objects.

-Joe

In that case, we can also add some methods hash that avoid create an array
for let say 2 to 5 arguments:
hash(Object, Object), hash-Object, Object, Object), hash(Object,Object,Object,Object)
and hash(Object,Object,Object,Object,Object).


I don't think such methods are justified at present.

-Joe


It's not a good idea to have a hashCode() that allocate objects,
at least until escape analysis is implemented in all VMs.

Rémi


Reply via email to