写java代码的时候。有时候需要打印输出一下二维数组。Arrays中只用一维数据的toString方法。只好循环输出。在控制台打印了一片。
乱糟糟,看着头疼。不禁想到了数据库控制台输出的表是那么的整齐。要是这个二维数组也能那么显示就好了。于是费了点力气写出了一个类初步可以想数据库控制台那样显示了;代码草草写成。还有许多不完备的地方。一般的二维数据显示没问题。
为了像数据库控制台那样有表头有数据。类中也设置了可选使用一个一维数组作为二维数组的表头。
代码如下:
/**
* 二维数组格式化显示工具
*
* @author Administrator
*
*/
public class Array {
/**
* 分隔符字符串用来分割表头用的
*/
private static final String DELIMITER = "--------";
/**
* 私有构造器。不实例化对象。
*/
private Array() {
}
/**
* 在控制台打印格式化后的二维数组
*
* @param arr
* 要打印的输出的数组对象
*/
public static void print(final Object[][] arr) {
print(null, arr);
}
/**
* 在控制台打印加上表头后格式化的二维数组
*
* @param thead
* 自定义表头
* @param tbody
* 二维数组
*/
public static void print(final Object[] thead, final Object[][] tbody) {
System.out.println(toString(thead, tbody));
}
/**
* 将一个二维数组格式化后转换成字符串,方便打印输出
*
* @param arr
* 二维数组对象
* @return 格式化后的字符串
*/
public static String toString(final Object[][] arr) {
return toString(null, arr);
}
/**
* 添加表头后格式化
*
* @param thead
* 自定义表头
* @param tbody
* 二维数组
* @return 格式化的字符串
*/
public static String toString(final Object[] thead, final Object[][] tbody) {
StringBuilder sb = new StringBuilder();
int[][] tdSize;
if (thead == null && tbody == null) {// 全空
return "";
}
if (thead == null && tbody != null) {// 只有tbody
tdSize = new int[tbody.length + 1][];
for (int i = 0; i < tbody.length; i++) {// 长度计算
setTdSize(tdSize, i + 1, tbody[i]);
}
for (int i = 0; i < tbody.length; i++) {// 字符转换
append(sb, tdSize, i + 1, tbody[i]);
}
return sb.toString();
}
if (thead != null && tbody == null) {// 只有thead
tdSize = new int[2][];
setTdSize(tdSize, 1, thead);// 长度计算
append(sb, tdSize, 1, thead);// 字符转换
append(sb, tdSize[0], DELIMITER);
return sb.toString();
}
if (thead != null && tbody != null) {// 全不为空
tdSize = new int[tbody.length + 2][];
setTdSize(tdSize, 1, thead);// 长度计算
for (int i = 0; i < tbody.length; i++) {
setTdSize(tdSize, i + 2, tbody[i]);// 长度计算
}
append(sb, tdSize, 1, thead);// 字符转换
append(sb, tdSize[0], DELIMITER);
for (int i = 0; i < tbody.length; i++) {// 字符转换
append(sb, tdSize, i + 2, tbody[i]);
}
return sb.toString();
}
return "";
}
/**
* 添加制定长度的str。用来做表头的分隔符
*
* @param sb
* 字符串存放对象
* @param is
* 制表位个数数组
* @param str
* 分隔符字符串
*/
private static void append(StringBuilder sb, int[] is, String str) {
if (is == null || is.length < 1) {
sb.append(str);
}
for (int i = 0; i < is.length; i++) {
for (int j = 0; j < is[i]; j++) {
sb.append(str);
}
}
sb.append("\n");
}
/**
* 将obj【】数组格式化为字符串
*
* @param sb
* 结果存放对象
* @param tdSize
* 制表位控制
* @param index
* 制表位位置
* @param obj
* 要格式化的数组
*/
private static void append(StringBuilder sb, int[][] tdSize, int index,
Object[] obj) {
if (obj != null && obj.length > 0) {
for (int i = 0; i < obj.length; i++) {
if (obj[i] == null) {
sb.append("\t");
} else {
String s = obj[i].toString();
if (s == null) {
sb.append("\t");
} else {
sb.append(s);
sb.append("\t");
}
}
for (int j = 0; j < tdSize[0][i] - tdSize[index][i]; j++) {
sb.append("\t");
}
}
}
sb.append("\n");
}
/**
* 获取一维数组中每个元素的占用制表位个数
*
* @param tdSize
* 所有结果存放的对象
* @param index
* 结果存放的位置
* @param arr
* 要计算的数组
*/
private static void setTdSize(int[][] tdSize, int index, Object[] arr) {
int[] arrSize;
if (arr == null || arr.length < 1) {
arrSize = new int[1];
arrSize[0] = 0;
tdSize[index] = arrSize;
return;
}
arrSize = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
arrSize[i] = getTableLength(arr[i]);
}
tdSize[index] = arrSize;
if (tdSize[0] == null) {
int[] ts = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
ts[i] = arrSize[i];
}
tdSize[0] = ts;
return;
}
if (tdSize[0].length < arr.length) {// 原数据长度短时
int[] ts = new int[arr.length];
for (int i = 0; i < tdSize[0].length; i++) {
if (tdSize[0][i] > arrSize[i]) {
ts[i] = tdSize[0][i];
} else {
ts[i] = arrSize[i];
}
}
for (int i = tdSize[0].length; i < ts.length; i++) {
ts[i] = arrSize[i];
}
tdSize[0] = ts;
return;
}
for (int i = 0; i < arr.length; i++) {// 原数组长度不小于时
if (tdSize[0][i] > arrSize[i]) {
tdSize[0][i] = tdSize[0][i];
} else {
tdSize[0][i] = arrSize[i];
}
}
}
/**
* 数据(data)在加上\t后占用的制表位个数<br>
* 这里只是简单计算了一下。一般没问题。显示错位时在这里修改
*
* @param data
* 数据
* @return 占用制表位的个数
*/
private static int getTableLength(final Object obj) {
if (obj == null) {
return 1;
}
String data = obj.toString();
if (data == null || data.length() < 1) {
return 1;
}
int TL = 0;
int en = 0;// 英文字符个数
int zh = 0;// 中文字符个数
for (int i = 0; i < data.length(); i++) {
char ch = data.charAt(i);
if (ch < 128) {
en++;
} else {
zh++;
}
}
TL = (en / 8);// 8个英文字符占一个表位
TL += zh / 6;// 6个中文字符占一个表位
int den = en % 8;
int dzh = zh % 6;
switch (dzh) {
case 0:
TL++;
break;
case 1:
if (den > 6) {
TL += 2;
} else {
TL++;
}
break;
case 2:
if (den > 5) {
TL += 2;
} else {
TL++;
}
break;
case 3:
if (den > 3) {
TL += 2;
} else {
TL++;
}
break;
case 4:
if (den > 2) {
TL += 2;
} else {
TL++;
}
break;
case 5:
if (den > 1) {
TL += 2;
} else {
TL++;
}
break;
}
return TL;
}
}