程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java 源碼剖析Arrays.asList辦法詳解

java 源碼剖析Arrays.asList辦法詳解

編輯:關於JAVA

java 源碼剖析Arrays.asList辦法詳解。本站提示廣大學習愛好者:(java 源碼剖析Arrays.asList辦法詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是java 源碼剖析Arrays.asList辦法詳解正文


比來,抽閒把java Arrays 對象類的asList 辦法做了源碼剖析,在網上整頓了相干材料,記載上去,願望也能贊助讀者!

Arrays對象類供給了一個辦法asList, 應用該辦法可以將一個變長參數或許數組轉換成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<String> 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);
 }
 

成績發明

依據上述辦法的描寫,我們先來編寫幾個例子:

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

}

 運轉上述法式,輸入以下內容。

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

血汗來潮,忽然想在創立的列表中添加一個字符串“Cool~~~”,  走一個。

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

成果,碰到一個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)發生的列表挪用add辦法,居然碰到成績。

緣由查找

那末成績來了,究竟產生了甚麼工作?帶著疑問,去檢查一下Arrays.asList中應用的ArrayList究竟長啥樣?

本來Arrays的asList辦法應用的ArrayList類是一個外部界說的類,而不是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;
    }
  }

從這個外部類ArrayList的完成可以看出,它繼續了籠統類java.util.AbstractList<E>, 然則沒有重寫add和remove辦法,沒有給出詳細的完成。

然則,默許情形下,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類的外部類ArrayList沒有重寫add和remove辦法,所以,當我們挪用其add辦法時,其實就是挪用了AbstractList類的add辦法,成果就是直接拋出UnsupportedOperationException異常。

同理,在挪用remove辦法,或許挪用與add、remove辦法相干聯的其它辦法(如addAll)異樣會碰到UnsupportedOperationException異常。

addAll的例子:

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

  public static void main(String[] args) {

    /**應用變長參數*/
    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) {

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

}

恰是因為Arrays的外部類ArrayList重寫了set辦法,所以上述法式可以或許正常運轉,不會再拋出UnsupportedOperationException異常。

成果以下:

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

應用場景

從上述的例子和簡略剖析來看,Arrays對象類供給了一個辦法asList, 應用該辦法可以將一個變長參數或許數組轉換成List 。

然則,生成的List的長度是固定的;可以或許停止修正操作(好比,修正某個地位的元素);不克不及履行影響長度的操作(如add、remove等操作)。會拋出UnsupportedOperationException異常。

Arrays.asList比擬合適那些曾經稀有組數據或許一些元素,而須要疾速構建一個List,只用於讀取操作,而不停止添加或刪除操作的場景。

假如,想要依據已知數組數據,疾速獲得一個可停止增刪改查的列表List,一個比擬簡略的辦法以下:

從新應用java.util.ArrayList包裝一層。

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

  public static void main(String[] args) {

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

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

  }

}

成果以下:

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

感激浏覽,願望能贊助到年夜家,感謝年夜家對本站的支撐!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved