博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
向大师学习怎样使用嵌套类
阅读量:6181 次
发布时间:2019-06-21

本文共 14003 字,大约阅读时间需要 46 分钟。

hot3.png

图1  嵌套类

       如上图一所示是嵌套类的分类和一些使用策略,主要需要注意的就是,嵌套类主要是为外部类服务的,最好是仅仅在外部类中使用,如在其他类中需要使用另外一个类的嵌套类,那么该嵌套类就应该做为顶级类,而不是嵌套类。

       如果需要使用嵌套类,那么优秀考虑静态成员类,可以参考 effictive java 2版 22节 优先考虑静态成员类。因为每一个非静态成员类的实例会维护一个外部类的实例,所以有空间和时间的开销。如果确实需要外部类的实例引用,例如要直接访问外部类的飞静态成员变量等,那么就可以考虑非静态成员类。

       如果只需要类的一个实例,并且有预置类型,例如很多继承Thread的类,或者实现Runnable的类就可以做成匿名类。如果没有预置类型就可以考虑局部类。

      上面讲了一些原因和策略,下面来看一下具体的应用,我们以LinkedList的源码为例,LinkedList也是Josh Block写的,代码里面对于嵌套类使用应该是对嵌套类使用的最佳实践了。

package java.util;/** *  * List 和 Deque双向链表的实现 * */public class LinkedList
extends AbstractSequentialList
implements List
, Deque
, Cloneable, java.io.Serializable{ //3个成员变量都是transient修饰的,不会被系列化 transient int size = 0; transient Node
first; transient Node
last; public LinkedList() { } public LinkedList(Collection
c) { this(); addAll(c); } /** * 把元素放入双向链表中的第一个位置 * * 首先构造一个节点(Node),因为是插入在1个节点之前所以它的前一个(prev)节点为null, * 后一个节点(succ)就是原来的第一节点f */ private void linkFirst(E e) { final Node
f = first; final Node
newNode = new Node<>(null, e, f); first = newNode; //f为null说明原来没有节点,所以第一个节点也是最后一个节点,last也指向它 if (f == null) last = newNode; else f.prev = newNode;//如果原来链表不为null,新节点(newNode)就是原来第一个节点的前一个(prev)节点 size++; modCount++; } /** * 把元素放入双向链表中的最后一个位置 * * 因为是插入在最后一个位置,所以新的节点的前一个节点(prev)就是 * 原来的最后一个节点,后一个节点(succ)为null */ void linkLast(E e) { final Node
l = last; final Node
newNode = new Node<>(l, e, null); last = newNode; if (l == null)//如果最后一个节点为空,说明链表原来为空,新节点既是最后一个也是第一个节点 first = newNode; else l.next = newNode; size++; modCount++; } /** * 把指定元素插入都指定元素succ之前 */ void linkBefore(E e, Node
succ) { // assert succ != null; final Node
pred = succ.prev; final Node
newNode = new Node<>(pred, e, succ); succ.prev = newNode;//把succ节点的前一个(pred)节点设置为新节点(newNode) if (pred == null)//如果succ的原来的前一个节点为null,说明succ节点是第一个节点 first = newNode; else pred.next = newNode; //把新节点的后一个(next)节点设置为succ size++; modCount++; } /** * 移除第一个元素 */ private E unlinkFirst(Node
f) { // assert f == first && f != null; final E element = f.item; final Node
next = f.next; f.item = null; f.next = null; // help GC first = next; if (next == null) last = null; else next.prev = null; size--; modCount++; return element; } /** * 移除最后一个元素 */ private E unlinkLast(Node
l) { // assert l == last && l != null; final E element = l.item; final Node
prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; } /** * Unlinks non-null node x. */ E unlink(Node
x) { // assert x != null; final E element = x.item; final Node
next = x.next; final Node
prev = x.prev; if (prev == null) { first = next; } else { prev.next = next; x.prev = null; } if (next == null) { last = prev; } else { next.prev = prev; x.next = null; } x.item = null; size--; modCount++; return element; } /** * 获取第一个节点元素O(1) * */ public E getFirst() { final Node
f = first; if (f == null) throw new NoSuchElementException(); return f.item; } /** * 获取最后一个节点元素O(1) * */ public E getLast() { final Node
l = last; if (l == null) throw new NoSuchElementException(); return l.item; } /** * 移除第一个元素O(1) * */ public E removeFirst() { final Node
f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); } /** * 移除最后一个O(1) * */ public E removeLast() { final Node
l = last; if (l == null) throw new NoSuchElementException(); return unlinkLast(l); } /** * 把元素e插入双向链表的第一个位置 * O(1) */ public void addFirst(E e) { linkFirst(e); } /** * 把元素插入双向链表最后一个位置 * O(1) * */ public void addLast(E e) { linkLast(e); } /** * 检查是否包含指定元素O(n) */ public boolean contains(Object o) { return indexOf(o) != -1; } /** * 返回元素个数 * */ public int size() { return size; } /** * 把元素插入双向链表最后一个位置 * O(1) * */ public boolean add(E e) { linkLast(e); return true; } /** * * */ public boolean remove(Object o) { if (o == null) { for (Node
x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { for (Node
x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } /** * * */ public boolean addAll(Collection
c) { return addAll(size, c); } /** * * */ public boolean addAll(int index, Collection
c) { checkPositionIndex(index); Object[] a = c.toArray(); int numNew = a.length; if (numNew == 0) return false; Node
pred, succ; if (index == size) { succ = null; pred = last; } else { succ = node(index); pred = succ.prev; } for (Object o : a) { @SuppressWarnings("unchecked") E e = (E) o; Node
newNode = new Node<>(pred, e, null); if (pred == null) first = newNode; else pred.next = newNode; pred = newNode; } if (succ == null) { last = pred; } else { pred.next = succ; succ.prev = pred; } size += numNew; modCount++; return true; } /** * 帮助GC * */ public void clear() { // Clearing all of the links between nodes is "unnecessary", but: // - helps a generational GC if the discarded nodes inhabit // more than one generation // - is sure to free memory even if there is a reachable Iterator for (Node
x = first; x != null; ) { Node
next = x.next; x.item = null; x.next = null; x.prev = null; x = next; } first = last = null; size = 0; modCount++; } /** * 获取指定位置的元素 * */ public E get(int index) { checkElementIndex(index); return node(index).item; } /** * * 使用指定元素替换指定位置的元素 */ public E set(int index, E element) { checkElementIndex(index); Node
x = node(index); E oldVal = x.item; x.item = element; return oldVal; } /** * * 把指定元素插入都指定位置之前 * */ public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index)); } /** * 移除指定位置的元素 * */ public E remove(int index) { checkElementIndex(index); return unlink(node(index)); } /** * 判断指定元素是否存在 */ private boolean isElementIndex(int index) { return index >= 0 && index < size; } /** * 检查是否可是一个合法的索引或者可以添加元素的位置 */ private boolean isPositionIndex(int index) { return index >= 0 && index <= size; } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } private void checkElementIndex(int index) { if (!isElementIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private void checkPositionIndex(int index) { if (!isPositionIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } /** * 获取指定位置的节点(Node) */ Node
node(int index) { // assert isElementIndex(index); //简单二分,size>>1等价于size/2 //如果index值小于元素的一半,就从第一个元素开始查找 //否则就从最后一个位置开始查找 if (index < (size >> 1)) { Node
x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node
x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } // Search Operations /** * * 查找指定元素的位置 O(n) * */ public int indexOf(Object o) { int index = 0; if (o == null) { for (Node
x = first; x != null; x = x.next) { if (x.item == null) return index; index++; } } else { for (Node
x = first; x != null; x = x.next) { if (o.equals(x.item)) return index; index++; } } return -1; } /** * 查找指定元素的位置 O(n) */ public int lastIndexOf(Object o) { int index = size; if (o == null) { for (Node
x = last; x != null; x = x.prev) { index--; if (x.item == null) return index; } } else { for (Node
x = last; x != null; x = x.prev) { index--; if (o.equals(x.item)) return index; } } return -1; } // Queue operations. /** * 获取第一个元素,但是不删除 * */ public E peek() { final Node
f = first; return (f == null) ? null : f.item; } /** * 获取第一个元素,但是不删除 * */ public E element() { return getFirst(); } /** * 获取并且删除第一个元素 * */ public E poll() { final Node
f = first; return (f == null) ? null : unlinkFirst(f); } /** * 获取并且删除第一个元素 * */ public E remove() { return removeFirst(); } /** * 把指定元素插入到链表末尾 * */ public boolean offer(E e) { return add(e); } /** * 把指定元素插入到链表开始 * */ public boolean offerFirst(E e) { addFirst(e); return true; } /** * 把指定元素插入到链表末尾 * */ public boolean offerLast(E e) { addLast(e); return true; } /** * 获取链表中的第一个元素 * * */ public E peekFirst() { final Node
f = first; return (f == null) ? null : f.item; } /** * 获取链表中的最后一个元素 * * */ public E peekLast() { final Node
l = last; return (l == null) ? null : l.item; } /** * 获取并且删除链表中第一个元素 * * */ public E pollFirst() { final Node
f = first; return (f == null) ? null : unlinkFirst(f); } /** * 获取并且删除链表中最后一个元素 * * */ public E pollLast() { final Node
l = last; return (l == null) ? null : unlinkLast(l); } /** * 把指定元素加入到链表开头O(1) */ public void push(E e) { addFirst(e); } /** * 移除链表第一个元素O(1) */ public E pop() { return removeFirst(); } /** * 移除链表中第一个指定元素 */ public boolean removeFirstOccurrence(Object o) { return remove(o); } /** * 移除链表中最后一个指定元素 */ public boolean removeLastOccurrence(Object o) { if (o == null) { for (Node
x = last; x != null; x = x.prev) { if (x.item == null) { unlink(x); return true; } } } else { for (Node
x = last; x != null; x = x.prev) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } /** * 返回一个迭代器 */ public ListIterator
listIterator(int index) { checkPositionIndex(index); return new ListItr(index); } /** * 非静态成员类,LinkedList迭代器,只是为LinkedList服务的 * 因为ListItr要使用外部类的非静态成员变量,需要外部实例的 * 引用,所以使用的是非静态内部类 */ private class ListItr implements ListIterator
{ private Node
lastReturned = null;//迭代器的前一个位置 private Node
next; private int nextIndex; //在类(ListItr)初始化的时候记录修改的次数,以便于检查在迭代过程中数据有没有修改 private int expectedModCount = modCount; ListItr(int index) { // assert isPositionIndex(index); next = (index == size) ? null : node(index);//初始化迭代器的开始位置 nextIndex = index;//初始化迭代器的开始索引值 } public boolean hasNext() { return nextIndex < size; } //把当前位置标记为前一个位置,然后next指向下一个位置 //下一个索引位置值+1,最后把迭代器当前位置的元素返回 public E next() { checkForComodification(); if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.item; } public boolean hasPrevious() { return nextIndex > 0; } public E previous() { checkForComodification(); if (!hasPrevious()) throw new NoSuchElementException(); lastReturned = next = (next == null) ? last : next.prev; nextIndex--; return lastReturned.item; } public int nextIndex() { return nextIndex; } public int previousIndex() { return nextIndex - 1; } //把迭代器当前位置的元素移除 public void remove() { checkForComodification(); if (lastReturned == null) throw new IllegalStateException(); Node
lastNext = lastReturned.next; unlink(lastReturned); if (next == lastReturned) next = lastNext; else nextIndex--; lastReturned = null; expectedModCount++; } public void set(E e) { if (lastReturned == null) throw new IllegalStateException(); checkForComodification(); lastReturned.item = e; } public void add(E e) { checkForComodification(); lastReturned = null; if (next == null) linkLast(e); else linkBefore(e, next); nextIndex++; expectedModCount++; } //这个的假设是不会在迭代过程中使用LinkedList的引用修改操作(参考LinkedListTest) //如果假设成立,那么只有在多线程中其他线程修改了LinkedList的实例才会满足 //modCount != expectedModCount条件,说明产生了脏数据,直接抛出异常 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } /** * * 私用静态内部类,为外部内LinkedList服务,作为LinkedList的一个组件 * 作为一个外部类的成员,外部类就可以像这样访问: * * final Node
f = first; * return (f == null) ? null : f.item; * */ private static class Node
{ E item; Node
next; Node
prev; Node(Node
prev, E element, Node
next) { this.item = element; this.next = next; this.prev = prev; } } public Iterator
descendingIterator() { return new DescendingIterator(); } /** * 反向迭代器类 */ private class DescendingIterator implements Iterator
{ private final ListItr itr = new ListItr(size()); public boolean hasNext() { return itr.hasPrevious(); } public E next() { return itr.previous(); } public void remove() { itr.remove(); } } @SuppressWarnings("unchecked") private LinkedList
superClone() { try { return (LinkedList
) super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } /** * 浅拷贝 */ public Object clone() { LinkedList
clone = superClone(); // Put clone into "virgin" state clone.first = clone.last = null; clone.size = 0; clone.modCount = 0; // Initialize clone with our elements for (Node
x = first; x != null; x = x.next) clone.add(x.item); return clone; } public Object[] toArray() { Object[] result = new Object[size]; int i = 0; for (Node
x = first; x != null; x = x.next) result[i++] = x.item; return result; } @SuppressWarnings("unchecked") public
T[] toArray(T[] a) { if (a.length < size) a = (T[])java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size); int i = 0; Object[] result = a; for (Node
x = first; x != null; x = x.next) result[i++] = x.item; if (a.length > size) a[size] = null; return a; } private static final long serialVersionUID = 876323262645176354L; /** * 系列化 */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject(); // Write out size s.writeInt(size); // Write out all elements in the proper order. for (Node
x = first; x != null; x = x.next) s.writeObject(x.item); } /** * 反系列化 */ @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject(); // Read in size int size = s.readInt(); // Read in all elements in the proper order. for (int i = 0; i < size; i++) linkLast((E)s.readObject()); }}
import java.util.LinkedList;import java.util.ListIterator;public class LinkedListTest {    public static void main(String[] args) {        LinkedList
list = new LinkedList
(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("e"); //一般我们不会像下面这样使用迭代器,不,是绝对不能 //那么引起ConcurrentModificationException异常 //就可能是其他线程修改了list的数据了 ListIterator
iterator = list.listIterator(); if(iterator.hasNext()) System.out.println(iterator.next()); list.add("f");//在迭代过程中不能使用获得迭代器的实例来修改数据 if(iterator.hasNext()) System.out.println(iterator.next()); }}

 

转载于:https://my.oschina.net/u/2474629/blog/702411

你可能感兴趣的文章
Ganglia监控Hadoop集群的安装部署
查看>>
java后台进程和线程优先级
查看>>
dede时间格试,dede时间标签
查看>>
Android代码中设置背景图片
查看>>
eclipse生成jar包
查看>>
Machine Learning - 第7周(Support Vector Machines)
查看>>
libaio under MIPS architecture /在mips架构下使用的libaio
查看>>
18. 使用模板【从零开始学Spring Boot】
查看>>
15、Spring Boot使用Druid和监控配置【从零开始学Spring Boot】
查看>>
Spring boot Security Disable security
查看>>
2017云栖大会大咖演讲PPT+视频官方资料合集来啦!
查看>>
今年全家福流行这样拍 华为手机的花式姿势上央视了
查看>>
从内到外无懈可击,努比亚Z17让你一见钟情!
查看>>
滴滴:按原计划恢复深夜出行服务 新版上线一键报警功能
查看>>
十年磨一剑 企业级互联网架构Aliware助力企业数字化转型
查看>>
一箱农村垃圾的“重生之旅”
查看>>
合江长江公路大桥飞燕式系杆拱桥首节主拱成功吊装
查看>>
中国气象局:2018年高温日数多 总的气候年景正常
查看>>
广西博物馆改扩建项目开工 将建设面向东盟文化交流窗口
查看>>
最新!2018年中国程序员薪资生活调查报告
查看>>