本博客转载自:https://blog.csdn.net/maywehe/article/details/52553954

写demo的时候,为了避免用list.add方法,特意写了个数组然后转换成list。一开始以为转换成的list就是实现了AbstractList的通用的List, 比如ArrayList或者LinkedList等。 当调用add方法的时候, 奇怪的事情发生了。

  1. String[] arrays = new String[] { "1", "2", "3" };
  2. List<String> list = Arrays.asList(arrays);
  3. list.add("4");

  抛异常:

  1. Exception in thread "main" java.lang.UnsupportedOperationException
  2. at java.util.AbstractList.add(AbstractList.java:148)
  3. at java.util.AbstractList.add(AbstractList.java:108)
  4. at com.maywe.list.Demo.main(Demo.java:43)

  

List 调用add方法是最普遍不过的场景,怎么会抛异常呢? 赶快去研究下源码。

java.util.Arrays$ArrayList 源码($表示内部类的意思,下面的源码是Arrays内部类ArrayList 的类型定义源码,在java.util.Arrays.class文件中

  1. private static class ArrayList<E> extends AbstractList<E>
  2. implements RandomAccess, java.io.Serializable
  3. {
  4. private static final long serialVersionUID = -2764017481108945198L;
  5. private final E[] a;
  6.  
  7. ArrayList(E[] array) {
  8. if (array==null)
  9. throw new NullPointerException();
  10. a = array;
  11. }
  12.  
  13. public int size() {
  14. return a.length;
  15. }
  16.  
  17. public Object[] toArray() {
  18. return a.clone();
  19. }
  20.  
  21. public <T> T[] toArray(T[] a) {
  22. int size = size();
  23. if (a.length < size)
  24. return Arrays.copyOf(this.a, size,
  25. (Class<? extends T[]>) a.getClass());
  26. System.arraycopy(this.a, , a, , size);
  27. if (a.length > size)
  28. a[size] = null;
  29. return a;
  30. }
  31.  
  32. public E get(int index) {
  33. return a[index];
  34. }
  35.  
  36. public E set(int index, E element) {
  37. E oldValue = a[index];
  38. a[index] = element;
  39. return oldValue;
  40. }
  41.  
  42. public int indexOf(Object o) {
  43. if (o==null) {
  44. for (int i=; i<a.length; i++)
  45. if (a[i]==null)
  46. return i;
  47. } else {
  48. for (int i=; i<a.length; i++)
  49. if (o.equals(a[i]))
  50. return i;
  51. }
  52. return -;
  53. }
  54.  
  55. public boolean contains(Object o) {
  56. return indexOf(o) != -;
  57. }
  58. }

 

的确是实现了AbstractList,但是没有实现add方法, 在看看AbstractList的add方法:

  1. public boolean add(E e) {
  2. add(size(), e);
  3. return true;
  4. }
  5.  
  6. public void add(int index, E element) {
  7. throw new UnsupportedOperationException();
  8. }

UnsupportedOperationException 就是怎么抛出来的。(解释:List<String> list = Arrays.asList(arrays)语句中,Arrays.asList(arrays)的返回值(Arrays$ArrayList类型)被向上为list。当调用add(E e)方法的时候,会直接调用Arrays$ArrayList类的add(int index, E element)方法,由于Arrays$ArrayList类没有重写add(size(), e)方法,所以会调用基类(AbstractList)的add(int index, E element)方法,所以会抛出UnsupportedOperationException异常。由此可知,如果想不报异常,Arrays$ArrayList类应该重写add(E e)方法或者add(int index, E element)方法)

所以java.util.Arrays$ArrayList只能在不超过capacity的情况下调用set设置元素,不能增加元素。


顺便研究了下java.util..ArrayList的add方法。

  1. public boolean add(E e) {
  2. ensureCapacityInternal(size + ); // Increments modCount!!
  3. elementData[size++] = e;
  4. return true;
  5. }

在List的最后Append新元素,capacity增加一个

  1. public void add(int index, E element) {
  2. rangeCheckForAdd(index);//判断index是否小于0或者大于数组长度,
  3.  
  4. ensureCapacityInternal(size + ); // Increments modCount!!
  5. System.arraycopy(elementData, index, elementData, index + ,
  6. size - index);
  7. elementData[index] = element;
  8. size++;
  9. }
  • 在index指定的位置增加元素E, 同时index右边的(索引>index) 所有元素右移;
  • 如果参数index大于当前的size会抛出异常,因为capacity只是增加一;
  • 因为存在“右移”操作,建议没有必要的情况下调用List#add(E e)即可,避免不必要的“右移”操作

demo 代码:

  1. String[] arrays = new String[] { "", "", "" };
  2. List<String> list = Arrays.asList(arrays);
  3. System.out.println(list);
  4. System.out.println(list.getClass());
  5. List<String> list2 = new ArrayList<String>(list);
  6. list2.add(, "");
  7. System.out.println(list2);
  8. System.out.println(list2.getClass());

结果输出:

  1. [, , ]
  2. class java.util.Arrays$ArrayList
  3. [, , , ]
  4. class java.util.ArrayList

java.util.ArrayList与java.util.Arrays$ArrayList区别的更多相关文章

  1. java.util.ArrayList、java.util.vector和java.util.LinkedList (JDK 1.8.0_111)

    一.java.util.ArrayList 1.1 ArrayList 继承结构 ArrayList实现了RandomAccess,可以随机访问(其实就是通过数组下标访问):实现了Cloneable, ...

  2. Java链表基本操作和Java.util.ArrayList

    Java链表基本操作和Java.util.ArrayList 今天做了一道<剑指offer>上的一道编程题“从尾到头打印链表”,具体要求如下:输入一个链表,按链表值从尾到头的顺序返回一个A ...

  3. Exception in thread "main" java.lang.StackOverflowError at java.util.ArrayList$SubList.rangeCheckForAdd(Unknown Source)

    Exception in thread "main" java.lang.StackOverflowError at java.util.ArrayList$SubList.ran ...

  4. mybatis异常: invalid comparison: java.util.ArrayList and java.lang.String] with root cause

    mybatis中使用动态sql,报错: invalid comparison: java.util.ArrayList and java.lang.String] with root cause 是由 ...

  5. invalid comparison: java.util.ArrayList and java.lang.String解决

    报错: Caused by: org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause ...

  6. Java数据结构之表的增删对比---ArrayList与LinkedList之一

    一.Java_Collections表的实现 与c不同Java已经实现并封装了现成的表数据结构,顺序表以及链表. 1.ArrayList是基于数组的实现,因此具有的特点是:1.有索引值方便查找,对于g ...

  7. Java基础知识强化之集合框架笔记28:ArrayList集合练习之去除ArrayList集合中的重复字符串元素(升级)

    1. 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)     要求:不能创建新的集合,就在以前的集合上做. 2. 代码示例之 去除集合中重复元素,不创建新的集合: package ...

  8. Java基础知识强化之集合框架笔记27:ArrayList集合练习之去除ArrayList集合中的重复字符串元素

    1. 去除ArrayList集合中的重复字符串元素(字符串内容相同) 分析: (1)创建集合对象 (2)添加多个字符串元素(包含重复的) (3)创建新的集合 (4)遍历旧集合,获取得到每一个元素 (5 ...

  9. [转]Java Code Examples for android.util.JsonReader

    [转]Java Code Examples for android.util.JsonReader The following are top voted examples for showing h ...

随机推荐

  1. iOS编程规范(整理)

    一.文档结构管理 1.建立Libraries文件夹,所有第三方库放入其中. 2.建立Utilities文件夹,自已封装的类放入其中. 3.建立Constants.h头文件,所有的常量定义于其中.Con ...

  2. iOS-加载数据的实现-MJRefresh

    使用CocoaPods加载三方库: pod 'MJRefresh' MJRefresh类结构图: 具体实现方法和效果图: The drop-down refresh 01-Default self.t ...

  3. TestNG并发测试包

    https://www.yiibai.com/testng/basic-annotations.html

  4. 解决mysql连接输入密码提示Warning: Using a password on the command line interface can be insecure

    有时候客户端连接mysql需要指定密码时(如用zabbix监控mysql)5.6后数据库会给出个警告信息 mysql -uroot -pxxxx Warning: Using a password o ...

  5. PHP重定向的三个方法

    js的重定向方法:location.href=目标 url(如 https:www.baidu.com); php的重定向方法: header("location: https:www.ba ...

  6. 微信jssdk实现分享到微信

    本来用的是这个插件http://overtrue.me/share.js/和百度分享 相同之处:在微信分享的时候,分享的链接都不能获取到缩略图... 不同之处:百度分享在微信低版本是可以看到缩略图的( ...

  7. HDU3874 线段树 + 离线处理

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3874 , 线段树(或树状数组) + 离线处理 下午做了第一道离线处理的题目(HDU4417),多少有点 ...

  8. LA 2038 Strategic game(最小点覆盖,树形dp,二分匹配)

    题意即求一个最小顶点覆盖. 对于没有孤立点的图G=(V,E),最大独立集+最小顶点覆盖= V.(往最大独立集加点) 问题可以变成求树上的最大独立集合. 每个结点的选择和其父节点选不选有关, dp(u, ...

  9. python_16_自己建立模块

    import python_5_password

  10. Python实现注册和登录

    一.注册账号需要实现的功能 1.输入:用户名,密码,密码确认 2.限制1:输入的账号和密码不能为空 3.限制2:两次输入密码必须一致 4.限制3:用户名不能重复 5.限制4:错误次数为4次 6.用字典 ...