




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
操纵JSOM、XML、Java bean等对象时你可能最先想到访问者模式。但是使用访问者模式很难从调用代码控制回调。比如,不能有条件的从所有回调的子分支和叶子节点跳过某个分支。解决这个问题就可以使用Iterator模式遍历整个对象,生成易于开发者阅读和调试的字符串。该迭代器具备一定的通用性,我在使用XPath查找Java对象和在StackHunter中记录异常的工具中都用到了它。API本文主要介绍的两个类:StringGenerator和ObjectIterator。字符串生成器StringGenerator工具类将对象转化为字符串,使对象可读性更好。可以用它来实现类的toString方法或者把对象的字符串表达作为日志调试代码:123456789101112131415161718192021222324package com.stackhunter.util.tostring.example;import com.stackhunter.example.employee.Department;import com.stackhunter.example.employee.Employee;import com.stackhunter.example.employee.Manager;import com.stackhunter.example.people.Person;import com.stackhunter.util.tostring.StringGenerator;public class StringGeneratorExample public static void main(String args) Department department = new Department(5775, Sales).setEmployees(new Employee(111, Bill, Gates), new Employee(222, Howard, Schultz), new Manager(333, Jeff, Bezos, 75000);System.out.println(StringGenerator.generate(department);System.out.println(StringGenerator.generate(new int 111, 222, 333 );System.out.println(StringGenerator.generate(true);StringGenerator.generate()将department,数组和boolean值进行格式化输出。12345678910111213141516171819202122com.stackhunter.example.employee.Department129719f4deptId = 5775employeeList = java.util.ArrayList7037717aemployeeList0 = com.stackhunter.example.employee.Employee17a323c0firstName = Billid = 111lastName = GatesemployeeList1 = com.stackhunter.example.employee.Employee57801e5ffirstName = Howardid = 222lastName = SchultzemployeeList2 = com.stackhunter.example.employee.Manager1c4a1bdabudget = 75000.0firstName = Jeffid = 333lastName = Bezosname = SalesI39df3255object0 = 111object1 = 222object2 = 333true对象迭代器ObjectIterator使用迭代器模式遍历对象的属性,以键值对形式保存。对象中的Java bean、集合、数组及map都要进行迭代。ObjectIterator也会考虑到对象之间循环引用的处理。123456789101112131415161718192021222324package com.stackhunter.util.tostring.example;import com.stackhunter.example.employee.Department;import com.stackhunter.example.employee.Employee;import com.stackhunter.example.employee.Manager;import com.stackhunter.util.objectiterator.ObjectIterator;public class ObjectIteratorExample public static void main(String args) Department department = new Department(5775, Sales).setEmployees(new Employee(111, Bill, Gates), new Employee(222, Howard, Schultz), new Manager(333, Jeff, Bezos, 75000);ObjectIterator iterator = new ObjectIterator(some department, department);while (iterator.next() System.out.println(iterator.getName() + = + iterator.getValueAsString();通过遍历整个对象生成键值对的集合。使用getValueAsString()方法而不是toString()格式化输出。对于原始类型、包装类型、字符串、日期和枚举使用原始的toString()实现。对于其他类型输出类名和hash值。ObjectIterator.getDepth()会增加缩进,输出更易读。调用next()之前使用nextParent()缩短当前分支跳跃到下一属性。123456some department=com.stackhunter.example.employee.Department780324ffdeptId=5775employeeList=java.util.ArrayList6bd15108employeeList0=com.stackhunter.example.employee.Employee22a79c31firstName=Bill.Java对象迭代器的具体实现实现iterator模式的第一步是创建通用的迭代器接口:IObjectIterator。无论遍历的对象是Java bean、数组还是map都可以使用该接口。12345public interface IObjectIterator boolean next();String getName();Object getValue();使用该接口可以按照单一顺序依次获取当前属性的name和value。实现了IObjectIterator的类用来处理某一种类型的对象。大多数类调用getName()返回名称前缀。ArrayIterator使用了元素的索引:return name + + nextIndex + ;。属性迭代器PropertyIterator可能是最重要的迭代类。它使用Java bean introspection读取对象属性,将它们转化为键值对序列。1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556public class PropertyIterator implements IObjectIterator private final Object object;private final PropertyDescriptor properties;private int nextIndex = -1;private PropertyDescriptor currentProperty;public PropertyIterator(Object object) this.object = object;try BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass();properties = beanInfo.getPropertyDescriptors(); catch (RuntimeException e) throw e; catch (Exception e) throw new RuntimeException(e.getMessage(), e);Overridepublic boolean next() if (nextIndex + 1 = properties.length) return false;nextIndex+;currentProperty = propertiesnextIndex;if (currentProperty.getReadMethod() = null | class.equals(currentProperty.getName() return next();return true;Overridepublic String getName() if (currentProperty = null) return null;return currentProperty.getName();Overridepublic Object getValue() try if (currentProperty = null) return null;return currentProperty.getReadMethod().invoke(object); catch (RuntimeException e) throw e; catch (Exception e) throw new RuntimeException(e.getMessage(), e);数组迭代器ArrayIterator通过反射得到数组的长度,进而检索每个数据元素。ArrayIterator不关心从getValue()方法返回值的具体细节。它们一般情况下被传递给PropertyIterator。123456789101112131415161718192021222324252627282930313233343536public class ArrayIterator implements IObjectIterator private final String name;private final Object array;private final int length;private int nextIndex = -1;private Object currentElement;public ArrayIterator(String name, Object array) = name;this.array = array;this.length = Array.getLength(array);Overridepublic boolean next() if (nextIndex + 1 = length) return false;nextIndex+;currentElement = Array.get(array, nextIndex);return true;Overridepublic String getName() return name + + nextIndex + ;Overridepublic Object getValue() return currentElement;集合迭代器CollectionIterator与ArrayIterator非常相似。使用java.lang.Iterable调用它的Iterable.iterator()方法初始化内部迭代器。Map迭代器MapIterator遍历java.util.Map的entry。它并不深入到每个entry的键值对,这个工作由MapEntryIterator类完成。12345678910111213141516171819202122232425public class MapIterator implements IObjectIterator private final String name;private Iterator entryIterator;private Map.Entry currentEntry;private int nextIndex = -1;public MapIterator(String name, Map map) = name;this.entryIterator = map.entrySet().iterator();Overridepublic boolean next() if (entryIterator.hasNext() nextIndex+;currentEntry = (Entry) entryIterator.next();return true;return false;.Map Entry迭代器MapEntryIterator处理java.util.Map的单个entry。它只返回两个值:entry的键和值。与ArrayIterator及其他的类似,如果是复杂类型的话,它的结果可能最终传递给PropertyIterator,作为Java bean处理。根迭代器RootIterator返回单个元素初始节点。可以把它想成XML文件的根节点。目的是发起整个遍历过程。整合ObjectIterator类作为门面角色(Facade),包装了所有的遍历逻辑。它根据最后一次getValue()的返回值类型决定哪个IObjectIterator的子类需要实例化。当子迭代器在内部创建时它在栈中保存当前迭代器的状态。它也暴露了getChild()和getDepth()方法为调用者展示当前进度。12345678910111213141516171819202122232425262728293031323334private IObjectIterator iteratorFor(Object object) try if (object = null) return null;if (object.getClass().isArray() return new ArrayIterator(name, object);if (object instanceof Iterable) return new CollectionIterator(name, (Iterable) object);if (object instanceof Map) return new MapIterator(name, (Map) object);if (object instanceof Map.Entry) return new MapEntryIterator(name, (Map.Entry) object);if (isSingleValued(object) return null;return new PropertyIterator(object); catch (RuntimeException e) throw e; catch (Exception e) throw new RuntimeException(e.getMessage(), e);字符串生成器的实现已经看到如何遍历对象中的所有属性。最后的工作就是让输出
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论