/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.editor; import java.util.Comparator; /** * Utilities over object array. * * @author Miloslav Metelka * @version 1.00 */ public class ObjectArrayUtilities { private ObjectArrayUtilities() { // no instances } /** * Searches the specified object array for the specified object using the binary * search algorithm. The object array must be sorted into ascending order * according to the <i>natural ordering</i> of its items. If it is * not sorted, the results are undefined. If the object array contains multiple * elements equal to the specified object, there is no guarantee which one * will be found. * <BR>This method runs in log(n) time. * @param objectArray object array to be searched. * @param key the key to be searched for. * @return index of the search key, if it is contained in the object array; * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The * <i>insertion point</i> is defined as the point at which the * key would be inserted into the object array: the index of the first * element greater than the key, or <tt>objectArray.getItemCount()</tt>, if all * elements in the object array are less than the specified key. Note * that this guarantees that the return value will be >= 0 if * and only if the key is found. * @throws ClassCastException if the object array contains elements that are not * <i>mutually comparable</i> (for example, strings and * integers), or the search key in not mutually comparable * with the elements of the object array. * @see Comparable */ public static int binarySearch(ObjectArray objectArray, Object key) { int low = 0; int high = objectArray.getItemCount() - 1; while (low <= high) { int mid = (low + high) >> 1; Object midVal = objectArray.getItem(mid); int cmp = ((Comparable)midVal).compareTo(key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found } /** * Perform binary search with the specified comparator. The more detailed * description is given in the doc for {@link #binarySearch(ObjectArray, Object)}. * @param objectArray object array to be searched. * @param key key to search for. * @param c comparator to be used to compare the items. * @return index of the search key, if it is contained in the object array; * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. * @see binarySearch(ObjectArray, Object) */ public static int binarySearch(ObjectArray objectArray, Object key, Comparator c) { int low = 0; int high = objectArray.getItemCount() - 1; while (low <= high) { int mid = (low + high) >> 1; Object midVal = objectArray.getItem(mid); int cmp = c.compare(midVal, key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found } /** * Get index of the occurrence of the given item in the object array * by using binary search and scanning the adjacent items * that are equal copmared to the searched item. * @param objectArray object array containing the item. * @param item object to be found. * @return index of the found object. The object must be the same physical * instance as the search item. * <BR>For multiple occurrences of the item in the object array * a random occurrence is returned. * <BR>If the object is not found in the objectArray then * this method returns -1. */ public static int findIndex(ObjectArray objectArray, Object item) { int index = binarySearch(objectArray, item); if (index < 0) { // nothing equal to item found return -1; } if (objectArray.getItem(index) == item) { return index; } int cnt = objectArray.getItemCount(); for (int upIndex = index + 1; upIndex < cnt; upIndex++) { Object indexItem = objectArray.getItem(upIndex); if (indexItem == item) { return upIndex; } if (((Comparable)item).compareTo(indexItem) != 0) { break; } } while (--index >= 0) { Object indexItem = objectArray.getItem(index); if (indexItem == item) { return index; } if (((Comparable)item).compareTo(indexItem) != 0) { break; } } return -1; } /** * Get index of the occurrence of the given item in the object array * by using binary search and scanning the adjacent items * that are equal copmared to the searched item. * @param objectArray object array containing the item. * @param item object to be found. * @param c comparator to use to compare the items. * @return index of the found object. The object must be the same physical * instance as the search item. * <BR>For multiple occurrences of the item in the object array * a random occurrence is returned. * <BR>If the object is not found in the objectArray then * this method returns -1. */ public static int findIndex(ObjectArray objectArray, Object item, Comparator c) { int index = binarySearch(objectArray, item, c); if (index < 0) { // nothing equal to item found return -1; } if (objectArray.getItem(index) == item) { return index; } int cnt = objectArray.getItemCount(); for (int upIndex = index + 1; upIndex < cnt; upIndex++) { Object indexItem = objectArray.getItem(upIndex); if (indexItem == item) { return upIndex; } if (c.compare(item, indexItem) != 0) { break; } } while (--index >= 0) { Object indexItem = objectArray.getItem(index); if (indexItem == item) { return index; } if (c.compare(item, indexItem) != 0) { break; } } return -1; } /** * Create array and fill it with all the items from the given objectArray. * @param objectArray objectArray containing items to copy. * @return array containing all the items from the given objectArray. */ public static Object[] toArray(ObjectArray objectArray) { return toArray(objectArray, 0, objectArray.getItemCount()); } /** * Create array and fill it with the items from the given objectArray. * @param objectArray objectArray containing items to copy. * @param startIndex index of the first item to copy. * @param endIndex index that follows the last item to copy. * @return array containing the requested items from the given objectArray. */ public static Object[] toArray(ObjectArray objectArray, int startIndex, int endIndex) { Object[] dest = new Object[endIndex - startIndex]; copyItems(objectArray, startIndex, endIndex, dest, 0); return dest; } /** * Copy items from the given object array into destination array. * @param srcObjectArray objectArray containing items to copy. * @param srcStartIndex index of the first item in the objectArray to copy. * @param srcEndIndex index that follows the last item in the objectArray to copy. * @param dest array into which the items will be copied. * @param destIndex index in the destination array at which the placing * of the copied items will be started. */ public static void copyItems(ObjectArray srcObjectArray, int srcStartIndex, int srcEndIndex, Object[] dest, int destIndex) { if (srcObjectArray instanceof ObjectArray.CopyItems) { ((ObjectArray.CopyItems)srcObjectArray).copyItems( srcStartIndex, srcEndIndex, dest, destIndex); } else { while (srcStartIndex < srcEndIndex) { dest[destIndex++] = srcObjectArray.getItem(srcStartIndex++); } } } /** * Utility method to reverse order of the elements in the given array. * @param array array to be reversed. */ public static void reverse(Object[] array) { for (int i = 0, j = array.length - 1; i < j; i++, j--) { Object o = array[i]; array[i] = array[j]; array[j] = o; } } }