Mega Code Archive

 
Categories / Java / Data Type
 

A fast way to convert character arrays into Strings

/*  * $Id: CharStringConverter.java,v 1.3 2004/07/08 08:01:45 yuvalo Exp $  *  * (C) Copyright 2002-2004 by Yuval Oren. All rights reserved.  *  *  Licensed under the Apache License, Version 2.0 (the "License");  *  you may not use this file except in compliance with the License.  *  You may obtain a copy of the License at  *  *     http://www.apache.org/licenses/LICENSE-2.0  *  *  Unless required by applicable law or agreed to in writing, software  *  distributed under the License is distributed on an "AS IS" BASIS,  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *  See the License for the specific language governing permissions and  *  limitations under the License.  */ //package  com.bluecast.util; import  java.io.*; import  java.util.*; /**  * A fast way to convert character arrays into Strings. This class maintains  * a hashtable of char[] -> String mappings. Returned Strings are guaranteed  * to be internalized.  *  * @author Yuval Oren, yuval@bluecast.com  * @version $Revision: 1.3 $  */ final public class CharStringConverter {     private static final float DEFAULT_LOAD = 0.70F;     private float loadFactor;     private int numEntries = 0;     private int maxEntries;     private int hashmask;     private char[][] keys;     private String[] values;     public CharStringConverter (int initialCapacity, float loadFactor) {         if (initialCapacity < 0) {             throw  new IllegalArgumentException("Illegal initial capacity: "                     + initialCapacity);         }         if (loadFactor < 0 || loadFactor > 1) {             throw  new IllegalArgumentException("Illegal load factor: " + loadFactor);         }         int desiredSize = (int)((float)initialCapacity/loadFactor);         int size = 16;         while (size < desiredSize) {             size <<= 1;         }         hashmask = size - 1;         maxEntries = (int)(size*loadFactor);         keys = new char[size][];         values = new String[size];         this.loadFactor = loadFactor;     }     public CharStringConverter () {         this(0, DEFAULT_LOAD);     }     public CharStringConverter (int initialCapacity) {         this(initialCapacity, DEFAULT_LOAD);     }     /**      * Returns the number of cached conversion mappings.      */     public int getCacheSize () {         return  numEntries;     }     /**      * Converts a character array into an internalized String.      */     public String convert (char[] ch) {         return  convert(ch, 0, ch.length);     }     /**      * Converts a character array into an internalized String.      *      * @param ch character array to convert      * @param start starting offset of ch[]      * @param length number of characters to read      */     public String convert (char[] ch, int start, int length) {         if (numEntries >= maxEntries) {             rehash();         }         // Look for the cached String for this char array         int offset = hashKey(ch, start, length) & hashmask;         char[] k = null;         while ((k = keys[offset]) != null && !keysAreEqual(k, 0, k.length,                 ch, start, length)) {             offset = (offset - 1) & hashmask;         }         if (k != null) {             return  values[offset];         }         else {             // Add the conversion to the cache             k = new char[length];             System.arraycopy(ch, start, k, 0, length);             String v = new String(k).intern();             keys[offset] = k;             values[offset] = v;             numEntries++;             return  v;         }     }     private void rehash () {         int newlength = keys.length << 1;         char[][] newkeys = new char[newlength][];         String[] newvalues = new String[newlength];         int newhashmask = newlength - 1;         for (int i = 0; i < keys.length; i++) {             char[] k = keys[i];             String v = values[i];             if (k != null) {                 int newoffset = hashKey(k, 0, k.length) & newhashmask;                 char[] newk = null;                 while ((newk = newkeys[newoffset]) != null && !keysAreEqual(newk,                         0, newk.length, k, 0, k.length)) {                     newoffset = (newoffset - 1) & newhashmask;                 }                 newkeys[newoffset] = k;                 newvalues[newoffset] = v;             }         }         keys = newkeys;         values = newvalues;         maxEntries = (int)(newlength*loadFactor);         hashmask = newhashmask;     }     public void clearCache () {         for (int i = 0; i < keys.length; i++) {             keys[i] = null;             values[i] = null;         }         numEntries = 0;     }     private static final boolean keysAreEqual (char[] a, int astart, int alength,             char[] b, int bstart, int blength) {         if (alength != blength) {             return  false;         }         else {             for (int i = 0; i < alength; i++) {                 if (a[astart + i] != b[bstart + i]) {                     return  false;                 }             }             return  true;         }     }     private static final int hashKey (char ch[], int start, int length) {         int hash = 0;         for (int i = 0; i < length; i++) {             hash = (hash << 5) + ch[start + i];         }         return  hash;     } }