使用Iterator模式将对象转成String文档格式.docx
- 文档编号:21594943
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:13
- 大小:52.36KB
使用Iterator模式将对象转成String文档格式.docx
《使用Iterator模式将对象转成String文档格式.docx》由会员分享,可在线阅读,更多相关《使用Iterator模式将对象转成String文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
16
17
18
19
20
21
22
23
24
packagecom.stackhunter.util.tostring.example;
importcom.stackhunter.example.employee.Department;
importcom.stackhunter.example.employee.Employee;
importcom.stackhunter.example.employee.Manager;
importcom.stackhunter.example.people.Person;
importcom.stackhunter.util.tostring.StringGenerator;
publicclassStringGeneratorExample{
publicstaticvoidmain(String[]args){
Departmentdepartment=newDepartment(5775,"
Sales"
)
.setEmployees(
newEmployee(111,"
Bill"
"
Gates"
),
newEmployee(222,"
Howard"
Schultz"
newManager(333,"
Jeff"
Bezos"
75000));
System.out.println(StringGenerator.generate(department));
System.out.println(StringGenerator.generate(newint[]{111,222,333}));
System.out.println(StringGenerator.generate(true));
}
StringGenerator.generate()将department,数组和boolean值进行格式化输出。
com.stackhunter.example.employee.Department@129719f4
deptId=5775
employeeList=java.util.ArrayList@7037717a
employeeList[0]=com.stackhunter.example.employee.Employee@17a323c0
firstName=Bill
id=111
lastName=Gates
employeeList[1]=com.stackhunter.example.employee.Employee@57801e5f
firstName=Howard
id=222
lastName=Schultz
employeeList[2]=com.stackhunter.example.employee.Manager@1c4a1bda
budget=75000.0
firstName=Jeff
id=333
lastName=Bezos
name=Sales
[I@39df3255
object[0]=111
object[1]=222
object[2]=333
true
对象迭代器
ObjectIterator使用迭代器模式遍历对象的属性,以键值对形式保存。
对象中的Javabean、集合、数组及map都要进行迭代。
ObjectIterator也会考虑到对象之间循环引用的处理。
importcom.stackhunter.util.objectiterator.ObjectIterator;
publicclassObjectIteratorExample{
ObjectIteratoriterator=newObjectIterator("
somedepartment"
department);
while(iterator.next()){
System.out.println(iterator.getName()+"
="
+iterator.getValueAsString());
通过遍历整个对象生成键值对的集合。
使用getValueAsString()方法而不是toString()格式化输出。
对于原始类型、包装类型、字符串、日期和枚举使用原始的toString()实现。
对于其他类型输出类名和hash值。
ObjectIterator.getDepth()会增加缩进,输出更易读。
调用next()之前使用nextParent()缩短当前分支跳跃到下一属性。
somedepartment=com.stackhunter.example.employee.Department@780324ff
deptId=5775
employeeList=java.util.ArrayList@6bd15108
employeeList[0]=com.stackhunter.example.employee.Employee@22a79c31
firstName=Bill
...
Java对象迭代器的具体实现
实现iterator模式的第一步是创建通用的迭代器接口:
IObjectIterator。
无论遍历的对象是Javabean、数组还是map都可以使用该接口。
publicinterfaceIObjectIterator{
booleannext();
StringgetName();
ObjectgetValue();
使用该接口可以按照单一顺序依次获取当前属性的name和value。
实现了IObjectIterator的类用来处理某一种类型的对象。
大多数类调用getName()返回名称前缀。
ArrayIterator使用了元素的索引:
returnname+"
["
+nextIndex+"
]"
;
。
属性迭代器
PropertyIterator可能是最重要的迭代类。
它使用Javabeanintrospection读取对象属性,将它们转化为键值对序列。
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
publicclassPropertyIteratorimplementsIObjectIterator{
privatefinalObjectobject;
privatefinalPropertyDescriptor[]properties;
privateintnextIndex=-1;
privatePropertyDescriptorcurrentProperty;
publicPropertyIterator(Objectobject){
this.object=object;
try{
BeanInfobeanInfo=Introspector.getBeanInfo(object.getClass());
properties=beanInfo.getPropertyDescriptors();
}catch(RuntimeExceptione){
throwe;
}catch(Exceptione){
thrownewRuntimeException(e.getMessage(),e);
@Override
publicbooleannext(){
if(nextIndex+1>
=properties.length){
returnfalse;
nextIndex++;
currentProperty=properties[nextIndex];
if(currentProperty.getReadMethod()==null||"
class"
.equals(currentProperty.getName())){
returnnext();
returntrue;
publicStringgetName(){
if(currentProperty==null){
returnnull;
returncurrentProperty.getName();
publicObjectgetValue(){
returncurrentProperty.getReadMethod().invoke(object);
数组迭代器
ArrayIterator通过反射得到数组的长度,进而检索每个数据元素。
ArrayIterator不关心从getValue()方法返回值的具体细节。
它们一般情况下被传递给PropertyIterator。
publicclassArrayIteratorimplementsIObjectIterator{
privatefinalStringname;
privatefinalObjectarray;
privatefinalintlength;
privateObjectcurrentElement;
publicArrayIterator(Stringname,Objectarray){
this.name=name;
this.array=array;
this.length=Array.getLength(array);
=length){
currentElement=Array.get(array,nextIndex);
returncurrentElement;
集合迭代器
CollectionIterator与ArrayIterator非常相似。
使用java.lang.Iterable调用它的Iterable.iterator()方法初始化内部迭代器。
Map迭代器
MapIterator遍历java.util.Map的entry。
它并不深入到每个entry的键值对,这个工作由MapEntryIterator类完成。
publicclassMapIteratorimplementsIObjectIterator{
privateIterator<
?
>
entryIterator;
privateMap.Entry<
?
currentEntry;
publicMapIterator(Stringname,Map<
map){
this.entryIterator=map.entrySet().iterator();
if(entryIterator.hasNext()){
currentEntry=(Entry<
)entryIterator.next();
MapEntry迭代器
MapEntryIterator处理java.util.Map的单个entry。
它只返回两个值:
entry的键和值。
与ArrayIterator及其他的类似,如果是复杂类型的话,它的结果可能最终传递给PropertyIterator,作为Javabean处理。
根迭代器
RootIterator返回单个元素——初始节点。
可以把它想成XML文件的根节点。
目的是发起整个遍历过程。
整合
ObjectIterator类作为门面角色(Facade),包装了所有的遍历逻辑。
它根据最后一次getValue()的返回值类型决定哪个IObjectIterator的子类需要实例化。
当子迭代器在内部创建时它在栈中保存当前迭代器的状态。
它也暴露了getChild()和getDepth()方法为调用者展示当前进度。
privateIObjectIteratoriteratorFor(Objectobject){
if(object==null){
if(object.getClass().isArray()){
returnnewArrayIterator(name,object);
if(objectinstanceofIterable){
returnnewCollectionIterator(name,(Iterable<
)object);
if(objectinstanceofMap){
returnnewMapIterator(name,(Map<
if(objectinstanceofMap.Entry){
returnnewMapEntryIterator(name,(Map.Entry<
if(isSingleValued(object)){
returnnewPropertyIterator(object);
字符串生成器的实现
已经看到如何遍历对象中的所有属性。
最后的工作就是让输出更加美观,以及增加一些限制条件(比如不能创建一个GB级大小的字符串)。
publicstaticStringgenerate(Objectobject){
Strings="
"
object"
object);
if(s.length()>
=MAX_STRING_LENGTH){
returns;
if(iterator.getChild()>
=MAX_CHILDREN){
iterator.nextParent();
continue;
StringvalueAsString=iterator.getValueAsString();
s+=System.lineSeparator();
s+=indent(iterator.getDepth())+truncateString
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用 Iterator 模式 对象 转成 String