commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Oliver Plohmann <oli...@plohmann.com>
Subject My HashCodeBuilderUtil class to generate initial values for HashCodeBuilder
Date Sun, 16 Dec 2007 11:28:09 GMT

I once got fed up with looking for unused initial values for new 
HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber). So 
I built my HashCodeBuilderUtil class (see code below) that generates 
initial values for each class that are randomly chosen, non-zero, odd 
number, and prime numbers. Now I'm not so sure whether the way I have 
implemented this HashCodeBuilderUtil is so good in every way and would 
like to see what the public thinks about it.

In the constructor HashCodeBuilder(int initialNonZeroOddNumber, int 
multiplierNonZeroOddNumber) the two passed-in ints get multiplied. When 
not taking much care which two initial numbers to chose you run preatty 
early into a situation where after multiplication of the two initial 
values you get a value that is already taken for a different class. Now 
I'm not so sure how much of a problem that is in the end. What I have 
done was to divide multiplierNonZeroOddNumber by 100000 in my code 
below. This way it takes much more "time" till mulitplication of the two 
initial values results in a value already used by a different class. I'm 
not so sure whether that is really good, because the range of numbers 
for multiplierNonZeroOddNumber is this way quite reduced. What I also 
don't like is the static variable initialNumbersByClass since its use 
results in loss of heap space. Sure not dramatic, but a solution without 
storing already generated values would be nice. Any ideas or any 
comments about this HashCodeBuilderUtil class would be appreciated.

Regards, Oliver



public class HashCodeBuilderUtil
{
    protected static Random random = new Random(new Date().getTime());

    protected static Map<Class<?>, List<Integer>> initialNumbersByClass

= new HashMap<Class<?>, List<Integer>>();

    public static HashCodeBuilder forClass(Class<?> theClass)
    {
        List<Integer> initialNumberPair = 
initialNumbersByClass.get(theClass);

        if (initialNumberPair == null)
        {
        initialNumberPair = getInitialNumberPair();
        initialNumbersByClass.put(theClass, initialNumberPair);
        }

        return new HashCodeBuilder(initialNumberPair.get(0), 
initialNumberPair.get(1));
    }

    public static List<Integer> getInitialNumberPair()
    {
        List<Integer> initialNumberPair = new ArrayList<Integer>(2);
        
        initialNumberPair.add(nextPrime(random.nextInt(Integer.MAX_VALUE)));
        initialNumberPair.add(nextPrime(random.nextInt(Integer.MAX_VALUE 
/ 100000)));

        return initialNumberPair;
    }

    public static int nextPrime(int n)
    {
        if (n % 2 == 0)
            ++n;
        while (!isPrime(n))
            n += 2;
        return n;
    }

    public static boolean isPrime(int n)
    {
        int r = (int) Math.sqrt(n);
        for (int d = 3; d <= r; d += 2)
        {
            if (n % d == 0)
                return false;
        }
        return true;
    }
}


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Mime
View raw message