home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java 1.2 How-To
/
JavaHowTo.iso
/
3rdParty
/
jbuilder
/
unsupported
/
JDK1.2beta3
/
SOURCE
/
SRC.ZIP
/
java
/
util
/
Arrays.java
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
UTF-8
Wrap
Java Source
|
1998-03-20
|
48.5 KB
|
1,624 lines
/*
* @(#)Arrays.java 1.17 98/03/18
*
* Copyright 1997, 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
package java.util;
/**
* This class contains various methods for manipulating arrays (such as
* sorting and searching). It also contains a static factory that allows
* arrays to be viewed as Lists.
*
* @author Josh Bloch
* @version 1.17 03/18/98
* @see Comparable
* @see Comparator
* @since JDK1.2
*/
public class Arrays {
// Sorting
/**
* Sorts the specified array of longs into ascending numerical order.
* The sorting algorithm is a tuned quicksort, adapted from Jon
* L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
* Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
* 1993). This algorithm offers n*log(n) performance on many data sets
* that cause other quicksorts to degrade to quadratic performance.
*
* @param a the array to be sorted.
*/
public static void sort(long[] a) {
sort1(a, 0, a.length);
}
/**
* Sorts the specified array of ints into ascending numerical order.
* The sorting algorithm is a tuned quicksort, adapted from Jon
* L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
* Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
* 1993). This algorithm offers n*log(n) performance on many data sets
* that cause other quicksorts to degrade to quadratic performance.
*
* @param a the array to be sorted.
*/
public static void sort(int[] a) {
sort1(a, 0, a.length);
}
/**
* Sorts the specified array of shorts into ascending numerical order.
* The sorting algorithm is a tuned quicksort, adapted from Jon
* L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
* Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
* 1993). This algorithm offers n*log(n) performance on many data sets
* that cause other quicksorts to degrade to quadratic performance.
*
* @param a the array to be sorted.
*/
public static void sort(short[] a) {
sort1(a, 0, a.length);
}
/**
* Sorts the specified array of chars into ascending numerical order.
* The sorting algorithm is a tuned quicksort, adapted from Jon
* L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
* Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
* 1993). This algorithm offers n*log(n) performance on many data sets
* that cause other quicksorts to degrade to quadratic performance.
*
* @param a the array to be sorted.
*/
public static void sort(char[] a) {
sort1(a, 0, a.length);
}
/**
* Sorts the specified array of bytes into ascending numerical order.
* The sorting algorithm is a tuned quicksort, adapted from Jon
* L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
* Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
* 1993). This algorithm offers n*log(n) performance on many data sets
* that cause other quicksorts to degrade to quadratic performance.
*
* @param a the array to be sorted.
*/
public static void sort(byte[] a) {
sort1(a, 0, a.length);
}
/**
* Sorts the specified array of doubles into ascending numerical order.
* The sorting algorithm is a tuned quicksort, adapted from Jon
* L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
* Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
* 1993). This algorithm offers n*log(n) performance on many data sets
* that cause other quicksorts to degrade to quadratic performance.
*
* @param a the array to be sorted.
*/
public static void sort(double[] a) {
sort1(a, 0, a.length);
}
/**
* Sorts the specified array of floats into ascending numerical order.
* The sorting algorithm is a tuned quicksort, adapted from Jon
* L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function",
* Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November
* 1993). This algorithm offers n*log(n) performance on many data sets
* that cause other quicksorts to degrade to quadratic performance.
*
* @param a the array to be sorted.
*/
public static void sort(float[] a) {
sort1(a, 0, a.length);
}
/*
* The code for each of the seven primitive types is identical.
* C'est la vie.
*/
/**
* Sorts the specified sub-array of longs into ascending order.
*/
private static void sort1(long x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
for (int i=off; i<len+off; i++)
for (int j=i; j>off && x[j-1]>x[j]; j--)
swap(x, j, j-1);
return;
}
// Choose a partition element, v
int m = off + len/2; // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len/8;
l = med3(x, l, l+s, l+2*s);
m = med3(x, m-s, m, m+s);
n = med3(x, n-2*s, n-s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
long v = x[m];
// Establish Invariant: v* (<v)* (>v)* v*
int a = off, b = a, c = off + len - 1, d = c;
while(true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}
// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
// Recursively sort non-partition-elements
if ((s = b-a) > 1)
sort1(x, off, s);
if ((s = d-c) > 1)
sort1(x, n-s, s);
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(long x[], int a, int b) {
long t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
*/
private static void vecswap(long x[], int a, int b, int n) {
for (int i=0; i<n; i++, a++, b++)
swap(x, a, b);
}
/**
* Returns the index of the median of the three indexed longs.
*/
private static int med3(long x[], int a, int b, int c) {
return (x[a] < x[b] ?
(x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
(x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}
/**
* Sorts the specified sub-array of integers into ascending order.
*/
private static void sort1(int x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
for (int i=off; i<len+off; i++)
for (int j=i; j>off && x[j-1]>x[j]; j--)
swap(x, j, j-1);
return;
}
// Choose a partition element, v
int m = off + len/2; // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len/8;
l = med3(x, l, l+s, l+2*s);
m = med3(x, m-s, m, m+s);
n = med3(x, n-2*s, n-s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
int v = x[m];
// Establish Invariant: v* (<v)* (>v)* v*
int a = off, b = a, c = off + len - 1, d = c;
while(true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}
// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
// Recursively sort non-partition-elements
if ((s = b-a) > 1)
sort1(x, off, s);
if ((s = d-c) > 1)
sort1(x, n-s, s);
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(int x[], int a, int b) {
int t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
*/
private static void vecswap(int x[], int a, int b, int n) {
for (int i=0; i<n; i++, a++, b++)
swap(x, a, b);
}
/**
* Returns the index of the median of the three indexed integers.
*/
private static int med3(int x[], int a, int b, int c) {
return (x[a] < x[b] ?
(x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
(x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}
/**
* Sorts the specified sub-array of shorts into ascending order.
*/
private static void sort1(short x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
for (int i=off; i<len+off; i++)
for (int j=i; j>off && x[j-1]>x[j]; j--)
swap(x, j, j-1);
return;
}
// Choose a partition element, v
int m = off + len/2; // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len/8;
l = med3(x, l, l+s, l+2*s);
m = med3(x, m-s, m, m+s);
n = med3(x, n-2*s, n-s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
short v = x[m];
// Establish Invariant: v* (<v)* (>v)* v*
int a = off, b = a, c = off + len - 1, d = c;
while(true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}
// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
// Recursively sort non-partition-elements
if ((s = b-a) > 1)
sort1(x, off, s);
if ((s = d-c) > 1)
sort1(x, n-s, s);
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(short x[], int a, int b) {
short t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
*/
private static void vecswap(short x[], int a, int b, int n) {
for (int i=0; i<n; i++, a++, b++)
swap(x, a, b);
}
/**
* Returns the index of the median of the three indexed shorts.
*/
private static int med3(short x[], int a, int b, int c) {
return (x[a] < x[b] ?
(x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
(x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}
/**
* Sorts the specified sub-array of chars into ascending order.
*/
private static void sort1(char x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
for (int i=off; i<len+off; i++)
for (int j=i; j>off && x[j-1]>x[j]; j--)
swap(x, j, j-1);
return;
}
// Choose a partition element, v
int m = off + len/2; // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len/8;
l = med3(x, l, l+s, l+2*s);
m = med3(x, m-s, m, m+s);
n = med3(x, n-2*s, n-s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
char v = x[m];
// Establish Invariant: v* (<v)* (>v)* v*
int a = off, b = a, c = off + len - 1, d = c;
while(true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}
// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
// Recursively sort non-partition-elements
if ((s = b-a) > 1)
sort1(x, off, s);
if ((s = d-c) > 1)
sort1(x, n-s, s);
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(char x[], int a, int b) {
char t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
*/
private static void vecswap(char x[], int a, int b, int n) {
for (int i=0; i<n; i++, a++, b++)
swap(x, a, b);
}
/**
* Returns the index of the median of the three indexed chars.
*/
private static int med3(char x[], int a, int b, int c) {
return (x[a] < x[b] ?
(x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
(x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}
/**
* Sorts the specified sub-array of bytes into ascending order.
*/
private static void sort1(byte x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
for (int i=off; i<len+off; i++)
for (int j=i; j>off && x[j-1]>x[j]; j--)
swap(x, j, j-1);
return;
}
// Choose a partition element, v
int m = off + len/2; // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len/8;
l = med3(x, l, l+s, l+2*s);
m = med3(x, m-s, m, m+s);
n = med3(x, n-2*s, n-s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
byte v = x[m];
// Establish Invariant: v* (<v)* (>v)* v*
int a = off, b = a, c = off + len - 1, d = c;
while(true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}
// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
// Recursively sort non-partition-elements
if ((s = b-a) > 1)
sort1(x, off, s);
if ((s = d-c) > 1)
sort1(x, n-s, s);
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(byte x[], int a, int b) {
byte t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
*/
private static void vecswap(byte x[], int a, int b, int n) {
for (int i=0; i<n; i++, a++, b++)
swap(x, a, b);
}
/**
* Returns the index of the median of the three indexed bytes.
*/
private static int med3(byte x[], int a, int b, int c) {
return (x[a] < x[b] ?
(x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
(x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}
/**
* Sorts the specified sub-array of doubles into ascending order.
*/
private static void sort1(double x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
for (int i=off; i<len+off; i++)
for (int j=i; j>off && x[j-1]>x[j]; j--)
swap(x, j, j-1);
return;
}
// Choose a partition element, v
int m = off + len/2; // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len/8;
l = med3(x, l, l+s, l+2*s);
m = med3(x, m-s, m, m+s);
n = med3(x, n-2*s, n-s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
double v = x[m];
// Establish Invariant: v* (<v)* (>v)* v*
int a = off, b = a, c = off + len - 1, d = c;
while(true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}
// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
// Recursively sort non-partition-elements
if ((s = b-a) > 1)
sort1(x, off, s);
if ((s = d-c) > 1)
sort1(x, n-s, s);
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(double x[], int a, int b) {
double t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
*/
private static void vecswap(double x[], int a, int b, int n) {
for (int i=0; i<n; i++, a++, b++)
swap(x, a, b);
}
/**
* Returns the index of the median of the three indexed doubles.
*/
private static int med3(double x[], int a, int b, int c) {
return (x[a] < x[b] ?
(x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
(x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}
/**
* Sorts the specified sub-array of floats into ascending order.
*/
private static void sort1(float x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
for (int i=off; i<len+off; i++)
for (int j=i; j>off && x[j-1]>x[j]; j--)
swap(x, j, j-1);
return;
}
// Choose a partition element, v
int m = off + len/2; // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len/8;
l = med3(x, l, l+s, l+2*s);
m = med3(x, m-s, m, m+s);
n = med3(x, n-2*s, n-s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
float v = x[m];
// Establish Invariant: v* (<v)* (>v)* v*
int a = off, b = a, c = off + len - 1, d = c;
while(true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}
// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a-off, b-a ); vecswap(x, off, b-s, s);
s = Math.min(d-c, n-d-1); vecswap(x, b, n-s, s);
// Recursively sort non-partition-elements
if ((s = b-a) > 1)
sort1(x, off, s);
if ((s = d-c) > 1)
sort1(x, n-s, s);
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(float x[], int a, int b) {
float t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
*/
private static void vecswap(float x[], int a, int b, int n) {
for (int i=0; i<n; i++, a++, b++)
swap(x, a, b);
}
/**
* Returns the index of the median of the three indexed floats.
*/
private static int med3(float x[], int a, int b, int c) {
return (x[a] < x[b] ?
(x[b] < x[c] ? b : x[a] < x[c] ? c : a) :
(x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}
/**
* Sorts the specified array of objects into ascending order, according
* to the <i>natural comparison method</i> of its elements. All
* elements in the array must implement the Comparable interface.
* Furthermore, all elements in the array must be <i>mutually
* comparable</i> (that is, e1.compareTo(e2) must not throw a
* typeMismatchException for any elements e1 and e2 in the array).
* <p>
* This sort is guaranteed to be <em>stable</em>: equal elements will
* not be reordered as a result of the sort.
* <p>
* The sorting algorithm is a modified mergesort (in which the merge is
* omitted if the highest element in the low sublist is less than the
* lowest element in the high sublist). This algorithm offers guaranteed
* n*log(n) performance, and can approach linear performance on nearly
* sorted lists.
*
* @param a the array to be sorted.
* @exception ClassCastException array contains elements that are not
* <i>mutually comparable</i> (for example, Strings and
* Integers).
* @see Comparable
*/
public static void sort(Object[] a) {
Object aux[] = (Object[])a.clone();
mergeSort(aux, a, 0, a.length);
}
private static void mergeSort(Object src[], Object dest[],
int low, int high) {
int length = high - low;
// Insertion sort on smallest arrays
if (length < 7) {
for (int i=low; i<high; i++)
for (int j=i; j>low &&
((Comparable)dest[j-1]).compareTo((Comparable)dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
// Recursively sort halves of dest into src
int mid = (low + high)/2;
mergeSort(dest, src, low, mid);
mergeSort(dest, src, mid, high);
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
if (((Comparable)src[mid-1]).compareTo((Comparable)src[mid]) <= 0) {
System.arraycopy(src, low, dest, low, length);
return;
}
// Merge sorted halves (now in src) into dest
for(int i = low, p = low, q = mid; i < high; i++) {
if (q>=high || p<mid && ((Comparable)src[p]).compareTo(src[q])<=0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
/**
* Swaps x[a] with x[b].
*/
private static void swap(Object x[], int a, int b) {
Object t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* Sorts the specified array of objects according to the order induced by
* the specified Comparator. All elements in the array must be
* <i>mutually comparable</i> by the specified comparator (that is,
* comparator.compare(e1, e2) must not throw a typeMismatchException for
* any elements e1 and e2 in the array).
* <p>
* This sort is guaranteed to be <em>stable</em>: equal elements will
* not be reordered as a result of the sort.
* <p>
* The sorting algorithm is a modified mergesort (in which the merge is
* omitted if the highest element in the low sublist is less than the
* lowest element in the high sublist). This algorithm offers guaranteed
* n*log(n) performance, and can approach linear performance on nearly
* sorted lists.
*
* @param a the array to be sorted.
* @param c the Comparator to determine the order of the array.
* @exception ClassCastException array contains elements that are not
* <i>mutually comparable</i> with the specified Comparator.
* @see Comparator
*/
public static void sort(Object[] a, Comparator c) {
Object aux[] = (Object[])a.clone();
mergeSort(aux, a, 0, a.length, c);
}
private static void mergeSort(Object src[], Object dest[],
int low, int high, Comparator c) {
int length = high - low;
// Insertion sort on smallest arrays
if (length < 7) {
for (int i=low; i<high; i++)
for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
// Recursively sort halves of dest into src
int mid = (low + high)/2;
mergeSort(dest, src, low, mid, c);
mergeSort(dest, src, mid, high, c);
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
if (c.compare(src[mid-1], src[mid]) <= 0) {
System.arraycopy(src, low, dest, low, length);
return;
}
// Merge sorted halves (now in src) into dest
for(int i = low, p = low, q = mid; i < high; i++) {
if (q>=high || p<mid && c.compare(src[p], src[q]) <= 0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
// Searching
/**
* Searches the specified array of longs for the specified value using
* the binary search algorithm. The array must <strong>must</strong> be
* sorted (as by the sort method, above) prior to making this call. If
* it is not sorted, the results are undefined: in particular, the call
* may enter an infinite loop. If the array contains multiple elements
* equal to the specified object, there is no guarantee which instance
* will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(<i>insertion point</i>) - 1). The <i>insertion
* point</i> is defined as the the point at which the value would
* be inserted into the array: the index of the first element
* greater than the value, or a.length, if all elements in
* the array are less than the specified value. Note that this
* guarantees that the return value will be >= 0 if and only
* if the object is found.
* @see #sort(long[])
*/
public static int binarySearch(long[] a, long key) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
long midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
/**
* Searches the specified array of ints for the specified value using
* the binary search algorithm. The array must <strong>must</strong> be
* sorted (as by the sort method, above) prior to making this call. If
* it is not sorted, the results are undefined: in particular, the call
* may enter an infinite loop. If the array contains multiple elements
* equal to the specified object, there is no guarantee which instance
* will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(the "insertion point") - 1).
* @see #sort(int[])
*/
public static int binarySearch(int[] a, int key) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
int midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
/**
* Searches the specified array of shorts for the specified value using
* the binary search algorithm. The array must <strong>must</strong> be
* sorted (as by the sort method, above) prior to making this call. If
* it is not sorted, the results are undefined: in particular, the call
* may enter an infinite loop. If the array contains multiple elements
* equal to the specified object, there is no guarantee which instance
* will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(the "insertion point") - 1).
* @see #sort(short[])
*/
public static int binarySearch(short[] a, short key) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
short midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
/**
* Searches the specified array of chars for the specified value using
* the binary search algorithm. The array must <strong>must</strong> be
* sorted (as by the sort method, above) prior to making this call. If
* it is not sorted, the results are undefined: in particular, the call
* may enter an infinite loop. If the array contains multiple elements
* equal to the specified object, there is no guarantee which instance
* will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(the "insertion point") - 1).
* @see #sort(char[])
*/
public static int binarySearch(char[] a, char key) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
char midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
/**
* Searches the specified array of bytes for the specified value using
* the binary search algorithm. The array must <strong>must</strong> be
* sorted (as by the sort method, above) prior to making this call. If
* it is not sorted, the results are undefined: in particular, the call
* may enter an infinite loop. If the array contains multiple elements
* equal to the specified object, there is no guarantee which instance
* will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(the "insertion point") - 1).
* @see #sort(byte[])
*/
public static int binarySearch(byte[] a, byte key) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
byte midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
/**
* Searches the specified array of doubles for the specified value using
* the binary search algorithm. The array must <strong>must</strong> be
* sorted (as by the sort method, above) prior to making this call. If
* it is not sorted, the results are undefined: in particular, the call
* may enter an infinite loop. If the array contains multiple elements
* equal to the specified object, there is no guarantee which instance
* will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(the "insertion point") - 1).
* @see #sort(double[])
*/
public static int binarySearch(double[] a, double key) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
double midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
/**
* Searches the specified array of floats for the specified value using
* the binary search algorithm. The array must <strong>must</strong> be
* sorted (as by the sort method, above) prior to making this call. If
* it is not sorted, the results are undefined: in particular, the call
* may enter an infinite loop. If the array contains multiple elements
* equal to the specified object, there is no guarantee which instance
* will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(the "insertion point") - 1).
* @see #sort(float[])
*/
public static int binarySearch(float[] a, float key) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
float midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
/**
* Searches the specified array for the specified Object using the binary
* search algorithm. The array must be sorted into ascending order
* according to the <i>natural comparison method</i> of its elements (as by
* Sort(Object[]), above) prior to making this call. The array must
* <strong>must</strong> be sorted (as by the sort method, above) prior to
* making this call. If it is not sorted, the results are undefined: in
* particular, the call may enter an infinite loop. If the array contains
* multiple elements equal to the specified object, there is no guarantee
* which instance will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(the "insertion point") - 1).
* @exception ClassCastException 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 array.
* @see Comparable
* @see #sort(Object[])
*/
public static int binarySearch(Object[] a, Object key) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
Object midVal = a[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.
}
/**
* Searches the specified array for the specified Object using the binary
* search algorithm. The array must be sorted into ascending order
* according to the specified Comparator (as by Sort(Object[], Comparator),
* above), prior to making this call. If it is not sorted, the results are
* undefined: in particular, the call may enter an infinite loop. If the
* array contains multiple elements equal to the specified object, there is
* no guarantee which instance will be found.
*
* @param a the array to be searched.
* @param key the value to be searched for.
* @param c the Comparator to determine the order of the array.
* @return index of the search key, if it is contained in the array;
* otherwise, (-(the "insertion point") - 1).
* @exception ClassCastException array contains elements that are not
* <i>mutually comparable</i> with the specified Comparator,
* or the search key in not mutually comparable with the
* elements of the array using this Comparator.
* @see Comparable
* @see #sort(Object[], Comparator)
*/
public static int binarySearch(Object[] a, Object key, Comparator c) {
int low = 0;
int high = a.length-1;
while (low <= high) {
int mid =(low + high)/2;
Object midVal = a[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.
}
// Equality Testing
/**
* Returns true if the the specified array of long is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type long[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(long[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof long[]))
return false;
long[] a2 = (long[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
/**
* Returns true if the the specified array of int is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type int[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(int[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof int[]))
return false;
int[] a2 = (int[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
/**
* Returns true if the the specified array of short is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type short[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(short[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof short[]))
return false;
short[] a2 = (short[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
/**
* Returns true if the the specified array of char is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type char[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(char[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof char[]))
return false;
char[] a2 = (char[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
/**
* Returns true if the the specified array of byte is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type byte[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(byte[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof byte[]))
return false;
byte[] a2 = (byte[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
/**
* Returns true if the the specified array of boolean is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type boolean[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(boolean[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof boolean[]))
return false;
boolean[] a2 = (boolean[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
/**
* Returns true if the the specified array of double is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type double[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(double[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof double[]))
return false;
double[] a2 = (double[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
/**
* Returns true if the the specified array of float is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type float[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(float[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof float[]))
return false;
float[] a2 = (float[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
/**
* Returns true if the the specified array of Object is <em>equal</em>
* to the given object. The array and the object are considered equal
* if the object is of type Object[], both arrays contain the same number
* of elements, and all corresponding pairs of elements in the two arrays
* are equal. In other words, the two arrays are equal if they contain the
* same elements in the same order. Also, the array is considered equal
* to the object if both are null.
*
* @param a the array to be tested for equality.
* @param o the object to be tested for equality.
* @return true if the array and the object are equal.
*/
public static boolean equals(Object[] a, Object o) {
if (a == o)
return true;
if (a==null || !(o instanceof Object[]))
return false;
Object[] a2 = (Object[])o;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++) {
Object o1 = a[i];
Object o2 = a2[i];
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return true;
}
// Filling
/**
* Sets each element of the specified array of longs with the specified
* long value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(long[] a, long val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
/**
* Sets each element of the specified array of ints with the specified
* int value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(int[] a, int val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
/**
* Sets each element of the specified array of shorts with the specified
* short value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(short[] a, short val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
/**
* Sets each element of the specified array of chars with the specified
* char value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(char[] a, char val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
/**
* Sets each element of the specified array of bytes with the specified
* byte value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(byte[] a, byte val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
/**
* Sets each element of the specified array of booleans with the specified
* boolean value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(boolean[] a, boolean val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
/**
* Sets each element of the specified array of doubles with the specified
* double value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(double[] a, double val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
/**
* Sets each element of the specified array of floats with the specified
* float value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(float[] a, float val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
/**
* Sets each element of the specified array of Objects with the specified
* Object value.
*
* @param a the array to be filled.
* @param val the value to be stored in all elements of the array.
*/
public static void fill(Object[] a, Object val) {
int length = a.length;
for (int i=0; i<length; i++)
a[i] = val;
}
// Misc
/**
* Returns a fixed-size List backed by the specified array. (Changes to
* the returned List "write through" to the array.) This method acts
* as bridge between array-based and Collection-based APIs, in
* combination with Collection.toArray.
*
* @param a the array by which the List will be backed.
* @return a List view of the specified array.
* @see Collection#toArray()
*/
public static List toList(Object[] a) {
return new ArrayList(a);
}
private static class ArrayList extends AbstractList implements Cloneable {
private Object[] a;
ArrayList(Object[] array) {
a = array;
}
public int size() {
return a.length;
}
public Object[] toArray() {
return (Object[]) a.clone();
}
public Object get(int index) {
return a[index];
}
public Object set(int index, Object element) {
Object oldValue = a[index];
a[index] = element;
return oldValue;
}
public Object clone() {
return new ArrayList(toArray());
}
}
}