1.迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。 简单理解:对容器内元素遍历 2.迭代器模式角色划分 迭代器角色(Iterator):定义遍历元素所需要的方法,一般来说会有这么三个方法:取得下一个元素next(),判断是否遍历结束的方法hasNext(),移除当前对象的方法remove()。 具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代。 容器角色(Aggregate):一般是一个接口,提供一个iterator()方法,例如java中的Collection接口、List接口、Set接口等。 具体容器角色(Concrete Aggregate):就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
3.具体实例 大公司收购小公司(有员工信息) 大公司:保存员工信息,采用List集合保存 小公司:保存员工信息,采用数组保存 两个公司用不同数据类型(List 、Array)保存数据,现在读取他们 常规的写法:
public class Client {
public static void main(String[] args) {
AppleCompany appleCompany = new AppleCompany();
List<UserBean> users = appleCompany.getUserList();
for (UserBean userBean : users) {
System.out.println("用户信息:" + userBean.toString());
}
SmallCompany smallCompany = new SmallCompany();
UserBean[] userArray = smallCompany.getUserArray();
for ( UserBean userBean : userArray ) {
System.out.println("用户信息:" + userBean.toString());
}
}
public static void save(List<UserBean> users){
//保存数据库代码
}
public static void save(UserBean[] users){
}
}
复制代码
这样写会将遍历方法以及信息暴露出来
迭代器模式写法:
public class UserBean {
private String userId;
private String userName;
private String userSex;
public UserBean(String userId, String userName, String userSex) {
this.userId = userId;
this.userName = userName;
this.userSex = userSex;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserSex() {
return userSex;
}
public void setUserSex(String userSex) {
this.userSex = userSex;
}
@Override
public String toString() {
return "UserBean{" +
"userId='" + userId + '\'' +
", userName='" + userName + '\'' +
", userSex='" + userSex + '\'' +
'}';
}
}
复制代码
/**
* 容器接口
* 存储数据
* Created by Xionghu on 2017/7/6.
* Desc:
*/
public interface Aggregate<T> {
/**
* 获取迭代器
* @return
*/
public Iterator<T> iterator();
}
复制代码
public class AppleAggregate implements Aggregate<UserBean> {
private List<UserBean> userList;
public AppleAggregate() {
userList = new ArrayList<UserBean>();
userList.add(new UserBean("0001","zhangsan","男"));
userList.add(new UserBean("0002","lisi","男"));
userList.add(new UserBean("0003","Michel","男"));
userList.add(new UserBean("0004","Goode","男"));
}
@Override
public Iterator<UserBean> iterator() {
return new AppleIterator(userList);
}
}
复制代码
public class SmallAggregate implements Aggregate<UserBean> {
private UserBean[] userArray;
public SmallAggregate() {
this.userArray =new UserBean[6];
this.userArray[0] = new UserBean("001","Boy1","男");
this.userArray[1] = new UserBean("002","Boy2","男");
this.userArray[2] = new UserBean("003","Boy3","男");
this.userArray[3] = new UserBean("004","Boy4","男");
this.userArray[4] = new UserBean("005","Boy5","男");
this.userArray[5] = new UserBean("006","Boy6","男");
}
@Override
public Iterator<UserBean> iterator() {
return new SmallIterator(userArray);
}
}
复制代码
/**
* Created by Xionghu on 2017/7/6.
* Desc: 用来遍历数据
*/
public interface Iterator<T> {
/**
* 是否有下一个元素
*
* @return
*/
public boolean hasNext();
/**
* 下一个元素
*
* @return
*/
public T next();
/**
* 删除元素
*/
public void remove();
}
复制代码
/**
* Created by Xionghu on 2017/7/6.
* Desc:
* 苹果公司员工信息迭代器
*/
public class AppleIterator implements Iterator<UserBean> {
private List<UserBean> userList;
private int index = 0;
public AppleIterator(List<UserBean> userList) {
this.userList = userList;
}
@Override
public boolean hasNext() {
if(userList == null){
return false;
}
return index < userList.size();
}
@Override
public UserBean next() {
if (userList == null) {
return null;
}
return userList.get(index++);
}
@Override
public void remove() {
}
}
复制代码
/**
* Created by Xionghu on 2017/7/6.
* Desc:小公司员工信息迭代器
*/
public class SmallIterator implements Iterator<UserBean> {
private UserBean[] userList;
private int index = 0;
public SmallIterator( UserBean[] userList) {
this.userList = userList;
}
@Override
public boolean hasNext() {
if(userList == null){
return false;
}
return index < userList.length;
}
@Override
public UserBean next() {
if (userList == null) {
return null;
}
return userList[index++];
}
@Override
public void remove() {
}
}
复制代码
public class Client {
public static void main(String[] args) {
AppleAggregate appleAggregate = new AppleAggregate();
Iterator<UserBean> iterator = appleAggregate.iterator();
save(iterator);
SmallAggregate smallAggregate = new SmallAggregate();
Iterator<UserBean> iterator2 = smallAggregate.iterator();
save(iterator2);
}
/**
* 不需要关注细节,所有遍历细节(比如数据类型)已经封装好了,没有对外暴露
* @param iterator
*/
public static void save(Iterator<UserBean> iterator) {
while (iterator.hasNext()) {
UserBean userBean = iterator.next();
System.out.println("用户信息:" + userBean.toString());
}
}
}
复制代码
结果输出: 用户信息:UserBean{userId='0001', userName='zhangsan', userSex='男'} 用户信息:UserBean{userId='0002', userName='lisi', userSex='男'} 用户信息:UserBean{userId='0003', userName='Michel', userSex='男'} 用户信息:UserBean{userId='0004', userName='Goode', userSex='男'} 用户信息:UserBean{userId='001', userName='Boy1', userSex='男'} 用户信息:UserBean{userId='002', userName='Boy2', userSex='男'} 用户信息:UserBean{userId='003', userName='Boy3', userSex='男'} 用户信息:UserBean{userId='004', userName='Boy4', userSex='男'} 用户信息:UserBean{userId='005', userName='Boy5', userSex='男'} 用户信息:UserBean{userId='006', userName='Boy6', userSex='男'}
可以看到迭代器模式有点: 不需要关注细节,所有遍历细节(比如数据类型)已经封装好了,没有对外暴露 4.UML图
5.分析Android里面有哪些地方用到了迭代器模式 Java里面集合Collection(List、Set、Map等)都用到了迭代器模式
public interface Iterable<T> {
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
}
复制代码
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
复制代码
ArrayList 中 Itr类
private class Itr implements Iterator<E> {
// The "limit" of this iterator. This is the size of the list at the time the
// iterator was created. Adding & removing elements will invalidate the iteration
// anyway (and cause next() to throw) so saving this value will guarantee that the
// value of hasNext() remains stable and won't flap between true and false when elements
// are added and removed from the list.
protected int limit = ArrayList.this.size;
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor < limit;
}
@SuppressWarnings("unchecked")
public E next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
int i = cursor;
if (i >= limit)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
limit--;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
复制代码
Iterable:相当于容器接口 ArrayList 相当于具体的容器 iterator:迭代器接口 Itr:相当于具体的迭代器
其他HashSet、HashMap类似
使用场景:遍历数据的