tbwshc

Arrays.asList方法 学习记录

Arrays工具类提供了一些比较实用的方法,比如sort, binarySearch, fill等。其中还有一个asList方法,此方法能够将一个变长参数或者数组转换成List。
  但是,这个生成的List,它是固定长度的,如果对其进行add或者remove的操作,会抛出UnsupportedOperationException,为什么会这样呢?
  带着疑问,查看一下Arrays的源码,可以得到问题的结果。
  Java代码
  /**
  * 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 Collection.toArray. The returned list is
  * serializable and implements {@link RandomAccess}.
  *
  *
  This method also provides a convenient way to create a fixed-size
  * list initialized to contain several elements:
  *
  * List 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.
  * @see Collection#toArray()
  */
  public static List asList(T... a) {
  return new ArrayList(a);

  方法asList返回的是new ArrayList(a)。但是,这个ArrayList并不是java.util.ArrayList,它是一个Arrays类中的重新定义的内部类。
  具体的实现如下:
  Java代码
  /**
  * @serial include
  */
  private static class ArrayList extends AbstractList
  implements RandomAccess, java.io.Serializable
  {
  private static final long serialVersionUID = -2764017481108945198L;
  private Object[] a;
  ArrayList(E[] array) {
  if (array==null)
  throw new NullPointerException();
  a = array;
  }
  public int size() {
  return a.length;
  }
  public Object[] toArray() {
  return (Object[])a.clone();
  }
  public E get(int index) {
  return (E)a[index];
  }
  public E set(int index, E element) {
  Object oldValue = a[index];
  a[index] = element;
  return (E)oldValue;
  }
  public int indexOf(Object o) {
  if (o==null) {
  for (int i=0; i
  if (a[i]==null)
  return i;
  } else {
  for (int i=0; i
  if (o.equals(a[i]))
  return i;
  }
  return -1;
  }
  public boolean contains(Object o) {
  return indexOf(o) != -1;
  }
  }
  从这个内部类ArrayList的实现可以看出,它继承了类AbstractList,但是没有重写add和remove方法,没有给出具体的实现。查看一下AbstractList类中对add和remove方法的定义,如果一个list不支持add和remove就会抛出UnsupportedOperationException。
  Java代码
  public abstract class AbstractList extends AbstractCollection implements List {
  /**
  * Sole constructor. (For invocation by subclass constructors, typically
  * implicit.)
  */
  protected AbstractList() {
  }
  /**
  * Appends the specified element to the end of this List (optional
  * operation).
  *
  * This implementation calls add(size(), o).
  *
  * Note that this implementation throws an
  * UnsupportedOperationException unless add(int, Object)
  * is overridden.
  *
  * @param o element to be appended to this list.
  *
  * @return true (as per the general contract of
  * Collection.add).
  *
  * @throws UnsupportedOperationException if the add method is not
  * supported by this Set.
  *
  * @throws ClassCastException if the class of the specified element
  * prevents it from being added to this set.
  *
  * @throws IllegalArgumentException some aspect of this element prevents
  * it from being added to this collection.
  */
  public boolean add(E o) {
  add(size(), o);
  return true;
  }
  /**
  * Inserts the specified element at the specified position in this list
  * (optional operation). Shifts the element currently at that position
  * (if any) and any subsequent elements to the right (adds one to their
  * indices).
  *
  * This implementation always throws an UnsupportedOperationException.
  *
  * @param index index at which the specified element is to be inserted.
  * @param element element to be inserted.
  *
  * @throws UnsupportedOperationException if the add method is not
  * supported by this list.
  * @throws ClassCastException if the class of the specified element
  * prevents it from being added to this list.
  * @throws IllegalArgumentException if some aspect of the specified
  * element prevents it from being added to this list.
  * @throws IndexOutOfBoundsException index is out of range (index <
  * 0 || index > size()).
  */
  public void add(int index, E element) {
  throw new UnsupportedOperationException();
  }
  /**
  * Removes the element at the specified position in this list (optional
  * operation). Shifts any subsequent elements to the left (subtracts one
  * from their indices). Returns the element that was removed from the
  * list.
  *
  * This implementation always throws an
  * UnsupportedOperationException.
  *
  * @param index the index of the element to remove.
  * @return the element previously at the specified position.
  *
  * @throws UnsupportedOperationException if the remove method is
  * not supported by this list.
  * @throws IndexOutOfBoundsException if the specified index is out of
  * range (index < 0 || index >= size()).
  */
  public E remove(int index) {
  throw new UnsupportedOperationException();
  }
  }
  至此,为什么Arrays.asList产生的List是不可添加或者删除,否则会产生UnsupportedOperationException,就可以得到解释了。
  如果我们想把一个变长或者数据转变成List, 而且tb期望这个List能够进行add或者remove操作,那该怎么做呢?
  我们可以写一个类似的方法,里面直接采用java.util.ArrayList即可。
  比如:
  Java代码
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  public class MyArrays {
  public static List asList(T... a) {
  List list = new ArrayList();
  Collections.addAll(list, a);
  return list;
  }
  }
  测试代码如下:
  Java代码
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  public class Test {
  @SuppressWarnings("unchecked")
  public static void main(String[] args) {
  List stooges = Arrays.asList("Larry", "Moe", "Curly");
  print(stooges);
  List> seasonsList = Arrays.asList(retrieveSeasonsList());
  print(seasonsList);
  /*
  * 自己实现一个asList方法,能够添加和删除。
  */
  List list = MyArrays.asList("Larry", "Moe", "Curly");
  list.add("Hello");
  print(list);
  }
  private static void print(List list) {
  System.out.println(list);
  }
  private static List retrieveSeasonsList() {
  List seasonsList = new ArrayList();
  seasonsList.add("Spring");
  seasonsList.add("Summer");
  seasonsList.add("Autumn");
  seasonsList.add("Winter");
  return seasonsList;
  }
  }
  输出结果:
  [Larry, Moe, Curly]
  [[Spring, Summer, Autumn, Winter]]
  [Larry, Moe, Curly, Hello]

posted on 2013-07-15 17:08 chen11-1 阅读(227) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: