<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVA—咖啡館

    ——?dú)g迎訪問rogerfan的博客,常來《JAVA——咖啡館》坐坐,喝杯濃香的咖啡,彼此探討一下JAVA技術(shù),交流工作經(jīng)驗(yàn),分享JAVA帶來的快樂!本網(wǎng)站部分轉(zhuǎn)載文章,如果有版權(quán)問題請(qǐng)與我聯(lián)系。

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      447 Posts :: 145 Stories :: 368 Comments :: 0 Trackbacks

    1. 為了方面按列作外循環(huán),想把ArrayList構(gòu)造成一個(gè)二維數(shù)組,如下:

        ......

      ArrayList result=GetResult();

      int n=result.size();

      String[][] myArray=new String[n][]; //定義二維數(shù)組
     
      for (int i=0;i<n;i++)  //構(gòu)造二維數(shù)組
      {
        ArrayList tempArray= (ArrayList)result.get(i);
        myArray[i]=(String[])tempArray.toArray();
      }

      ......

    程序可以編譯通過。

    但在運(yùn)行到myArray[i]=(String[])tempArray.toArray()時(shí),出現(xiàn)java.lang.ClassCastException的錯(cuò)誤,很奇怪。

    花了一晚上時(shí)間,查了N多資料,總算搞定了。現(xiàn)把問題記錄下來,以備參考。

     

     

    2. 此事從頭說起。  

    ArrayList類擴(kuò)展AbstractList并執(zhí)行List接口。ArrayList支持可隨需要而增長(zhǎng)的動(dòng)態(tài)數(shù)組。

        ArrayList有如下的構(gòu)造函數(shù):
      
            ArrayList( )
            ArrayList(Collection c)
            ArrayList(int capacity)

    如果調(diào)用new ArrayList()構(gòu)造時(shí),其默認(rèn)的capacity(初始容量)為10。

    參見ArrayList源碼,其中是這樣定義的:

        public ArrayList() {
      this(10);
         }

    默認(rèn)初始化內(nèi)部數(shù)組大小為10。為什么是10?不知道。可能SUN覺得這樣比較爽吧。

    程序編譯后執(zhí)行ArrayList.toArray(),把ArrayList轉(zhuǎn)化為數(shù)組時(shí),該數(shù)組大小仍為capacity(為10)。

    當(dāng)裝入的數(shù)據(jù)和capacity值不等時(shí)(小于capacity),比如只裝入了5個(gè)數(shù)據(jù),數(shù)組中后面的(capacity - size)個(gè)對(duì)象將置為null,此時(shí)當(dāng)數(shù)組強(qiáng)制類型轉(zhuǎn)換時(shí),容易出現(xiàn)一些問題,如java.lang.ClassCastException異常等。

    解決辦法是:在用ArrayList轉(zhuǎn)化為數(shù)組裝數(shù)據(jù)后,使用trimToSize()重新設(shè)置數(shù)組的真實(shí)大小。


    3. 本例修改后的代碼修如下,可順利運(yùn)行:

        for (int i=0;i<n;i++)  //構(gòu)造二維數(shù)組
          {
                ArrayList tempArray= (ArrayList)result.get(i);
                myArray[i]=(String[])tempArray.toArray(new String[0]);   //注意此處的寫法
           }

     看看下面這些也許就明白了--

    ArrayList.toArray()之一:

    public Object[] toArray() {
      Object[] result = new Object[size];
      System.arraycopy(elementData, 0, result, 0, size);
      return result;
    }

    返回ArrayList元素的一個(gè)數(shù)組,注意這里雖然生成了一個(gè)新的數(shù)組,但是數(shù)組元素和集合中的元素是共享的,Collection接口中說這個(gè)是安全的,這是不嚴(yán)格的。

    下面的例子演示了這個(gè)效果。
     
       ArrayList al=new ArrayList();
       al.add(new StringBuffer("hello"));
       Object[] a=al.toArray();
       StringBuffer sb=(StringBuffer)a[0];
       sb.append("changed");  //改變數(shù)組元素同樣也改變了原來的ArrayList中的元素
       System.out.println(al.get(0));    

    這里不要用String來代替StringBuffer,因?yàn)镾tring是常量。


    ArrayList.toArray()之二:

    public Object[] toArray(Object a[]) {
      if (a.length < size)
        a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
       System.arraycopy(elementData, 0, a, 0, size);
       if (a.length > size)
          a[size] = null;
       return a;
    }

    這個(gè)方法有可能不需要生成新的數(shù)組,注意到如果數(shù)組a容量過大,只在size處設(shè)置為null。

    如果這個(gè)數(shù)組a足夠大,就會(huì)把數(shù)據(jù)全放進(jìn)去,返回的數(shù)組也是指向這個(gè)數(shù)組,(數(shù)組多余的空間存儲(chǔ)的是null對(duì)象);要是不夠大,就申請(qǐng)一個(gè)跟參數(shù)同樣類型的數(shù)組,把值放進(jìn)去,然后返回。


    4. 網(wǎng)上的資料一:

      public String[] getPlatformIDList()
     
      {
            Vector result = new Vector();
            try
            {
                Statement stmt = conn.createStatement();
                String sql = "SELECT PlatformID FROM Platform";
                rs = stmt.executeQuery(sql);
                while(rs.next())
                {
                    result.add(rs.getString(1));
                }       
                if (result.size() > 0)
                {
                    String[] str = (String[]) result.toArray(); // 出現(xiàn)ClassCastException
                    return str;
                }
                else
                    return null;
            }
            catch(Exception e)
            {
                System.err.println(e);
                return null;
            }
            finally
            {
                try
                {
                    rs.close();
                    conn.close();
                }
                catch(Exception e2)
                {}
            }
        }

        程序運(yùn)行后,發(fā)現(xiàn)不能將Vector類經(jīng)過toArray()方法得到的Object[]直接轉(zhuǎn)換成String[]。

        找到用另一個(gè)帶有參數(shù)的 toArray(T[] a)方法才可以。

        將該語句改為:

        String[] str = (String[]) result.toArray(new String[1]);即告訴Vector,我要得到的數(shù)組的類型。

        回想一下,應(yīng)該是java中的強(qiáng)制類型轉(zhuǎn)換只是針對(duì)單個(gè)對(duì)象的,想要偷懶,將整個(gè)數(shù)組轉(zhuǎn)換成另外一種類型的數(shù)組是不行的。


    5. 網(wǎng)上的資料二:

        正確使用List.toArray()--
     
       在程序中,往往得到一個(gè)List,程序要求對(duì)應(yīng)賦值給一個(gè)array,可以這樣寫程序:
     
        Long [] l = new Long[list.size()];
        for(int i=0;i<list.size();i++)
            l[i] = (Long) list.get(i);
     
        要寫這些code,似乎比較繁瑣,其實(shí)List提供了toArray()的方法。
        但是要使用不好,就會(huì)有ClassCastExceptiony異常。究竟這個(gè)是如何產(chǎn)生的,且看代碼:

            List list = new ArrayList();
            list.add(new Long(1));list.add(new Long(2));
            list.add(new Long(3));list.add(new Long(4));
            Long[] l = (Long[])list.toArray();
            for(int i=0; i<l.length; i++)
                System.out.println(l[i].longValue());

        紅色代碼會(huì)拋java.lang.ClassCastException。

        當(dāng)然,為了讀出值來,你可以這樣code:

            Object [] a =  list.toArray();
            for(int i=0;i<a.length;i++)
                System.out.println(((Long)a[i]).longValue());

        但是讓數(shù)組丟失了類型信息,這個(gè)不是我們想要得。


        toArray()正確使用方式如下:

            1)  Long[] l = new Long[<total size>];
                  list.toArray(l);
     
            2)  Long[] l = (Long []) list.toArray(new Long[0]);

            3)  Long [] a = new Long[<total size>];
                  Long [] l = (Long []) list.toArray(a);

     

    6. 總結(jié)補(bǔ)充:

          java sdk doc 上講:
     
          public Object[] toArray(Object[] a)

          a--the array into which the elements of this list are to be stored, if it is big enough; otherwise, a new array of the same  runtime type is allocated for this purpose.

          如果這個(gè)數(shù)組a足夠大,就會(huì)把數(shù)據(jù)全放進(jìn)去,返回的數(shù)組也是指向這個(gè)數(shù)組,(數(shù)組多余的空間存儲(chǔ)的是null對(duì)象);要是不夠大,就申請(qǐng)一個(gè)跟參數(shù)同樣類型的數(shù)組,把值放進(jìn)去,然后返回。
     
         需要注意的是:你要是傳入的參數(shù)為9個(gè)大小,而list里面有5個(gè)object,那么其他的四個(gè)很可能是null , 使用的時(shí)候要特別注意。

     

    7. 完畢。

    posted on 2008-05-14 13:40 rogerfan 閱讀(2004) 評(píng)論(0)  編輯  收藏 所屬分類: 【Java知識(shí)】
    主站蜘蛛池模板: 成年18网站免费视频网站| 国产2021精品视频免费播放| 好大好深好猛好爽视频免费| 亚洲短视频在线观看| 无码国产精品一区二区免费模式 | 亚洲免费视频网站| 亚洲AV无码成人精品区天堂| 亚洲一级毛片免费看| 我的小后妈韩剧在线看免费高清版 | 亚洲色无码专区一区| 四虎在线免费播放| 国产亚洲精品91| 亚洲精品美女久久久久99小说| 亚洲一区二区电影| 国产成人综合亚洲一区| 亚洲精品97久久中文字幕无码| ssswww日本免费网站片| 中文字幕av无码无卡免费| 亚洲午夜无码久久久久小说| 国产成人免费a在线视频app | 波多野结衣在线免费视频| 亚洲婷婷五月综合狠狠爱| 国产精品亚洲综合五月天| 午夜免费福利影院| xxxx日本在线播放免费不卡| 精品免费国产一区二区| 人人鲁免费播放视频人人香蕉| 久久亚洲精品AB无码播放 | 国产午夜无码视频免费网站| 久青草国产免费观看| 亚洲嫩模在线观看| 免费的一级片网站| 成全高清在线观看免费| 亚洲三级中文字幕| 亚洲一区二区三区在线播放| 1000部拍拍拍18勿入免费视频下载| 亚洲另类无码一区二区三区| 久草免费在线观看视频| 久久亚洲色WWW成人欧美| 免费无码看av的网站| 中文字幕乱码免费看电影|