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; } }