001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
006     *
007     * Project Info:  http://www.jfree.org/jfreechart/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it 
010     * under the terms of the GNU Lesser General Public License as published by 
011     * the Free Software Foundation; either version 2.1 of the License, or 
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but 
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022     * USA.  
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025     * in the United States and other countries.]
026     *
027     * ------------------
028     * HashUtilities.java
029     * ------------------
030     * (C) Copyright 2006, 2007, by Object Refinery Limited;
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   -;
034     *
035     * Changes
036     * -------
037     * 03-Oct-2006 : Version 1 (DG);
038     * 06-Mar-2007 : Fix for hashCodeForDoubleArray() method (DG);
039     * 13-Nov-2007 : Added new utility methods (DG);
040     * 22-Nov-2007 : Added hashCode() method for 'int' (DG);
041     *
042     */
043    
044    package org.jfree.chart;
045    
046    import java.awt.GradientPaint;
047    import java.awt.Paint;
048    import java.awt.Stroke;
049    
050    /**
051     * Some utility methods for calculating hash codes.  
052     * 
053     * @since 1.0.3
054     */
055    public class HashUtilities {
056        
057        /**
058         * Returns a hash code for a <code>Paint</code> instance.  If 
059         * <code>p</code> is <code>null</code>, this method returns zero.
060         * 
061         * @param p  the paint (<code>null</code> permitted).
062         * 
063         * @return The hash code.
064         */
065        public static int hashCodeForPaint(Paint p) {
066            if (p == null) {
067                return 0;
068            }
069            int result = 0;
070            // handle GradientPaint as a special case
071            if (p instanceof GradientPaint) {
072                GradientPaint gp = (GradientPaint) p;
073                result = 193;
074                result = 37 * result + gp.getColor1().hashCode();
075                result = 37 * result + gp.getPoint1().hashCode();
076                result = 37 * result + gp.getColor2().hashCode();
077                result = 37 * result + gp.getPoint2().hashCode();
078            }
079            else {
080                // we assume that all other Paint instances implement equals() and
081                // hashCode()...of course that might not be true, but what can we
082                // do about it?
083                result = p.hashCode();
084            }
085            return result;
086        }
087        
088        /**
089         * Returns a hash code for a <code>double[]</code> instance.  If the array
090         * is <code>null</code>, this method returns zero.
091         * 
092         * @param a  the array (<code>null</code> permitted).
093         * 
094         * @return The hash code.
095         */
096        public static int hashCodeForDoubleArray(double[] a) {
097            if (a == null) { 
098                return 0;
099            }
100            int result = 193;
101            long temp;
102            for (int i = 0; i < a.length; i++) {
103                temp = Double.doubleToLongBits(a[i]);
104                result = 29 * result + (int) (temp ^ (temp >>> 32));
105            }
106            return result;
107        }
108        
109        /**
110         * Returns a hash value based on a seed value and the value of a boolean
111         * primitive.
112         * 
113         * @param pre  the seed value.
114         * @param b  the boolean value.
115         * 
116         * @return A hash value.
117         * 
118         * @since 1.0.7
119         */
120        public static int hashCode(int pre, boolean b) {
121            return 37 * pre + (b ? 0 : 1);
122        }
123        
124        /**
125         * Returns a hash value based on a seed value and the value of an int
126         * primitive.
127         * 
128         * @param pre  the seed value.
129         * @param i  the int value.
130         * 
131         * @return A hash value.
132         * 
133         * @since 1.0.8
134         */
135        public static int hashCode(int pre, int i) {
136            return 37 * pre + i;
137        }
138    
139        /**
140         * Returns a hash value based on a seed value and the value of a double
141         * primitive.
142         * 
143         * @param pre  the seed value.
144         * @param d  the double value.
145         * 
146         * @return A hash value.
147         * 
148         * @since 1.0.7
149         */
150        public static int hashCode(int pre, double d) {
151            long l = Double.doubleToLongBits(d);
152            return 37 * pre + (int) (l ^ (l >>> 32));
153        }
154        
155        /**
156         * Returns a hash value based on a seed value and a paint instance.
157         * 
158         * @param pre  the seed value.
159         * @param p  the paint (<code>null</code> permitted).
160         * 
161         * @return A hash value.
162         * 
163         * @since 1.0.7
164         */
165        public static int hashCode(int pre, Paint p) {
166            return 37 * pre + hashCodeForPaint(p);
167        }
168    
169        /**
170         * Returns a hash value based on a seed value and a stroke instance.
171         * 
172         * @param pre  the seed value.
173         * @param s  the stroke (<code>null</code> permitted).
174         * 
175         * @return A hash value.
176         * 
177         * @since 1.0.7
178         */
179        public static int hashCode(int pre, Stroke s) {
180            int h = (s != null ? s.hashCode() : 0);
181            return 37 * pre + h;
182        }
183    
184        /**
185         * Returns a hash value based on a seed value and a string instance.
186         * 
187         * @param pre  the seed value.
188         * @param s  the string (<code>null</code> permitted).
189         * 
190         * @return A hash value.
191         * 
192         * @since 1.0.7
193         */
194        public static int hashCode(int pre, String s) {
195            int h = (s != null ? s.hashCode() : 0);
196            return 37 * pre + h;
197        }
198    
199        /**
200         * Returns a hash value based on a seed value and a <code>Comparable</code>
201         * instance.
202         * 
203         * @param pre  the seed value.
204         * @param c  the comparable (<code>null</code> permitted).
205         * 
206         * @return A hash value.
207         * 
208         * @since 1.0.7
209         */
210        public static int hashCode(int pre, Comparable c) {
211            int h = (c != null ? c.hashCode() : 0);
212            return 37 * pre + h;
213        }
214    
215        /**
216         * Returns a hash value based on a seed value and an <code>Object</code>
217         * instance.
218         * 
219         * @param pre  the seed value.
220         * @param obj  the object (<code>null</code> permitted).
221         * 
222         * @return A hash value.
223         * 
224         * @since 1.0.8
225         */
226        public static int hashCode(int pre, Object obj) {
227            int h = (obj != null ? obj.hashCode() : 0);
228            return 37 * pre + h;
229        }
230    
231    }