001: /* ArraysX.java
002:
003: {{IS_NOTE
004:
005: Purpose:
006: Description:
007: History:
008: 2001/11/13, Henri Chen: Created.
009:
010: }}IS_NOTE
011:
012: Copyright (C) 2001 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.util;
020:
021: import java.lang.reflect.Array;
022:
023: /**
024: * Utilities for handling arrays.
025: *
026: * @author henrichen
027: */
028: public class ArraysX {
029: /** Converts an array to a readable string (for debugging purpose).
030: */
031: public final static String toString(Object[] array) {
032: if (array == null)
033: return "null";
034:
035: StringBuffer sb = new StringBuffer(128).append('[');
036: for (int j = 0; j < array.length; ++j) {
037: if (array[j] == array)
038: sb.append("(this array)");
039: else
040: sb.append(array[j]);
041: if (j != array.length - 1)
042: sb.append(", ");
043: }
044: return sb.append(']').toString();
045: }
046:
047: /** Converts an array of int to a readable string (for debugging purpose).
048: */
049: public final static String toString(int[] array) {
050: if (array == null)
051: return "null";
052:
053: StringBuffer sb = new StringBuffer(128).append('[');
054: for (int j = 0; j < array.length; ++j) {
055: sb.append(array[j]);
056: if (j != array.length - 1)
057: sb.append(", ");
058: }
059: return sb.append(']').toString();
060: }
061:
062: /** Converts an array of long to a readable string (for debugging purpose).
063: */
064: public final static String toString(long[] array) {
065: if (array == null)
066: return "null";
067:
068: StringBuffer sb = new StringBuffer(128).append('[');
069: for (int j = 0; j < array.length; ++j) {
070: sb.append(array[j]);
071: if (j != array.length - 1)
072: sb.append(", ");
073: }
074: return sb.append(']').toString();
075: }
076:
077: /** Converts an array of short to a readable string (for debugging purpose).
078: */
079: public final static String toString(short[] array) {
080: if (array == null)
081: return "null";
082:
083: StringBuffer sb = new StringBuffer(128).append('[');
084: for (int j = 0; j < array.length; ++j) {
085: sb.append(array[j]);
086: if (j != array.length - 1)
087: sb.append(", ");
088: }
089: return sb.append(']').toString();
090: }
091:
092: /** Converts an array of byte to a readable string (for debugging purpose).
093: */
094: public final static String toString(byte[] array) {
095: if (array == null)
096: return "null";
097:
098: StringBuffer sb = new StringBuffer(128).append('[');
099: for (int j = 0; j < array.length; ++j) {
100: sb.append(array[j]);
101: if (j != array.length - 1)
102: sb.append(", ");
103: }
104: return sb.append(']').toString();
105: }
106:
107: /** Converts an array of char to a readable string (for debugging purpose).
108: */
109: public final static String toString(char[] array) {
110: if (array == null)
111: return "null";
112:
113: StringBuffer sb = new StringBuffer(128).append('[');
114: for (int j = 0; j < array.length; ++j) {
115: sb.append(array[j]);
116: if (j != array.length - 1)
117: sb.append(", ");
118: }
119: return sb.append(']').toString();
120: }
121:
122: /** Converts an array of boolean to a readable string (for debugging purpose).
123: */
124: public final static String toString(boolean[] array) {
125: if (array == null)
126: return "null";
127:
128: StringBuffer sb = new StringBuffer(128).append('[');
129: for (int j = 0; j < array.length; ++j) {
130: sb.append(array[j]);
131: if (j != array.length - 1)
132: sb.append(", ");
133: }
134: return sb.append(']').toString();
135: }
136:
137: /** Converts an array of float to a readable string (for debugging purpose).
138: */
139: public final static String toString(float[] array) {
140: if (array == null)
141: return "null";
142:
143: StringBuffer sb = new StringBuffer(128).append('[');
144: for (int j = 0; j < array.length; ++j) {
145: sb.append(array[j]);
146: if (j != array.length - 1)
147: sb.append(", ");
148: }
149: return sb.append(']').toString();
150: }
151:
152: /** Converts an array of char to a readable string (for debugging purpose).
153: */
154: public final static String toString(double[] array) {
155: if (array == null)
156: return "null";
157:
158: StringBuffer sb = new StringBuffer(128).append('[');
159: for (int j = 0; j < array.length; ++j) {
160: sb.append(array[j]);
161: if (j != array.length - 1)
162: sb.append(", ");
163: }
164: return sb.append(']').toString();
165: }
166:
167: /**
168: * Returns the hex String representation of a byte array without prefix 0x.
169: * The String is formed by making value[0] the leftmost two digits and
170: * value[value.length-1] the rightmost two digits.
171: *
172: * @param array the byte array
173: */
174: public final static String toHexString(byte[] array) {
175: StringBuffer sb = new StringBuffer(array.length * 2 + 8);
176: char ch;
177: for (int i = 0; i < array.length; i++) {
178: // byte will be promote to integer first, mask with 0x0f is a must.
179: ch = Character.forDigit(array[i] >>> 4 & 0x0f, 16);
180: sb.append(ch);
181: ch = Character.forDigit(array[i] & 0x0f, 16);
182: sb.append(ch);
183: }
184:
185: return sb.toString();
186: }
187:
188: /**
189: * Returns the octal String representation of a byte array with optional
190: * prefix. The String is formed by making value[0] the leftmost three digits
191: * and value[value.length-1] the rightmost three digits.
192: *
193: * @param array the byte array
194: */
195: public final static String toOctalString(byte[] array, String prefix) {
196: StringBuffer sb = new StringBuffer(array.length
197: * (3 + prefix.length()) + 8);
198: if (prefix == null) {
199: for (int i = 0; i < array.length; i++) {
200: appendOctalDigits(sb, array[i]);
201: }
202: } else {
203: for (int i = 0; i < array.length; i++) {
204: sb.append(prefix);
205: appendOctalDigits(sb, array[i]);
206: }
207: }
208: return sb.toString();
209: }
210:
211: /**
212: * Returns the octal digit String buffer representation of a byte.
213: * @param byte the byte
214: */
215: private final static StringBuffer appendOctalDigits(
216: StringBuffer sb, byte b) {
217: // b will be promote to integer first, mask with 0x07 is a must.
218: return sb.append(Character.forDigit(b >>> 6 & 0x07, 8)).append(
219: Character.forDigit(b >>> 3 & 0x07, 8)).append(
220: Character.forDigit(b & 0x07, 8));
221: }
222:
223: /**
224: * Duplicates the specified array.
225: *
226: * <p>The array could be an array of objects or primiitives.
227: *
228: * @param ary the array
229: * @param jb the beginning index (included)
230: * @param je the ending index (excluded)
231: * @return an array duplicated from ary
232: * @exception IllegalArgumentException if ary is not any array
233: * @exception IndexOutOfBoundsException if out of bounds
234: */
235: public static final Object duplicate(Object ary, int jb, int je) {
236: int len = Array.getLength(ary);
237: if (jb < 0 || je > len || jb > je)
238: throw new IndexOutOfBoundsException(jb + " or " + je
239: + " exceeds " + len);
240:
241: len = je - jb;
242: Object dst = Array.newInstance(ary.getClass()
243: .getComponentType(), len);
244: System.arraycopy(ary, jb, dst, 0, len);
245: return dst;
246: }
247:
248: /**
249: * Duplicates the specified array.
250: * @param ary the array
251: * @return an array duplicated from ary
252: * @exception IllegalArgumentException if ary is not any array
253: * @exception IndexOutOfBoundsException if out of bounds
254: */
255: public static final Object duplicate(Object ary) {
256: return duplicate(ary, 0, Array.getLength(ary));
257: }
258:
259: /**
260: * Concat the two specified array.
261: *
262: * <p>The array could be an array of objects or primiitives.
263: *
264: * @param ary the array
265: * @param ary1 the array
266: * @return an array concat the ary and ary1
267: * @exception IllegalArgumentException if ary and ary1 component type are different
268: */
269: public static final Object concat(Object ary, Object ary1) {
270: int len = Array.getLength(ary) + Array.getLength(ary1);
271:
272: if (!ary.getClass().getComponentType().equals(
273: ary1.getClass().getComponentType()))
274: throw new IllegalArgumentException(
275: "These concated array component type are different.");
276: Object dst = Array.newInstance(ary.getClass()
277: .getComponentType(), len);
278:
279: System.arraycopy(ary, 0, dst, 0, Array.getLength(ary));
280: System.arraycopy(ary1, 0, dst, Array.getLength(ary), Array
281: .getLength(ary1));
282:
283: return dst;
284: }
285:
286: /**
287: * Shrink the specified array. It is similar to duplicate, except
288: * it returns the previous instance if je==length && jb==0.
289: *
290: * @param ary the array
291: * @param jb the beginning index (included)
292: * @param je the ending index (excluded)
293: * @return ary or an array duplicated from ary
294: * @exception IllegalArgumentException if ary is not any array
295: * @exception IndexOutOfBoundsException if out of bounds
296: */
297: public static final Object shrink(Object ary, int jb, int je) {
298: if (jb == 0 && je == Array.getLength(ary))
299: return ary; //nothing changed
300: return duplicate(ary, jb, je);
301: }
302:
303: /**
304: * Resizes the specified array. Similar to {@link #shrink}, but
305: * it can enlarge and it keeps elements from the first.
306: */
307: public static final Object resize(Object ary, int size) {
308: final int oldsz = Array.getLength(ary);
309: if (oldsz == size)
310: return ary;
311:
312: final Object dst = Array.newInstance(ary.getClass()
313: .getComponentType(), size);
314: System.arraycopy(ary, 0, dst, 0, oldsz > size ? size : oldsz);
315: return dst;
316: }
317:
318: /** Clones an array.
319: */
320: public static final Object clone(Object ary) {
321: final int size = Array.getLength(ary);
322: final Object dst = Array.newInstance(ary.getClass()
323: .getComponentType(), size);
324: System.arraycopy(ary, 0, dst, 0, size);
325: return dst;
326: }
327: }
|