/* * Sort.java * * Brazil project web application toolkit, * export version: 2.3 * Copyright (c) 1999-2009 Sun Microsystems, Inc. * * 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 included as the file "license.terms", * and also available at http://www.sun.com/ * * The Original Code is from: * Brazil project web application toolkit release 2.3. * The Initial Developer of the Original Code is: suhler. * Portions created by suhler are Copyright (C) Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): cstevens, suhler. * * Version: 2.3 * Created by suhler on 99/08/05 * Last modified by suhler on 09/01/30 16:19:45 * * Version Histories: * * 2.3 09/01/30-16:19:45 (suhler) * doh! * * 2.2 04/11/30-14:59:57 (suhler) * fixed sccs version string * * 2.1 02/10/01-16:36:57 (suhler) * version change * * 1.6 02/07/24-10:49:38 (suhler) * doc updates * * 1.5 99/10/14-12:57:25 (cstevens) * Documentation for Sort.Compare. * * 1.4 99/08/27-13:15:58 (cstevens) * Merged changes between child workspace "/home/cstevens/ws/brazil/naws" and * parent workspace "/export/ws/brazil/naws". * * 1.2.1.1 99/08/27-12:31:11 (cstevens) * check the common case first * * 1.3 99/08/12-16:00:29 (suhler) * type * * 1.2 99/08/10-16:17:28 (cstevens) * sort arrays of things. * * 1.2 99/08/05-17:03:08 (Codemgr) * SunPro Code Manager data about conflicts, renames, etc... * Name history : 1 0 util/Sort.java * * 1.1 99/08/05-17:03:07 (suhler) * date and time created 99/08/05 17:03:07 by suhler * */ package sunlabs.brazil.util; import java.util.Vector; import java.lang.reflect.Array; /** * Placeholder for useful sorting utilities. * Currently, sorting arrays and Vectors using the qsort algorithm * are preovided. * * @author Stephen Uhler (stephen.uhler@sun.com) * @author Colin Stevens (colin.stevens@sun.com) * @version 2.3 */ public class Sort { private Sort() {} /** * Sort a vector of strings using the Qsort algorithm. * The compareTo method of the String class is used for comparison. */ public static void qsort(Vector strings) { qsort(strings,0,strings.size()-1); } private static void qsort(Vector A, int p, int r) { while (p < r) { int q = partition(A, p, r); qsort(A,p,q); p = q + 1; } } private static int partition (Vector A, int p, int r) { int z = (r+p)/2; String x = A.elementAt(z).toString(); int i = p - 1; int j = r + 1; while (true) { while (x.compareTo(A.elementAt(--j).toString()) < 0); while (x.compareTo(A.elementAt(++i).toString()) > 0); if (i >= j) { return j; } Object o = A.elementAt(i); A.setElementAt(A.elementAt(j),i); A.setElementAt(o,j); } } /** * This interface is used by the Sort class to compare * elements when an array is being sorted. * * @author Colin Stevens (colin.stevens@sun.com) * @version 2.3, 09/01/30 */ public interface Compare { /** * Compare two elements in the given array. The implementor must * know what the actual type of the array is and cast it to that * type in order to do the comparison. * * @param array * Array being sorted. * * @param index1 * The index in the given array of the first element to * compare. * * @param index2 * The index in the given array of the second element to * compare. * * @return The implementation must return a number less than, * equal to, or greater than zero to indicate whether * the array element at index1 should be * considered less than, equal to, or greater than the * array element at index2. */ int compare(Object array, int index1, int index2); } /** * Sorts an array of the basic types (ints, floats, bytes, etc.) or * Strings. The sort is in increasing order, and is case-sensitive * for strings. Sorting an array of booleans or an array of objects * other than Strings is not supported. * * @param array * The array to sort in place. * * @throws IllegalArgumentException * if array is not an array of the types listed * above. */ public static void qsort(Object array) throws IllegalArgumentException { qsort(array, new StandardCompare(array)); } /** * Sorts an array. The specified comparator is used to control the * sorting order. Arrays of any type may be sorted, depending upon * what the comparator accepts. * * @param array * The array to sort in place. * * @param compare * The comparator for sort order. * * @throws IllegalArgumentException * if array is not an array. */ public static void qsort(Object array, Compare compare) throws IllegalArgumentException { qsort(array, 0, Array.getLength(array) - 1, compare); } private static void qsort(Object A, int p, int r, Compare compare) { while (p < r) { int q = partition(A, p, r, compare); qsort(A, p, q, compare); p = q + 1; } } private static int partition(Object A, int p, int r, Compare compare) { int z = (r+p)/2; int i = p - 1; int j = r + 1; while (true) { while (compare.compare(A, z, --j) < 0) { /* do nothing. */ } while (compare.compare(A, z, ++i) > 0) { /* do nothing. */ } if (i >= j) { return j; } Object o = Array.get(A, i); Array.set(A, i, Array.get(A, j)); Array.set(A, j, o); if (z == i) { z = j; } else if (z == j) { z = i; } } } private static final class StandardCompare implements Sort.Compare { /* * Keep the two expected cases near the front. */ private static final int STRING = 0; private static final int INT = 1; private static final int BYTE = 2; private static final int CHAR = 3; private static final int SHORT = 4; private static final int LONG = 5; private static final int FLOAT = 6; private static final int DOUBLE = 7; int type; StandardCompare(Object array) throws IllegalArgumentException { if (array.getClass().isArray() == false) { /* * Let the qsort routine throw the "not an array exception". */ return; } else if (array instanceof String[]) { type = STRING; } else if (array instanceof int[]) { type = INT; } else if (array instanceof byte[]) { type = BYTE; } else if (array instanceof char[]) { type = CHAR; } else if (array instanceof short[]) { type = SHORT; } else if (array instanceof long[]) { type = LONG; } else if (array instanceof float[]) { type = FLOAT; } else if (array instanceof double[]) { type = DOUBLE; } else { throw new IllegalArgumentException("cannot sort array of" + array.getClass().getComponentType().getName()); } } public int compare(Object array, int index1, int index2) { switch (type) { case STRING: { String[] a = (String[]) array; String str1 = a[index1]; String str2 = a[index2]; return str1.compareTo(str2); } case INT: { int[] a = (int[]) array; int i1 = a[index1]; int i2 = a[index2]; return i1 - i2; } case BYTE: { byte[] a = (byte[]) array; byte b1 = a[index1]; byte b2 = a[index2]; return b1 - b2; } case CHAR: { char[] a = (char[]) array; char c1 = a[index1]; char c2 = a[index2]; return c1 - c2; } case SHORT: { short[] a = (short[]) array; short s1 = a[index1]; short s2 = a[index2]; return s1 - s2; } case LONG: { long[] a = (long[]) array; long l1 = a[index1]; long l2 = a[index2]; if (l1 > l2) { return 1; } else if (l1 == l2) { return 0; } else { return -1; } } case FLOAT: { float[] a = (float[]) array; float f1 = a[index1]; float f2 = a[index2]; if (f1 > f2) { return 1; } else if (f1 == f2) { return 0; } else { return -1; } } case DOUBLE: { double[] a = (double[]) array; double d1 = a[index1]; double d2 = a[index2]; if (d1 > d2) { return 1; } else if (d1 == d2) { return 0; } else { return -1; } } } return 0; } } }