最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java 源碼分析Arrays.asList方法詳解

 更新時間:2016年10月24日 10:07:23   作者:王孟君  
這篇文章主要介紹了java 源碼分析Arrays.asList方法詳解的相關(guān)資料,需要的朋友可以參考下

最近,抽空把java Arrays 工具類的asList 方法做了源碼分析,在網(wǎng)上整理了相關(guān)資料,記錄下來,希望也能幫助讀者!

Arrays工具類提供了一個方法asList, 使用該方法可以將一個變長參數(shù)或者數(shù)組轉(zhuǎn)換成List 。

其源代碼如下:

 /**
  * Returns a fixed-size list backed by the specified array. (Changes to
  * the returned list "write through" to the array.) This method acts
  * as bridge between array-based and collection-based APIs, in
  * combination with {@link Collection#toArray}. The returned list is
  * serializable and implements {@link RandomAccess}.
  *
  * <p>This method also provides a convenient way to create a fixed-size
  * list initialized to contain several elements:
  * <pre>
  *  List&lt;String&gt; stooges = Arrays.asList("Larry", "Moe", "Curly");
  * </pre>
  *
  * @param a the array by which the list will be backed
  * @return a list view of the specified array
  */
 @SafeVarargs
 public static <T> List<T> asList(T... a) {
  return new ArrayList<>(a);
 }
 

問題發(fā)現(xiàn)

根據(jù)上述方法的描述,我們先來編寫幾個例子:

/**
 * @author wangmengjun
 *
 */
public class ArrayExample {
 
 public static void main(String[] args) {
  
  /**使用變長參數(shù)*/
  List<String> array1 = Arrays.asList("Welcome", "to","Java", "world");
  System.out.println(array1);
  
  /**使用數(shù)組*/
  List<String> array2 = Arrays.asList(new String[] {"Welcome", "to","Java", "world"});
  System.out.println(array2);
 }

}

 運行上述程序,輸出如下內(nèi)容。

[Welcome, to, Java, world]
[Welcome, to, Java, world]

心血來潮,突然想在創(chuàng)建的列表中添加一個字符串“Cool~~~”,  走一個。

 /**使用變長參數(shù)*/
  List<String> array1 = Arrays.asList("Welcome", "to","Java", "world");
  array1.add("Cool~~~");

結(jié)果,遇到一個UnsupportedOperationException異常

Exception in thread "main" java.lang.UnsupportedOperationException
 at java.util.AbstractList.add(Unknown Source)
 at java.util.AbstractList.add(Unknown Source)
 at test.ArrayExample.main(ArrayExample.java:36)

不可思議,new ArrayList<>(a)產(chǎn)生的列表調(diào)用add方法,竟然遇到問題。

原因查找

那么問題來了,到底發(fā)生了什么事情?帶著疑問,去查看一下Arrays.asList中使用的ArrayList到底長啥樣?

原來Arrays的asList方法使用的ArrayList類是一個內(nèi)部定義的類,而不是java.util.ArrayList類。

其源代碼如下:

 /**
   * @serial include
   */
  private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
  {
    private static final long serialVersionUID = -2764017481108945198L;
    private final E[] a;

    ArrayList(E[] array) {
      if (array==null)
        throw new NullPointerException();
      a = array;
    }

    public int size() {
      return a.length;
    }

    public Object[] toArray() {
      return a.clone();
    }

    public <T> T[] toArray(T[] a) {
      int size = size();
      if (a.length < size)
        return Arrays.copyOf(this.a, size,
                   (Class<? extends T[]>) a.getClass());
      System.arraycopy(this.a, 0, a, 0, size);
      if (a.length > size)
        a[size] = null;
      return a;
    }

    public E get(int index) {
      return a[index];
    }

    public E set(int index, E element) {
      E oldValue = a[index];
      a[index] = element;
      return oldValue;
    }

    public int indexOf(Object o) {
      if (o==null) {
        for (int i=0; i<a.length; i++)
          if (a[i]==null)
            return i;
      } else {
        for (int i=0; i<a.length; i++)
          if (o.equals(a[i]))
            return i;
      }
      return -1;
    }

    public boolean contains(Object o) {
      return indexOf(o) != -1;
    }
  }

從這個內(nèi)部類ArrayList的實現(xiàn)可以看出,它繼承了抽象類java.util.AbstractList<E>, 但是沒有重寫add和remove方法,沒有給出具體的實現(xiàn)。

但是,默認情況下,java.util.AbstractList類在add、set以及remove方法中,直接會拋出UnsupportedOperationException異常。AbstractList的部分源代碼如下:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
  /**
   * Sole constructor. (For invocation by subclass constructors, typically
   * implicit.)
   */
  protected AbstractList() {
  }

  public E set(int index, E element) {
    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   *
   * <p>This implementation always throws an
   * {@code UnsupportedOperationException}.
   *
   * @throws UnsupportedOperationException {@inheritDoc}
   * @throws ClassCastException      {@inheritDoc}
   * @throws NullPointerException     {@inheritDoc}
   * @throws IllegalArgumentException   {@inheritDoc}
   * @throws IndexOutOfBoundsException   {@inheritDoc}
   */
  public void add(int index, E element) {
    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   *
   * <p>This implementation always throws an
   * {@code UnsupportedOperationException}.
   *
   * @throws UnsupportedOperationException {@inheritDoc}
   * @throws IndexOutOfBoundsException   {@inheritDoc}
   */
  public E remove(int index) {
    throw new UnsupportedOperationException();
  }
}

 正是因為java.util.Arrays類的內(nèi)部類ArrayList沒有重寫add和remove方法,所以,當我們調(diào)用其add方法時,其實就是調(diào)用了AbstractList類的add方法,結(jié)果就是直接拋出UnsupportedOperationException異常。

同理,在調(diào)用remove方法,或者調(diào)用與add、remove方法相關(guān)聯(lián)的其它方法(如addAll)同樣會遇到UnsupportedOperationException異常。

addAll的例子:

/**
 * @author wangmengjun
 *
 */
public class ArrayExample {

  public static void main(String[] args) {

    /**使用變長參數(shù)*/
    List<String> array1 = Arrays.asList("Welcome", "to", "Java", "world");
    array1.addAll(Arrays.asList("AAA", "BBB"));
  }

}

Exception in thread "main" java.lang.UnsupportedOperationException
 at java.util.AbstractList.add(Unknown Source)
 at java.util.AbstractList.add(Unknown Source)
 at java.util.AbstractCollection.addAll(Unknown Source)
 at test.ArrayExample.main(ArrayExample.java:36)
 

set的例子:

/**
 * @author wangmengjun
 *
 */
public class ArrayExample {

  public static void main(String[] args) {

    /**使用變長參數(shù)*/
    List<String> array1 = Arrays.asList("Welcome", "to", "Java", "world");
    System.out.println(array1);
    
    //將Java替換成hello
    array1.set(2, "hello");
    System.out.println(array1);
  }

}

正是由于Arrays的內(nèi)部類ArrayList重寫了set方法,所以上述程序能夠正常運行,不會再拋出UnsupportedOperationException異常。

結(jié)果如下:

[Welcome, to, Java, world]
[Welcome, to, hello, world] 

使用場景

從上述的例子和簡單分析來看,Arrays工具類提供了一個方法asList, 使用該方法可以將一個變長參數(shù)或者數(shù)組轉(zhuǎn)換成List 。

但是,生成的List的長度是固定的;能夠進行修改操作(比如,修改某個位置的元素);不能執(zhí)行影響長度的操作(如add、remove等操作)。會拋出UnsupportedOperationException異常。

Arrays.asList比較適合那些已經(jīng)有數(shù)組數(shù)據(jù)或者一些元素,而需要快速構(gòu)建一個List,只用于讀取操作,而不進行添加或刪除操作的場景。

如果,想要根據(jù)已知數(shù)組數(shù)據(jù),快速獲取一個可進行增刪改查的列表List,一個比較簡單的方法如下:

重新使用java.util.ArrayList包裝一層。

/**
 * @author wangmengjun
 *
 */
public class ArrayExample {

  public static void main(String[] args) {

    /**使用變長參數(shù)*/
    List<String> array1 = new ArrayList<>(Arrays.asList("Welcome", "to", "Java", "world"));
    System.out.println(array1);

    array1.add("Cool~~~");
    System.out.println(array1);

  }

}

結(jié)果如下:

[Welcome, to, Java, world]
[Welcome, to, Java, world, Cool~~~]

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • 初探Java內(nèi)部類的使用

    初探Java內(nèi)部類的使用

    Java內(nèi)部類一般可以分為以下三種:成員內(nèi)部類、靜態(tài)內(nèi)部類和匿名內(nèi)部類。這篇文章主要帶大家初探一下Java內(nèi)部類的使用,感興趣的可以了解一下
    2022-09-09
  • Springboot攔截器如何獲取@RequestBody參數(shù)

    Springboot攔截器如何獲取@RequestBody參數(shù)

    這篇文章主要介紹了Springboot攔截器如何獲取@RequestBody參數(shù)的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 詳解path和classpath的區(qū)別

    詳解path和classpath的區(qū)別

    這篇文章主要介紹了詳解path和classpath的區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • MyBatis-Plus中MetaObjectHandler沒生效完美解決

    MyBatis-Plus中MetaObjectHandler沒生效完美解決

    在進行測試時發(fā)現(xiàn)配置的MyMetaObjectHandler并沒有生效,本文主要介紹了MyBatis-Plus中MetaObjectHandler沒生效完美解決,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Windows Zookeeper安裝過程及啟動圖解

    Windows Zookeeper安裝過程及啟動圖解

    這篇文章主要介紹了Windows Zookeeper安裝過程及啟動圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • SpringMvc返回modelandview返回的頁面無法跳轉(zhuǎn)問題及解決

    SpringMvc返回modelandview返回的頁面無法跳轉(zhuǎn)問題及解決

    這篇文章主要介紹了SpringMvc返回modelandview返回的頁面無法跳轉(zhuǎn)問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 簡單理解java泛型的本質(zhì)(非類型擦除)

    簡單理解java泛型的本質(zhì)(非類型擦除)

    泛型在java中有很重要的地位,在面向?qū)ο缶幊碳案鞣N設(shè)計模式中有非常廣泛的應(yīng)用。泛型是參數(shù)化類型的應(yīng)用,操作的數(shù)據(jù)類型不限定于特定類型,可以根據(jù)實際需要設(shè)置不同的數(shù)據(jù)類型,以實現(xiàn)代碼復用。下面小編來簡單講一講泛型
    2019-05-05
  • 詳解springcloud 基于feign的服務(wù)接口的統(tǒng)一hystrix降級處理

    詳解springcloud 基于feign的服務(wù)接口的統(tǒng)一hystrix降級處理

    這篇文章主要介紹了詳解springcloud 基于feign的服務(wù)接口的統(tǒng)一hystrix降級處理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06
  • 深入了解java Lombok的使用方法

    深入了解java Lombok的使用方法

    這篇文章主要介紹了深入了解java Lombok的使用,Lombok是一個通過注解以達到減少代碼的Java庫,如通過注解的方式減少get,set方法,構(gòu)造方法等,需要的朋友可以參考下
    2019-06-06
  • Spring執(zhí)行流程和Bean的生命周期詳解

    Spring執(zhí)行流程和Bean的生命周期詳解

    這篇文章主要介紹了Spring執(zhí)行流程和Bean的生命周期詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06

最新評論

曲水县| 临西县| 赞皇县| 上林县| 巍山| 大同县| 乃东县| 资阳市| 张家界市| 江川县| 加查县| 家居| 新乐市| 林芝县| 万州区| 南开区| 深水埗区| 航空| 黄冈市| 什邡市| 屯留县| 韩城市| 兴山县| 白银市| 龙泉市| 怀仁县| 乐安县| 洛川县| 崇仁县| 达孜县| 麦盖提县| 罗平县| 宝清县| 博爱县| 溧阳市| 甘德县| 阿鲁科尔沁旗| 新余市| 黄梅县| 株洲市| 甘孜|