多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > Java提高配(三七)―

Java提高配(三七)―

來源:程序員人生   發布時間:2015-03-27 07:59:19 閱讀次數:2609次

         我們常常使用subString方法來對String對象進行分割處理,同時我們也能夠使用subList、subMap、subSet來對List、Map、Set進行分割處理,但是這個分割存在某些瑕疵。

1、subList返回僅僅只是1個視圖

        首先我們先看以下實例:

public static void main(String[] args) { List<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(2); //通過構造函數新建1個包括list1的列表 list2 List<Integer> list2 = new ArrayList<Integer>(list1); //通過subList生成1個與list11樣的列表 list3 List<Integer> list3 = list1.subList(0, list1.size()); //修改list3 list3.add(3); System.out.println("list1 == list2:" + list1.equals(list2)); System.out.println("list1 == list3:" + list1.equals(list3)); }

        這個例子非常簡單,不過就是通過構造函數、subList重新生成1個與list11樣的list,然后修改list3,最后比較list1 == list2?、list1 == list3?。依照我們常規的思路應當是這樣的:由于list3通過add新增了1個元素,那末它肯定與list1不等,而list2是通過list1構造出來的,所以應當相等,所以結果應當是:

list1 == list2:true list1 == list3: false

        首先我們先不論結果的正確與否,我們先看subList的源碼:

public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, 0, fromIndex, toIndex); }

        subListRangeCheck方式是判斷fromIndex、toIndex是不是合法,如果合法就直接返回1個subList對象,注意在產生該new該對象的時候傳遞了1個參數 this ,該參數非常重要,由于他代表著原始list。

/** * 繼承AbstractList類,實現RandomAccess接口 */ private class SubList extends AbstractList<E> implements RandomAccess { private final AbstractList<E> parent; //列表 private final int parentOffset; private final int offset; int size; //構造函數 SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; } //set方法 public E set(int index, E e) { rangeCheck(index); checkForComodification(); E oldValue = ArrayList.this.elementData(offset + index); ArrayList.this.elementData[offset + index] = e; return oldValue; } //get方法 public E get(int index) { rangeCheck(index); checkForComodification(); return ArrayList.this.elementData(offset + index); } //add方法 public void add(int index, E e) { rangeCheckForAdd(index); checkForComodification(); parent.add(parentOffset + index, e); this.modCount = parent.modCount; this.size++; } //remove方法 public E remove(int index) { rangeCheck(index); checkForComodification(); E result = parent.remove(parentOffset + index); this.modCount = parent.modCount; this.size--; return result; } }

        該SubLsit是ArrayList的內部類,它與ArrayList1樣,都是繼承AbstractList和實現RandomAccess接口。同時也提供了get、set、add、remove等list經常使用的方法。但是它的構造函數有點特殊,在該構造函數中有兩個地方需要注意:

        1、this.parent = parent;而parent就是在前面傳遞過來的list,也就是說this.parent就是原始list的援用。

        2、this.offset = offset + fromIndex;this.parentOffset = fromIndex;。同時在構造函數中它乃至將modCount(fail-fast機制)傳遞過來了。

        我們再看get方法,在get方法中return ArrayList.this.elementData(offset + index);這段代碼可以清晰表明get所返回就是原列表offset + index位置的元素。一樣的道理還有add方法里面的:

parent.add(parentOffset + index, e); this.modCount = parent.modCount;

        remove方法里面的

E result = parent.remove(parentOffset + index); this.modCount = parent.modCount;

        誠然,到了這里我們可以判斷subList返回的SubList一樣也是AbstractList的子類,同時它的方法如get、set、add、remove等都是在原列表上面做操作,它并沒有像subString1樣生成1個新的對象。所以subList返回的只是原列表的1個視圖,它所有的操作終究都會作用在原列表上。

        那末從這里的分析我們可以得出上面的結果應當恰恰與我們上面的答案相反:

list1 == list2:false list1 == list3:true

Java細節(3.1):subList返回的只是原列表的1個視圖,它所有的操作終究都會作用在原列表上

2、subList生成子列表后,不要試圖去操作原列表

        從上面我們知道subList生成的子列表只是原列表的1個視圖而已,如果我們操作子列表它產生的作用都會在原列表上面表現,但是如果我們操作原列表會產生甚么情況呢?

public static void main(String[] args) { List<Integer> list1 = new ArrayList<Integer>(); list1.add(1); list1.add(2); //通過subList生成1個與list11樣的列表 list3 List<Integer> list3 = list1.subList(0, list1.size()); //修改list3 list1.add(3); System.out.println("list1'size:" + list1.size()); System.out.println("list3'size:" + list3.size()); }

        該實例如果不產生意外,那末他們兩個list的大小都應當都是3,但是恰恰適得其反,事實上我們得到的結果是這樣的:

list1'size:3 Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$SubList.checkForComodification(Unknown Source) at java.util.ArrayList$SubList.size(Unknown Source) at com.chenssy.test.arrayList.SubListTest.main(SubListTest.java:17)

        list1正常輸出,但是list3就拋出ConcurrentModificationException異常,看過我另外一篇博客的同仁肯定對這個異常非常,fail-fast?不錯就是fail-fast機制,在fail-fast機制中,LZ花了很多力氣來說述這個異常,所以這里LZ就不對這個異常多講了(更多請點這里:Java提高篇(34)―

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产中文久久精品 | 在线观看一区二区三区四区 | 69毛片| 爱爱小视频免费体验区在线观看 | 另类 欧美 视频二区 | 亚洲午夜久久久久国产 | 美美女高清毛片视频免费观看 | 福利视频一区二区三区 | 亚洲人成a在线网站 | 久久天堂影院 | 欧美啊v在线 | 91精品一区二区综合在线 | 最近中文字幕无吗高清视频 | 欧美激情一区二区 | 国产男女爽爽爽爽爽免费视频 | 欧美理论在线 | 一级毛片在线不卡直接观看 | 美日韩一区二区 | 亚洲综合欧美日韩 | 国产精品嫩草影院88v | 欧美韩国日本在线 | 乱人伦精品一区二区 | 欧美巨大黑人精品videos人妖 | 亚洲精品福利网站 | 一级作爱视频免费观看 | 极品色αv影院 | 欧美日韩性猛交xxxxx免费看 | 欧美日韩国产高清一区二区三区 | 色阁阁日韩欧美在线 | 日本精品一区二区三本中文 | 九色九色九色在线综合888 | 中文亚洲动漫精品 | 一区二区三区在线免费看 | 琪琪理论影院2018中文版 | 永久免费在线观看视频 | 在线观看免费xx高清视频 | 鸡毛片 | 福利视频一区二区 | 欧美精品xxxxx | aa大片| 成人欧美一区二区三区 |