Source for org.jfree.chart.HashUtilities

   1: /* ===========================================================
   2:  * JFreeChart : a free chart library for the Java(tm) platform
   3:  * ===========================================================
   4:  *
   5:  * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
   6:  *
   7:  * Project Info:  http://www.jfree.org/jfreechart/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it 
  10:  * under the terms of the GNU Lesser General Public License as published by 
  11:  * the Free Software Foundation; either version 2.1 of the License, or 
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but 
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  22:  * USA.  
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
  25:  * in the United States and other countries.]
  26:  *
  27:  * ------------------
  28:  * HashUtilities.java
  29:  * ------------------
  30:  * (C) Copyright 2006, 2007, by Object Refinery Limited;
  31:  *
  32:  * Original Author:  David Gilbert (for Object Refinery Limited);
  33:  * Contributor(s):   -;
  34:  *
  35:  * Changes
  36:  * -------
  37:  * 03-Oct-2006 : Version 1 (DG);
  38:  * 06-Mar-2007 : Fix for hashCodeForDoubleArray() method (DG);
  39:  * 13-Nov-2007 : Added new utility methods (DG);
  40:  * 22-Nov-2007 : Added hashCode() method for 'int' (DG);
  41:  * 05-Dec-2007 : Added special methods to handle BooleanList, PaintList,
  42:  *               and StrokeList (DG);
  43:  *
  44:  */
  45: 
  46: package org.jfree.chart;
  47: 
  48: import java.awt.GradientPaint;
  49: import java.awt.Paint;
  50: import java.awt.Stroke;
  51: 
  52: import org.jfree.util.BooleanList;
  53: import org.jfree.util.PaintList;
  54: import org.jfree.util.StrokeList;
  55: 
  56: /**
  57:  * Some utility methods for calculating hash codes.  
  58:  * 
  59:  * @since 1.0.3
  60:  */
  61: public class HashUtilities {
  62:     
  63:     /**
  64:      * Returns a hash code for a <code>Paint</code> instance.  If 
  65:      * <code>p</code> is <code>null</code>, this method returns zero.
  66:      * 
  67:      * @param p  the paint (<code>null</code> permitted).
  68:      * 
  69:      * @return The hash code.
  70:      */
  71:     public static int hashCodeForPaint(Paint p) {
  72:         if (p == null) {
  73:             return 0;
  74:         }
  75:         int result = 0;
  76:         // handle GradientPaint as a special case
  77:         if (p instanceof GradientPaint) {
  78:             GradientPaint gp = (GradientPaint) p;
  79:             result = 193;
  80:             result = 37 * result + gp.getColor1().hashCode();
  81:             result = 37 * result + gp.getPoint1().hashCode();
  82:             result = 37 * result + gp.getColor2().hashCode();
  83:             result = 37 * result + gp.getPoint2().hashCode();
  84:         }
  85:         else {
  86:             // we assume that all other Paint instances implement equals() and
  87:             // hashCode()...of course that might not be true, but what can we
  88:             // do about it?
  89:             result = p.hashCode();
  90:         }
  91:         return result;
  92:     }
  93:     
  94:     /**
  95:      * Returns a hash code for a <code>double[]</code> instance.  If the array
  96:      * is <code>null</code>, this method returns zero.
  97:      * 
  98:      * @param a  the array (<code>null</code> permitted).
  99:      * 
 100:      * @return The hash code.
 101:      */
 102:     public static int hashCodeForDoubleArray(double[] a) {
 103:         if (a == null) { 
 104:             return 0;
 105:         }
 106:         int result = 193;
 107:         long temp;
 108:         for (int i = 0; i < a.length; i++) {
 109:             temp = Double.doubleToLongBits(a[i]);
 110:             result = 29 * result + (int) (temp ^ (temp >>> 32));
 111:         }
 112:         return result;
 113:     }
 114:     
 115:     /**
 116:      * Returns a hash value based on a seed value and the value of a boolean
 117:      * primitive.
 118:      * 
 119:      * @param pre  the seed value.
 120:      * @param b  the boolean value.
 121:      * 
 122:      * @return A hash value.
 123:      * 
 124:      * @since 1.0.7
 125:      */
 126:     public static int hashCode(int pre, boolean b) {
 127:         return 37 * pre + (b ? 0 : 1);
 128:     }
 129:     
 130:     /**
 131:      * Returns a hash value based on a seed value and the value of an int
 132:      * primitive.
 133:      * 
 134:      * @param pre  the seed value.
 135:      * @param i  the int value.
 136:      * 
 137:      * @return A hash value.
 138:      * 
 139:      * @since 1.0.8
 140:      */
 141:     public static int hashCode(int pre, int i) {
 142:         return 37 * pre + i;
 143:     }
 144: 
 145:     /**
 146:      * Returns a hash value based on a seed value and the value of a double
 147:      * primitive.
 148:      * 
 149:      * @param pre  the seed value.
 150:      * @param d  the double value.
 151:      * 
 152:      * @return A hash value.
 153:      * 
 154:      * @since 1.0.7
 155:      */
 156:     public static int hashCode(int pre, double d) {
 157:         long l = Double.doubleToLongBits(d);
 158:         return 37 * pre + (int) (l ^ (l >>> 32));
 159:     }
 160:     
 161:     /**
 162:      * Returns a hash value based on a seed value and a paint instance.
 163:      * 
 164:      * @param pre  the seed value.
 165:      * @param p  the paint (<code>null</code> permitted).
 166:      * 
 167:      * @return A hash value.
 168:      * 
 169:      * @since 1.0.7
 170:      */
 171:     public static int hashCode(int pre, Paint p) {
 172:         return 37 * pre + hashCodeForPaint(p);
 173:     }
 174: 
 175:     /**
 176:      * Returns a hash value based on a seed value and a stroke instance.
 177:      * 
 178:      * @param pre  the seed value.
 179:      * @param s  the stroke (<code>null</code> permitted).
 180:      * 
 181:      * @return A hash value.
 182:      * 
 183:      * @since 1.0.7
 184:      */
 185:     public static int hashCode(int pre, Stroke s) {
 186:         int h = (s != null ? s.hashCode() : 0);
 187:         return 37 * pre + h;
 188:     }
 189: 
 190:     /**
 191:      * Returns a hash value based on a seed value and a string instance.
 192:      * 
 193:      * @param pre  the seed value.
 194:      * @param s  the string (<code>null</code> permitted).
 195:      * 
 196:      * @return A hash value.
 197:      * 
 198:      * @since 1.0.7
 199:      */
 200:     public static int hashCode(int pre, String s) {
 201:         int h = (s != null ? s.hashCode() : 0);
 202:         return 37 * pre + h;
 203:     }
 204: 
 205:     /**
 206:      * Returns a hash value based on a seed value and a <code>Comparable</code>
 207:      * instance.
 208:      * 
 209:      * @param pre  the seed value.
 210:      * @param c  the comparable (<code>null</code> permitted).
 211:      * 
 212:      * @return A hash value.
 213:      * 
 214:      * @since 1.0.7
 215:      */
 216:     public static int hashCode(int pre, Comparable c) {
 217:         int h = (c != null ? c.hashCode() : 0);
 218:         return 37 * pre + h;
 219:     }
 220: 
 221:     /**
 222:      * Returns a hash value based on a seed value and an <code>Object</code>
 223:      * instance.
 224:      * 
 225:      * @param pre  the seed value.
 226:      * @param obj  the object (<code>null</code> permitted).
 227:      * 
 228:      * @return A hash value.
 229:      * 
 230:      * @since 1.0.8
 231:      */
 232:     public static int hashCode(int pre, Object obj) {
 233:         int h = (obj != null ? obj.hashCode() : 0);
 234:         return 37 * pre + h;
 235:     }
 236:     
 237:     /**
 238:      * Computes a hash code for a {@link BooleanList}.  In the latest version
 239:      * of JCommon, the {@link BooleanList} class should implement the hashCode()
 240:      * method correctly, but we compute it here anyway so that we can work with 
 241:      * older versions of JCommon (back to 1.0.0).
 242:      * 
 243:      * @param pre  the seed value.
 244:      * @param list  the list (<code>null</code> permitted).
 245:      * 
 246:      * @return The hash code.
 247:      * 
 248:      * @since 1.0.9
 249:      */
 250:     public static int hashCode(int pre, BooleanList list) {
 251:         if (list == null) {
 252:             return pre;
 253:         }
 254:         int result = 127;
 255:         int size = list.size();
 256:         result = HashUtilities.hashCode(result, size);
 257:         
 258:         // for efficiency, we just use the first, last and middle items to
 259:         // compute a hashCode...
 260:         if (size > 0) {
 261:             result = HashUtilities.hashCode(result, list.getBoolean(0));
 262:             if (size > 1) {
 263:                 result = HashUtilities.hashCode(result, 
 264:                         list.getBoolean(size - 1));
 265:                 if (size > 2) {
 266:                     result = HashUtilities.hashCode(result, 
 267:                             list.getBoolean(size / 2));
 268:                 }
 269:             }
 270:         }
 271:         return 37 * pre + result;
 272:     }
 273: 
 274:     /**
 275:      * Computes a hash code for a {@link PaintList}.  In the latest version
 276:      * of JCommon, the {@link PaintList} class should implement the hashCode()
 277:      * method correctly, but we compute it here anyway so that we can work with 
 278:      * older versions of JCommon (back to 1.0.0).
 279:      * 
 280:      * @param pre  the seed value.
 281:      * @param list  the list (<code>null</code> permitted).
 282:      * 
 283:      * @return The hash code.
 284:      * 
 285:      * @since 1.0.9
 286:      */
 287:     public static int hashCode(int pre, PaintList list) {
 288:         if (list == null) {
 289:             return pre;
 290:         }
 291:         int result = 127;
 292:         int size = list.size();
 293:         result = HashUtilities.hashCode(result, size);
 294:         
 295:         // for efficiency, we just use the first, last and middle items to
 296:         // compute a hashCode...
 297:         if (size > 0) {
 298:             result = HashUtilities.hashCode(result, list.getPaint(0));
 299:             if (size > 1) {
 300:                 result = HashUtilities.hashCode(result, 
 301:                         list.getPaint(size - 1));
 302:                 if (size > 2) {
 303:                     result = HashUtilities.hashCode(result, 
 304:                             list.getPaint(size / 2));
 305:                 }
 306:             }
 307:         }
 308:         return 37 * pre + result;
 309:     }
 310: 
 311:     /**
 312:      * Computes a hash code for a {@link StrokeList}.  In the latest version
 313:      * of JCommon, the {@link StrokeList} class should implement the hashCode()
 314:      * method correctly, but we compute it here anyway so that we can work with 
 315:      * older versions of JCommon (back to 1.0.0).
 316:      * 
 317:      * @param pre  the seed value.
 318:      * @param list  the list (<code>null</code> permitted).
 319:      * 
 320:      * @return The hash code.
 321:      * 
 322:      * @since 1.0.9
 323:      */
 324:     public static int hashCode(int pre, StrokeList list) {
 325:         if (list == null) {
 326:             return pre;
 327:         }
 328:         int result = 127;
 329:         int size = list.size();
 330:         result = HashUtilities.hashCode(result, size);
 331:         
 332:         // for efficiency, we just use the first, last and middle items to
 333:         // compute a hashCode...
 334:         if (size > 0) {
 335:             result = HashUtilities.hashCode(result, list.getStroke(0));
 336:             if (size > 1) {
 337:                 result = HashUtilities.hashCode(result, 
 338:                         list.getStroke(size - 1));
 339:                 if (size > 2) {
 340:                     result = HashUtilities.hashCode(result, 
 341:                             list.getStroke(size / 2));
 342:                 }
 343:             }
 344:         }
 345:         return 37 * pre + result;
 346:     }
 347: }