Rumah Java javaTutorial java 源码分析Arrays.asList方法详解

java 源码分析Arrays.asList方法详解

Feb 04, 2017 am 10:11 AM

最近,抽空把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 class="brush:php;toolbar:false">
 *  List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
 * 
* * @param a the array by which the list will be backed * @return a list view of the specified array */ @SafeVarargs public static List asList(T... a) { return new ArrayList<>(a); }
Salin selepas log masuk

问题发现

根据上述方法的描述,我们先来编写几个例子:

/**
 * @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);
 }
 
}
Salin selepas log masuk

运行上述程序,输出如下内容。

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

心血来潮,突然想在创建的列表中添加一个字符串“Cool~~~”, 走一个。

/**使用变长参数*/
 List<String> array1 = Arrays.asList("Welcome", "to","Java", "world");
 array1.add("Cool~~~");
Salin selepas log masuk

结果,遇到一个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)
Salin selepas log masuk

不可思议,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;
   }
 }
Salin selepas log masuk

从这个内部类ArrayList的实现可以看出,它继承了抽象类java.util.AbstractList, 但是没有重写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();
  }
}
Salin selepas log masuk

正是因为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"));
  }
 
}
Salin selepas log masuk

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)
Salin selepas log masuk

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);
  }
 
}
Salin selepas log masuk

正是由于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);
 
  }
 
}
Salin selepas log masuk

   

结果如下:

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

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

更多java 源码分析Arrays.asList方法详解相关文章请关注PHP中文网!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Adakah perisian keselamatan syarikat menyebabkan aplikasi gagal dijalankan? Bagaimana cara menyelesaikan masalah dan menyelesaikannya? Adakah perisian keselamatan syarikat menyebabkan aplikasi gagal dijalankan? Bagaimana cara menyelesaikan masalah dan menyelesaikannya? Apr 19, 2025 pm 04:51 PM

Penyelesaian masalah dan penyelesaian kepada perisian keselamatan syarikat yang menyebabkan beberapa aplikasi tidak berfungsi dengan baik. Banyak syarikat akan menggunakan perisian keselamatan untuk memastikan keselamatan rangkaian dalaman. …

Bagaimana untuk memudahkan isu pemetaan medan dalam dok sistem menggunakan mapstruct? Bagaimana untuk memudahkan isu pemetaan medan dalam dok sistem menggunakan mapstruct? Apr 19, 2025 pm 06:21 PM

Pemprosesan pemetaan medan dalam dok sistem sering menemui masalah yang sukar ketika melaksanakan sistem dok: bagaimana untuk memetakan medan antara muka sistem dengan berkesan ...

Bagaimana dengan elegan mendapatkan nama pemboleh ubah kelas entiti untuk membina keadaan pertanyaan pangkalan data? Bagaimana dengan elegan mendapatkan nama pemboleh ubah kelas entiti untuk membina keadaan pertanyaan pangkalan data? Apr 19, 2025 pm 11:42 PM

Apabila menggunakan Mybatis-Plus atau Rangka Kerja ORM yang lain untuk operasi pangkalan data, sering diperlukan untuk membina syarat pertanyaan berdasarkan nama atribut kelas entiti. Sekiranya anda secara manual setiap kali ...

Bagaimanakah Idea IntelliJ mengenal pasti nombor port projek boot musim bunga tanpa mengeluarkan log? Bagaimanakah Idea IntelliJ mengenal pasti nombor port projek boot musim bunga tanpa mengeluarkan log? Apr 19, 2025 pm 11:45 PM

Mula musim bunga menggunakan versi IntelliJideaultimate ...

Bagaimanakah saya menukar nama kepada nombor untuk melaksanakan penyortiran dan mengekalkan konsistensi dalam kumpulan? Bagaimanakah saya menukar nama kepada nombor untuk melaksanakan penyortiran dan mengekalkan konsistensi dalam kumpulan? Apr 19, 2025 pm 11:30 PM

Penyelesaian untuk menukar nama kepada nombor untuk melaksanakan penyortiran dalam banyak senario aplikasi, pengguna mungkin perlu menyusun kumpulan, terutama dalam satu ...

Bagaimana cara menukar objek Java dengan selamat ke array? Bagaimana cara menukar objek Java dengan selamat ke array? Apr 19, 2025 pm 11:33 PM

Penukaran objek dan tatasusunan Java: Perbincangan mendalam tentang risiko dan kaedah penukaran jenis cast yang betul Banyak pemula Java akan menemui penukaran objek ke dalam array ...

Kenapa projek musim bunga menyebabkan masalah rawak akibat kebergantungan bulat apabila bermula? Kenapa projek musim bunga menyebabkan masalah rawak akibat kebergantungan bulat apabila bermula? Apr 19, 2025 pm 11:21 PM

Memahami rawak kebergantungan bulat dalam permulaan projek musim bunga. Semasa membangunkan projek musim bunga, anda mungkin menghadapi rawak yang disebabkan oleh kebergantungan bulat pada permulaan projek ...

Bagaimana cara menukar nama ke nombor untuk melaksanakan penyortiran dalam kumpulan? Bagaimana cara menukar nama ke nombor untuk melaksanakan penyortiran dalam kumpulan? Apr 19, 2025 pm 01:57 PM

Bagaimana cara menukar nama ke nombor untuk melaksanakan penyortiran dalam kumpulan? Apabila menyusun pengguna dalam kumpulan, sering kali perlu menukar nama pengguna ke dalam nombor supaya ia boleh berbeza ...

See all articles