再谈谈java 数组

来源:互联网 发布:软件设计师下午试题 编辑:程序博客网 时间:2024/06/05 06:44
之所以写一篇专门的文章来说明这个java中的数组,是因为我对此并不熟悉,所以我要系统的来梳理下我所学到的,并在此基础
上进行深入一点的研究.好吧,闲话少说!
首先还是从最基础的讲起.
1,定义:
  String这个类最常用不过了,基本上你写的每个类都有它的身影.但是我们看它的源代码就知道其实这个类只是基于char[]
  的操作的封装而已.之所以说这个我是想说数组对于java很好很重要.
  从很多书上都讲了关于数组的定义和初始化.
  int[] a; //定义一个int型数组
  String[] arrStr = new String[3]; //定义了一个字符串数组,长度为3,每个元素为null
  也就是说这句运行完了后 arrStr[0] = null, arrStr[2] = null, 如果你写了句 String a = arrStr[3];那么你会获得一个
  "java.lang.ArrayIndexOutOfBoundsException: 3  "异常.

2,初始化:
  先看例子:
  String[] arrStr = new String[3];
  for (int i=0; i<arrStr.length; i++)
    arrStr[i] = "hello";
  其实定义和初始化可以放在一句里面.
  int[] a = new int[]{1,2,4};
  String[] strs = new String[]{"hello","world","everyone"}; //或者直接String[] strs = {"abc","efg","hij","hh"};
  但是看这里的函数
  public String[] getArrays() {
    return {"hello","world"};
  }

  有问题,如果你在eclipse里面写的该代码,你肯定知道,因为编辑器知道错了,你得改正.如果是记事本或editplus就必须要编译
  的时候才知道了.
  编译的时候会抛出下面的异常
  LotteryDrawing.java:7: illegal start of expression
        return {"hello","world"};
               ^
  1 error
  必须改为 return new String[]{"hello","world"};  //注意这里的[]中一定不要填上2或者别的数字
  原因???
  今天 和何同事讨论下,他说是返回的时候并不知道 {"hello","world"}是什么类型的,
  而定义的时候是明确指定的左边的类型的String[] strs = {"abc","efg","hij","hh"};
  -------------------------------------------------------------------------------------------

3,动态数组:
  在实际编码过程中,我们要返回一个数组类型,但是函数逻辑是不确定该数组到底有多长,这种情况你是怎么做的呢?
  我是这样解决的:
  1.     public static String[] getMatch(String str, String regex) {
  2.         if (str == null || str.length() == 0)
  3.             return null;
  4.         if (regex == null || regex.length() == 0)
  5.             return new String[]{str};
  6.         
  7.         ArrayList list = new ArrayList();
  8.         
  9.         Pattern p = Pattern.compile(regex);
  10.         Matcher m = p.matcher(str);
  11.         while(m.find()) {
  12.             String s = m.group();
  13.             list.add(s);
  14.         }
  15.         String[] a= new String[list.size()];
  16.         list.toArray(a);
  17.         return a;
  18.     }

  这段代码的意思是返回字符串str中符合正则表达式regex的子串数组


4,操作:
  说到操作数组的利器莫过于Arrays这个类了.
  二分搜索法binarySearch函数,填充fill函数,升序排序sort函数,另外java5 中新增加一个工具函数toString(T []);这个函数对于
  我们写测试代码很有用,把一个数组转换成字符串[a,b,c].
  如果使用java.1.4的朋友可以看下1.5的代码自己写个工具类来打印数组了,不用老是写个循环来打印了,注意1.4是没有StringBuilder
  这个类的,使用StringBuffer来代替即可
/**********************************************************************************/
  1. public static String toString(Object[] a) {
  2.     if (a == null)
  3.         return "null";
  4.     if (a.length == 0)
  5.         return "[]";
  6.     StringBuilder buf = new StringBuilder();
  7.     for (int i = 0; i < a.length; i++) {
  8.         if (i == 0)
  9.             buf.append('[');
  10.         else
  11.             buf.append(", ");
  12.         buf.append(String.valueOf(a[i]));
  13.     }
  14.     buf.append("]");
  15.     return buf.toString();
  16. }

/***********************************比较*******************************************/
  1. public static String toString(int[] a) {
  2.     if (a == null)
  3.         return "null";
  4.     if (a.length == 0)
  5.         return "[]";
  6.     StringBuilder buf = new StringBuilder();
  7.     buf.append('[');
  8.     buf.append(a[0]);
  9.     for (int i = 1; i < a.length; i++) {
  10.         buf.append(", ");
  11.         buf.append(a[i]);
  12.     }
  13.     buf.append("]");
  14.     return buf.toString();
  15. }


/**********************************************************************************/
上面两段代码很有意思,你可以看看他们是如何处理最后一个","的问题的.
我在没有看源代码之前是这样写的:
  1. public static String toString(int[] a) {
  2.     if (a == null)
  3.         return "null";
  4.     if (a.length == 0)
  5.         return "[]";
  6.     StringBuffer buf = new StringBuffer();
  7.     buf.append('[');
  8.     for (int i = 0; i < a.length; i++) {
  9.         buf.append(a[i]);
  10.         buf.append(", "); //有两个字符
  11.     }
  12.     int len = buf.length();
  13.     if (len > 1){
  14.         buf.delete(len-2,len);
  15.         //上面一行可以用这两句来替代 buf.deleteCharAt(len-2);  buf.deleteCharAt(len-1);
  16.     }
  17.     buf.append("]");
  18.     return buf.toString();
  19. }


  比较以上三种代码,窃以为算toString(Object[] obj)最差,因为每个循环里面都作了判断,但是我写的代码中多了个delete函数
  不论是delete还是 deleteCharAt,里面都进行了数组的拷贝(查看源代码知道的),无疑也是落了下乘.最好的代码莫过于
  toString(int[] a)了,或者说这种循环的思想最perfect.值得学习!!!


5,数组拷贝
请尽量使用System.arraycopy()函数,特别是大的数组,方便高效,从下面的程序可以看出
  1. class AtoS{
  2. public void copy1(String[] src) {
  3.     String[] d = new String[src.length];
  4.     int len = src.length;
  5.     for (int i=0; i<len; i++){
  6.         d[i] = src[i];
  7.     }
  8.     //System.out.println(toString(d));
  9. }
  10. public void copy2(String[]src) {
  11.     String[] d = new String[src.length];
  12.     int len = src.length;
  13.     System.arraycopy(src, 0, d, 0, len);
  14.     //System.out.println(toString(d));
  15. }
  16. public static void main(String[] args) {
  17.     String[] src = new String[1000000];
  18.     Arrays.fill(src, "hello");
  19.     AtoS as = new AtoS();
  20.     long time = System.currentTimeMillis();
  21.     as.copy1(src);
  22.     long a = System.currentTimeMillis() - time;
  23.     time = System.currentTimeMillis();
  24.     as.copy2(src);
  25.     long b = System.currentTimeMillis() - time;
  26.     System.out.println(a + "   " + b);
  27. }
  28. }


运行结果 : 71    40
因为定义 public static native void arraycopy(...)这个函数是一个本地的函数,速度更快。
关于本地方法的一些知识参考:
http://www.80x86.cn/article.asp?id=1448
原创粉丝点击