为了账号安全,请及时绑定邮箱和手机立即绑定

JAVA优化建议(7)

标签:
Java

1.List的equals方法只在在乎元素的相不相等

因为equals方法是在AbstractList中,代码如下:

 public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;

        ListIterator<E> e1 = listIterator();
        ListIterator e2 = ((List) o).listIterator();
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }

因此会得到以下结果

ArrayList arrayList = new ArrayList();
arrayList.add(1);
LinkedList linkedList = new LinkedList();
linkedList.add(1);
System.out.println("ArrayList是否与LinkedList相等"+arrayList.equals(linkedList));

打印结果如下:
ArrayList是否与LinkedList相等true
Map中也一样

2.subList只是返回List的一个视图

源码如下:

public List<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, 0, fromIndex, toIndex);
    }

 private class SubList extends AbstractList<E> implements RandomAccess {
        private final AbstractList<E> parent;
        private final int parentOffset;
        private final int offset;
        int size;

        SubList(AbstractList<E> parent,
                int offset, int fromIndex, int toIndex) {
            this.parent = parent;
            this.parentOffset = fromIndex;
            this.offset = offset + fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = ArrayList.this.modCount;
        }

        public E set(int index, E e) {
            rangeCheck(index);
            checkForComodification();
            E oldValue = ArrayList.this.elementData(offset + index);
            ArrayList.this.elementData[offset + index] = e;
            return oldValue;
        }

        public E get(int index) {
            rangeCheck(index);
            checkForComodification();
            return ArrayList.this.elementData(offset + index);
        }

        public int size() {
            checkForComodification();
            return this.size;
        }

        public void add(int index, E e) {
            rangeCheckForAdd(index);
            checkForComodification();
            parent.add(parentOffset + index, e);
            this.modCount = parent.modCount;
            this.size++;
        }
        。。。。其他方法省略

subList返回new SubList(),其中add等方法是在原数组上添加
因此会看到如下现象

ArrayList a1 = new ArrayList();
a1.add(1);
List a3 = a1.subList(0,a1.size());
a3.add(2);
System.out.println("a1==a3:"+a1.equals(a3));
for (int i = 0; i <a1.size() ; i++) {
    System.out.println(a1.get(i));
}

打印如下:
a1==a3:true
1 2
但是建立视图以后,不允许修改原List

 ArrayList a1 = new ArrayList();
 a1.add(1);
 List a3 = a1.subList(0,a1.size());
 a3.add(2);
 a1.add(3);

就会报java.util.ConcurrentModificationException
原因如下:

*//ArrayList里面的add方法*
public void add(E e) {
	*//add执行之前会进行并发检查*
    checkForComodification();

    try {
        int i = cursor;
        ArrayList.this.add(i, e);
        cursor = i + 1;
        lastRet = -1;
        expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
    }
}

 final void checkForComodification() {
	*//会对比这两个数是否相等*		 
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

*//但是subList里面的add方法*
 public void add(int index, E e) {
     rangeCheckForAdd(index);
     checkForComodification();
     parent.add(parentOffset + index, e);
     this.modCount = parent.modCount;
     this.size++;
 }
 *没有改expectedModCount,所以会导致校验不通过抛异常*

局部批量删除,可以subList.clear();验证如下

 ArrayList a1 = new ArrayList();
 for (int i = 0; i <100 ; i++) {
     a1.add(Math.random());
 }
 List a3 = a1.subList(0,20);
 a3.clear();
 System.out.println(a1.size());

打印结果如下:
80

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
0
获赞与收藏
3

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消