Thinking in java 读书笔记(八.2:abstractCollection、List和AbstractList阅读)
2018-02-21 22:55
465 查看
AbstractCollection继承collection,只抽象了两个方法,因为其他方法基本都是可以使用迭代器实现的。
而List接口是增加了八个接口,两个ListIterator方法(ListIterator是可以双向遍历的一种迭代器,只适用于list),两个搜索操作(indexOf,lastIndexof),四个Positional Access Operations。
AbstractList感觉是精华啊,这个类里面实现了Iterator和ListIterator,ListIterator是只用于list的迭代器,提供向前遍历的功能。然后是一层一层抽象下来,到abstractList为止,只剩下最基本的增删改查(add(int index, E element), remove(int index),set(int index, E element),public E get)没有实现,其他的方法都已经实现好了。也就是说其他所有的逻辑都可以通过这四个方法组合。好特么厉害啊,逻辑清晰而且代码复用率高。
还有一点很出乎意料的就是sublist,本来还以为sublist会新建一个list然后将元素添加进去,结果原来是直接持有原来的对象,仅仅是限制了下标。其实仔细想想也应该的,如果再添加一次不是白白浪费计算时间了= =。
还有一点就是RandomAccess接口的用处。
RandomAccess是用来标记collection的,如果某个容器实现了这个接口,那么这个容器更适合使用for循环来遍历,
AbstractCollection两个地方比较注意,一个是对于数组越界的处理,一个是数组容量的处理。emmm只能说写的真的很严谨= =。
而List接口是增加了八个接口,两个ListIterator方法(ListIterator是可以双向遍历的一种迭代器,只适用于list),两个搜索操作(indexOf,lastIndexof),四个Positional Access Operations。
AbstractList感觉是精华啊,这个类里面实现了Iterator和ListIterator,ListIterator是只用于list的迭代器,提供向前遍历的功能。然后是一层一层抽象下来,到abstractList为止,只剩下最基本的增删改查(add(int index, E element), remove(int index),set(int index, E element),public E get)没有实现,其他的方法都已经实现好了。也就是说其他所有的逻辑都可以通过这四个方法组合。好特么厉害啊,逻辑清晰而且代码复用率高。
还有一点很出乎意料的就是sublist,本来还以为sublist会新建一个list然后将元素添加进去,结果原来是直接持有原来的对象,仅仅是限制了下标。其实仔细想想也应该的,如果再添加一次不是白白浪费计算时间了= =。
还有一点就是RandomAccess接口的用处。
RandomAccess是用来标记collection的,如果某个容器实现了这个接口,那么这个容器更适合使用for循环来遍历,
AbstractCollection两个地方比较注意,一个是对于数组越界的处理,一个是数组容量的处理。emmm只能说写的真的很严谨= =。
public abstract class MyAbstractCollection<E> implements MyCollection<E> { protected MyAbstractCollection(){} public abstract Iterator<E> iterator(); public abstract int size(); @Override public boolean isEmpty() { return size()==0; } @Override public boolean contains(Object o) { Iterator<E> iterator = iterator(); if (o==null){ //当collection为null,输入为null时返回true while (iterator.hasNext()){ if (iterator.next()==null){ return true; } } }else { while (iterator.hasNext()){ if (o.equals(iterator.next())){ return true; } } } return false; } /*将list以数组的形式返回*/ @Override public Object[] toArray() { Object[] r = new Object[size()];//定义一个等大小的数组 Iterator<E> iterator = iterator(); for (int i=0;i<r.length;i++){ if (!iterator.hasNext()){ //如果list中的实际元素数量小于size。为什么会有这种情况?会因为因为多线程搞成这样? //返回实际元素的数组. return Arrays.copyOf(r,i); } r[i] = iterator.next(); } //如果实际元素特么的比size多,返回finishToArray //是为什么会存在实际元素更多的情况。 return iterator.hasNext()? finishToArray(r,iterator): r; } @Override @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { int size = size(); //使用反射来创建数组 T[] r = a.length >= size ? a : (T[])java.lang.reflect.Array .newInstance(a.getClass().getComponentType(), size); Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (! it.hasNext()) { // collection中的数量小于期望值 if (a == r) { r[i] = null; // null-terminate } else if (a.length < i) { return Arrays.copyOf(r, i); } else { System.arraycopy(r, 0, a, 0, i); if (a.length > i) { a[i] = null; } } return a; } r[i] = (T)it.next(); } // more elements than expected return it.hasNext() ? finishToArray(r, it) : r; } //为什么要-8呢,因为这是个对象数组,而不是一个基础类型的数组,需要留有空间来描述这个对象 //The object header consists of a mark word and a klass pointer. //The mark word has word size (4 byte on 32 bit architectures, 8 byte on 64 bit architectures) and //the klass pointer has word size on 32 bit architectures. On 64 bit architectures the klass pointer either has word size, // but can also have 4 byte if the heap addresses can be encoded in these 4 bytes. /** * @see <a href="https://stackoverflow.com/questions/35756277/why-the-maximum-array-size-of-arraylist-is-integer-max-value-8"> * 为什么数组最大值减8</a> * */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8; @SuppressWarnings("unchecked") private static <T> T[] finishToArray(T[] r,Iterator<?> iterator){ int i = r.length; while (iterator.hasNext()){ int cap = r.length; if (i == cap){ //数组扩容 int newCap = cap + (cap >> 1)+1; //扩容后的数组容量过大, if (newCap-MAX_ARRAY_SIZE>0){ newCap = hugeCapacity(cap+1); } //扩容后数组转移 r = Arrays.copyOf(r,newCap); } r[i++] = (T)iterator.next(); } // trim if overallocated return (i==r.length)? r: Arrays.copyOf(r,i); } private static int hugeCapacity(int minCapacity){ if(minCapacity < 0 ){//意味着大于MaxInteger了 throw new OutOfMemoryError("Required array size too large"); } return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } /*为什么一直抛出异常= =*/ @Override public boolean add(E e) { throw new UnsupportedOperationException(); } /** * 能用迭代器解决的问题都用迭代器些了 * */ @Override public boolean remove(Object o) { Iterator<E> iterator = iterator(); if (o == null){ while (iterator.hasNext()){ if (iterator.next() == null){ iterator.remove(); return true; } } }else { while (iterator.hasNext()){ if (o.equals(iterator.next())){ iterator.remove(); return true; } } } return false; } @Override public boolean containsAll(MyCollection<?> collection) { for (Object o:collection){ if (!contains(o)) return false; } return true; } //所以这里其实是只要有改变就返回true,而不需要全部确认插入 @Override public boolean addAll(MyCollection<? extends E> collection) { boolean modified = false; for (E e:collection){ if (add(e)) modified = true; } return modified; } //写到这里下意识remove的时候想调用class中的remove方法= =,但是这样会多遍历一遍 @Override public boolean removeAll(MyCollection<?> collection) { if (collection == null) throw new NullPointerException(); boolean modified = false; Iterator<E> iterator = iterator(); while (iterator.hasNext()){ if (collection.contains(iterator.next())){ iterator.remove(); modified = true; } } return modified; } @Override public void clear() { Iterator<E> iterator = iterator(); while (iterator.hasNext()){ iterator.next(); iterator.remove(); } } @Override public String toString() { Iterator<E> iterator = iterator(); if (! iterator.hasNext()) return "[]"; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append('['); for (;;){ E e = iterator.next(); stringBuilder.append(e == this?"(this collection)":e); if (!iterator.hasNext()) return stringBuilder.append(']').toString(); stringBuilder.append(',').append(' '); } } } public interface List<E> extends MyCollection<E>{ @Override int size(); @Override boolean isEmpty(); @Override boolean contains(Object o); @Override Iterator iterator(); @Override Object[] toArray(); @Override Object[] toArray(Object[] a); @Override boolean add(Object o); @Override boolean remove(Object o); @Override boolean containsAll(MyCollection collection); @Override boolean addAll(MyCollection collection); boolean addAll(int index, MyCollection<? extends E> collection); @Override boolean removeAll(MyCollection collection); @Override void clear(); @Override int hashCode(); @Override boolean equals(Object o); E get(int index); E set(int index,E element); void add(int index,E element); E remove(int index); int indexOf(Object o); int lastIndexOf(Object o); ListIterator<E> listIterator(); ListIterator<E> listIterator(int index);
//具体的迭代器在这个abstract中实现。 public abstract class MyAbstractList<E> extends MyAbstractCollection<E> implements MyList<E> { protected MyAbstractList(){} //Iterators //修饰该变量不需要参与序列化过程, //用于记录该容器的修改次数 protected transient int modCount = 0; private class Itr implements Iterator<E>{ //这里的cursor = next;lastRet=current; 1003e int cursor = 0; int lastRet = -1; int expectedModeCount = modCount; @Override public boolean hasNext() { return cursor!=size(); } @Override public E next() { checkDorComodification(); try { int i= cursor; E next = get(i); lastRet = i; cursor = i+1; return next; }catch (IndexOutOfBoundsException e){ checkDorComodification(); throw new NoSuchElementException(); } } final void checkDorComodification(){ if (modCount != expectedModeCount) throw new ConcurrentModificationException(); } } private class ListItr extends Itr implements ListIterator<E>{ //cursor = next; ListItr(int index){ cursor = index; } @Override public boolean hasPrevious() { return cursor!=0; } @Override public E previous() { checkDorComodification(); try { int i = cursor-1; E privious = get(i); lastRet = cursor = i; return privious; }catch (IndexOutOfBoundsException e){ checkDorComodification(); throw new NoSuchElementException(); } } @Override public int nextIndex() { return cursor; } @Override public int previousIndex() { return cursor-1; } @Override public void remove() { if (lastRet<0) throw new IllegalStateException(); checkDorComodification(); } @Override public void set(E e) { if (lastRet<0){ throw new IllegalStateException(); } checkDorComodification(); try { MyAbstractList.this.set(lastRet,e); expectedModeCount = modCount; }catch (IndexOutOfBoundsException e1){ throw new ConcurrentModificationException(); } } @Override public void add(E e) { checkDorComodification(); try{ int i = cursor; MyAbstractList.this.add(i,e); lastRet = -1; cursor = i+1; expectedModeCount = modCount; }catch (IndexOutOfBoundsException ex){ throw new ConcurrentModificationException(); } } } @Override public Iterator<E> iterator() { return new Itr(); } @Override public ListIterator<E> listIterator() { return listIterator(0); } @Override public ListIterator<E> listIterator(final int index) { rangeCheckForAdd(index); return new ListItr(index); } private void rangeCheckForAdd(int index){ if (index<0||index>size()){ throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } } //能用方法互相调用的,就不要用到持有的属性, //比如说这里要是我自己写,,,一定是又写一遍逻辑 //这么想其实逻辑相近的接口互相调用着实现,能省很多的代码= =。 public boolean add(E e) { add(size(),e); return true; } abstract public E get(int index); @Override public E set(int index, E element) { throw new UnsupportedOperationException(); } @Override public void add(int index, E element) { throw new UnsupportedOperationException(); } @Override public E remove(int index) { throw new UnsupportedOperationException(); } @Override public int indexOf(Object o) { ListIterator<E> iterator = listIterator(); if(o == null){ while (iterator.hasNext()){ if (iterator.next()==null){ return iterator.previousIndex(); } } }else { while (iterator.hasNext()){ if (o.equals(iterator.next())) return iterator.previousIndex(); } } return -1; } @Override public int lastIndexOf(Object o) { ListIterator<E> iterator = listIterator(size()); if (o==null){ while (iterator.hasPrevious()){ if (iterator.previous()==null)return iterator.nextIndex(); } } else { while (iterator.hasPrevious()){ if (o.equals(iterator.previous())){ return iterator.nextIndex(); } } } return -1; } @Override public void clear() { removeRange(0,size()); } @Override public boolean addAll(int index, MyCollection<? extends E> collection) { rangeCheckForAdd(index); boolean modified =false; for (E e:collection){ add(index++,e); modified = true; } return modified; } protected void removeRange(int fromIndex, int toIndex){ ListIterator<E> listIterator = listIterator(fromIndex); for (int i=0,n=toIndex-fromIndex;i<n;i++){ listIterator.next(); listIterator.remove(); } } @Override public boolean equals(Object obj) { //不是本身并且是list的子类的情况下使用迭代器一个个比对数据 if (obj == this)return true; if (!(obj instanceof MyList)) return false; ListIterator<E> e1 = listIterator(); ListIterator<?> e2 = ((MyList<?>)obj).listIterator(); while (e1.hasNext() && e2.hasPrevious()){ E o1 = e1.next(); Object o2 = e2.next(); //不知道嘛时候写逻辑的时候我能马上想到这样写= = if (!(o1==null ? o2 == null : o1.equals(o2))) return false; } //长度不一样 return !(e1.hasNext()||e2.hasNext()); } @Override public int hashCode() { int hashcode = 1; for (E e:this){ hashcode = 31*hashcode+(e==null?0:e.hashCode()); } return hashcode; } private String outOfBoundsMsg(int index){ return "Index: "+index+", Size: "+size(); } } //本来还以为sublist会新建一个list然后将元素添加进去, // 结果原来是直接持有原来的对象,仅仅是限制了下标。 class MySubList<E> extends MyAbstractList<E>{ private final MyAbstractList<E> l; private final int offset ; private int size ; MySubList(MyAbstractList<E> list,int fromIndex,int toIndex){ if (fromIndex<0){ throw new IndexOutOfBoundsException("fromIndex = "+fromIndex); } if (toIndex>list.size()){ throw new IndexOutOfBoundsException("toIndex = "+toIndex); } if (fromIndex > toIndex){ throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); } l = list; offset = fromIndex; size = toIndex-fromIndex; this.modCount = l.modCount; } private void rangeCheckForAdd(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } private void checkForComodification() { if (this.modCount != l.modCount) throw new ConcurrentModificationException(); } private void rangeCheck(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //真是每次都需要检查一遍越界异常哦,,, @Override public E get(int index) { rangeCheck(index); checkForComodification(); return l.get(index+offset); } @Override public E set(int index, E element) { rangeCheck(index); checkForComodification(); return l.set(index+offset, element); } @Override public void add(int index, E element) { rangeCheckForAdd(index); checkForComodification(); l.add(index+offset,element); this.modCount = l.modCount; size++; } @Override public E remove(int index) { rangeCheck(index); checkForComodification(); E result = l.remove(index+offset); this.modCount = l.modCount; size--; return result; } @Override protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); l.removeRange(fromIndex+offset,toIndex+offset); this.modCount = l.modCount; size -= (toIndex-fromIndex); } @Override public boolean addAll(MyCollection<? extends E> collection) { return addAll(size,collection); } @Override public boolean addAll(int index, MyCollection<? extends E> collection) { rangeCheck(index); int cSize = collection.size(); if (cSize==0)return false; checkForComodification(); l.addAll(offset+index,collection); this.modCount = l.modCount; size+=cSize; return true; } @Override public Iterator<E> iterator() { return listIterator(); } @Override public ListIterator<E> listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); return new ListIterator<E>() { private final ListIterator<E> iterator = l.listIterator(index+offset); @Override public boolean hasNext() { return nextIndex()<size; } @Override public E next() { if (hasNext()) return iterator.next(); else throw new NoSuchElementException(); } @Override public boolean hasPrevious() { return previousIndex()>=0; } @Override public E previous() { if (hasPrevious()) return iterator.previous(); else throw new NoSuchElementException(); } @Override public int nextIndex() { return iterator.nextIndex()-offset; } @Override public int previousIndex() { return iterator.previousIndex()-offset; } @Override public void remove() { iterator.remove(); MySubList.this.modCount = l.modCount; size--; } @Override public void set(E e) { iterator.set(e); } @Override public void add(E e) { iterator.add(e); MySubList.this.modCount = l.modCount; size++; } }; } @Override public MyList<E> subList(int fromIndex, int toIndex) { return new MySubList<E>(this, fromIndex, toIndex); } @Override public int size() { checkForComodification(); return size; } } class RandomAccessSublist<E> extends MySubList<E> implements RandomAccess{ RandomAccessSublist(MyAbstractList<E> list, int fromIndex, int toIndex) { super(list, fromIndex, toIndex); } public MyList<E> subList(int fromIndex, int toIndex) { return new RandomAccessSublist<E>(this, fromIndex, toIndex); } }
相关文章推荐
- thinking in java 阅读笔记 第一章 对象入门
- thinking in java 阅读笔记 第一章 对象入门
- thinking in java 阅读笔记 第二章 一切都是对象
- thinking in java 阅读笔记 第三章 程序控制流程
- thinking in java 阅读笔记 第四章 初始化和清除
- thinking in java 阅读笔记 第六章 类再生
- thinking in java 阅读笔记 第六章 类再生
- Thinking in java 读书笔记(七.1:内部类:匿名内部类和内部类的简单应用)
- Thinking In Java 第四版读书笔记
- thinking in java 阅读笔记 第一章 对象入门
- thinking in java 阅读笔记 第二章 一切都是对象
- thinking in java 阅读笔记 第三章 程序控制流程
- Thinking in java 4th Edition 读书笔记-I/O(3)
- thinking in java 阅读笔记 第四章 初始化和清除
- thinking in java 阅读笔记 第六章 类再生
- thinking in java 阅读笔记 第六章 类再生
- Thinking in java 4th Edition 读书笔记-I/O(5)
- Thinking in java 4th Edition 读书笔记-I/O(6)
- java源码阅读系列-LinkedList
- Thinking in Java第三版读书笔记-第四章:初始化与清理