---------------------- android培训、java培训、期待与您交流! ----------------------
从模拟JAVA中的集合类Collection开始
首先写一个实体类:Cat
public class Cat { private int id; public Cat(int id) { this.id = id; } @Override public String toString() { return "cat:" + id; } }
现在我想写一个模拟JAVA中的ArrayList的集合类,可以动态添加Cat对象:
为了可扩展性,让集合类统一实现一个Collection接口:
public interface Collection { void add(Object o); int size(); }
public class ArrayList implements Collection { Object[] objects = new Object[10]; private int index = 0; @Override public void add(Object o) { if (objects.length == index) { Object[] extObjects = new Object[objects.length * 2]; System.arraycopy(objects, 0, extObjects, 0, objects.length); objects = extObjects; } objects[index] = o; index++; } @Override public int size() { return index; } }
我还想用链表方式实现动态添加Cat对象的集合:LinkedList
节点类:
public class Node { private Object data; // 组成链表的节点 private Node next; // 某个节点的下一个节点 public Node(Object data, Node next) { this.data = data; this.next = next; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } }
链表实现:public class LinkedList implements Collection { private Node head = null; private Node tail = null; private int size = 0; @Override public void add(Object o) { Node n = new Node(o, null); if (head == null) { head = n; tail = n; } tail.setNext(n); tail = n; size++; } @Override public int size() { return size; } }
如果在测试类中遍历集合类中的元素,可以在ArrayList或LinkedList中加一个方法(这里暂且叫show()),然后调用这个方法。
但将业务逻辑写在实体类中的做法显然是不恰当的!
而且由于ArrayList或LinkedList的遍历方式不同,如果需要更改Collection的实现方式(把ArrayList换成LinkedList),相应的遍历算法也要更改,显然扩展性不好。
这时就应该想到能否提供一个统一的接口来遍历ArrayList或LinkedList中的元素:
在ArrayList或LinkedList中封装各自的遍历方式,在外部调用时可以统一的方法来得到集合中的元素。
具体实现:在ArrayList或LinkedList中将遍历元素的类封装成内部类(假如类名是:Itr),实现一个统一的接口(这里叫Iterator,模仿JDK)。
并在集合类ArrayList或LinkedList中添加一个实现了Collection接口中的方法:Iterator<E> iterator() 返回一个Iterator类型的对象。
因此遍历容器时只要调用容器类对象的iterator()方法返回Iterator类型的对象(假如是Itr),循环调用Itr从Iterator接口实现的hasNext()和next()方法。
修改后的代码:
public interface Collection { void add(Object o); int size(); Iterator iterator(); }
public interface Iterator { Object next(); boolean hasNext(); }
public class LinkedList implements Collection { private Node head = null; private Node tail = null; private int size = 0; @Override public void add(Object o) { Node n = new Node(o, null); if (head == null) { head = n; tail = n; } tail.setNext(n); tail = n; size++; } @Override public int size() { return size; } @Override public Iterator iterator() { return new LLItr(); } private class LLItr implements Iterator { private Node currentNode = head; @Override public Object next() { Object o = currentNode.getData(); currentNode = currentNode.getNext(); return o; } @Override public boolean hasNext() { if (null == currentNode) return false; else return true; } } }
public class ArrayList implements Collection { Object[] objects = new Object[10]; private int index = 0; @Override public void add(Object o) { if (objects.length == index) { Object[] extObjects = new Object[objects.length * 2]; System.arraycopy(objects, 0, extObjects, 0, objects.length); objects = extObjects; } objects[index] = o; index++; } @Override public int size() { return index; } @Override public Iterator iterator() { return new ALItr(); } private class ALItr implements Iterator { private int currentIndex = 0; @Override public Object next() { Object o = objects[currentIndex]; currentIndex++; return o; } @Override public boolean hasNext() { if (currentIndex >= index) return false; else return true; } } }
显然在测试类中可以这样写:public class Test { public static void main(String[] args) { Collection c = new LinkedList(); for (int i = 0; i < 5; i++) { c.add(new Cat(i)); } System.out.println(c.size()); Iterator itr = c.iterator(); while (itr.hasNext()) { System.out.println(itr.next()); } } }
问题:为何不把hasNext()和next()方法放在Collection接口中而单独定义一个Iterator接口
“接口隔离原则”:一个类实现多个接口,当使用这个类时,若只需要用到某个接口中的方法,则没必要了解其它接口的存在,即接口定义越细越好!
例如:我只想遍历容器中的元素,就没必要了解Collection接口中的add()、size()、remove()等方法!
下面是类的关系图解:
---------------------- android培训、java培训、期待与您交流! ----------------------