zoukankan      html  css  js  c++  java
  • java源码 -- AbstractList

    AbstractList

      AbstractList是实现List接口的抽象类,AbstractList抽象类与List接口的关系类似于AbstractCollection抽象类与Collection接口的关系。

      AbstractList与AbstractCollection一样,也是通过提供一些方法的默认实现,简化我们编写List接口的列表类所需付出的努力。

    实现列表类的需要记住:

      1)要想实现一个不可修改的集合,只需要继承这个类,并且实现get(int)、size()方法;
      2)要想实现一个可以修改的集合,还必须重写set(int, E)方法,该方法默认抛出一个异常。如果集合是可动态调整大小的,还必须重写add(int, E),remove(int)方法。

    方法

     public boolean add(E e){}

    public boolean add(E e) {
            add(size(), e);  //通过调用add(int, E)方法进行添加
            return true;
        }

    //以下方法没有具体的实现,调用它时,抛出异常。

    public void add(int index, E element){ throw new UnsupportedOperationException(); }
    public E set(int index, E element) { throw new UnsupportedOperationException(); }
    public E remove(int index) {throw new UnsupportedOperationException();}

    abstract public E get(int index); //无实现

    // Search Operations搜索操作
    //通过迭代器,循环找出内容
    public int indexOf(Object o) {
            ListIterator<E> it = listIterator();
            if (o==null) { //如果参数为空
                while (it.hasNext())
                    if (it.next()==null) //找出内容为空
                        return it.previousIndex(); //返回
            } else {
                while (it.hasNext())
                    if (o.equals(it.next()))
                        return it.previousIndex();
            }
            return -1;
        }
    public int
    lastIndexOf(Object o) {
        ListIterator<E> it = listIterator(size());
    if (o==null) {
    while (it.hasPrevious())
    if (it.previous()==null)
    return it.nextIndex();
    } else {
    while (it.hasPrevious())
    if (o.equals(it.previous()))
    return it.nextIndex();
    }
    return -1;
    }

      // Bulk Operations 批量操作

    //清空集合
    public
    void clear() { removeRange(0, size()); //调用removeRange()方法删除 }
    // 参数是删除的范围。
     protected void removeRange(int fromIndex, int toIndex) {
            ListIterator<E> it = listIterator(fromIndex);
            for (int i=0, n=toIndex-fromIndex; i<n; i++) {
                it.next();
                it.remove();
            }
        }
    // 在集合中添加集合
    public boolean addAll(int index, Collection<? extends E> c) {
           rangeCheckForAdd(index);
           boolean modified = false;
           for (E e : c) { //foreach循环添加
                add(index++, e);
                modi= true;
            }
            return mod    }

      // Iterators迭代器

    两个迭代器实现类

      AbstractList 中提供了两个迭代器的实现类,默认实现了迭代器接口,实现了对元素的遍历,它们就是Itr 和其子类 ListItr,分别来了解一下。

    Itr类,实现了Iterator接口,重写了next() 和 remove() 方法

    private class Itr implements Iterator<E> {
        //游标
        int cursor;
        //最近迭代的元素位置,每次使用完默认置为-1
        int lastRet;
        //记录容器被修改的次数,值不相等说明有并发操作
        int expectedModCount = modCount;
      //是否有下一个元素,就是游标是否不等于集合大小。等于的话 游标在集合末尾 则没有下一个元素
        public boolean hasNext() {
            return cursor != size();
        }
    
    public E next() {
        //检测是否有并发
        checkForComodification();
        try {
            int i = cursor;
            // 获取容器对应游标位置的元素
            E next = get(i);
            //记录获取到的元素的索引
            lastRet = i;
            //获取下一个元素的索引
            cursor = i + 1;
            return next;
        } catch (IndexOutOfBoundsException var3) {
            checkForComodification();
            throw new NoSuchElementException();
        }
    }
    public void remove() {
        //还没读取元素就remove,报错
      if (lastRet < 0)
      throw new IllegalStateException();
      checkForComodification();

      try {
      AbstractList.this.remove(lastRet);
      if (lastRet < cursor) //删除之后,集合中少了一个元素,满足条件 游标自减 后退一个元素
      cursor--;
      lastRet = -1;
      expectedModCount = modCount;
      } catch (IndexOutOfBoundsException e) {
      throw new ConcurrentModificationException();
      }
      }
      //并发异常
      final void checkForComodification() {
      if (modCount != expectedModCount)
      throw new ConcurrentModificationException();
      }
    }


    ListItr Itr 的子,在Itr 的基础上增强了对元素的操作,多了指定索引的赋值,以及向前读取,add 和 set 的方法。

    private class ListItr extends Itr implements ListIterator<E> {
            ListItr(int index) {
                cursor = index; ////设置游标为指定值
            }
         ////游标不为第一个的话,前面都有元素的
            public boolean hasPrevious() {
                return cursor != 0;
            }
    
            public E previous() {
                checkForComodification();
                try {
                    int i = cursor - 1;
             //获取游标的前一个元素 E previous
    = get(i);
             //把最后操作的位置和游标都前移一位 lastRet
    = cursor = i; return previous; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public int nextIndex() { return cursor; } public int previousIndex() { return cursor-1; } public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.set(lastRet, e); expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void add(E e) { checkForComodification(); try { int i = cursor; AbstractList.this.add(i, e); lastRet = -1; cursor = i + 1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }

        AbstractList类中提供了两个方法,返回的各自实现的接口类型对象:

    public Iterator<E> iterator() {
        return new Itr();
    }
    public ListIterator<E> listIterator() {
        return listIterator(0);
    }
    public ListIterator<E> listIterator(final int index) {
        rangeCheckForAdd(index);
    
        return new ListItr(index);
    }

    两个子类

      AbstractList 提供了两个子类,可用于切分集合序列,这两个类是 SubListRandomAccessSubList

      1. SubList 的内部实现和 AbstractList 很相似,无非是传递了两个变量,返回指定的fromIndex (含)和toIndex之间的列表部分的视图,初识位置和结束位置来截取集合。

      2. RandomAccessSubList 是 SubList 的子类,内部实现直接沿用父类,只是实现了RandomAccess接口。

       不一样的是,RandomAccessSubList 实现了一个接口RandomAccess,打开后发现是空的,没有任何实现。

       它的作用是用于标识某个类是否支持 随机访问(随机访问,相对比“按顺序访问”)。一个支持随机访问的类明显可以使用更加高效的算法。例如遍历上,实现RandomAccess 接口的集合使用 get() 做迭代速度会更快,比起使用迭代器的话。

    感谢:https://blog.csdn.net/u013164931/article/details/79640715

  • 相关阅读:
    第六周作业
    第二次作业
    自我介绍
    2019春总结作业
    2019春第四次课程设计实验报告
    2019春第三次课程设计实验报告
    2019春第二次课程设计实验报告
    2019春第一次课程设计实验报告
    第十二周编程总结
    第十一周编程总结
  • 原文地址:https://www.cnblogs.com/FondWang/p/11922340.html
Copyright © 2011-2022 走看看