Konvertieren Sie das Objekt mithilfe des Iteratormusters in einen String
Beim Bearbeiten von JSOM, XML, Java Beans und anderen Objekten denken Sie möglicherweise zuerst an das Besuchermuster. Mithilfe des Besuchermusters ist es jedoch schwierig, Rückrufe vom aufrufenden Code aus zu steuern. Beispielsweise können Sie einen Zweig nicht von allen untergeordneten Callback-Zweigen und Blattknoten bedingt überspringen. Um dieses Problem zu lösen, können Sie das Iterator-Muster verwenden, um das gesamte Objekt zu durchlaufen und eine Zeichenfolge zu generieren, die für Entwickler leicht zu lesen und zu debuggen ist. Dieser Iterator ist sehr vielseitig und ich habe ihn in Tools wie der Suche nach Java-Objekten mithilfe von XPath und der Protokollierung von Ausnahmen in StackHunter verwendet.
API
In diesem Artikel werden hauptsächlich zwei Klassen vorgestellt: StringGenerator und ObjectIterator.
String Generator
Die Toolklasse StringGenerator konvertiert Objekte in Strings, um Objekte besser lesbar zu machen. Sie können damit die toString-Methode der Klasse implementieren oder den Zeichenfolgenausdruck des Objekts als Protokoll-Debugging-Code verwenden:
package 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() formatiert Abteilungs-, Array- und boolesche Werte für die Ausgabe .
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
Object Iterator
ObjectIterator verwendet das Iteratormuster, um die Eigenschaften des Objekts zu durchlaufen und sie in Form von Schlüssel-Wert-Paaren zu speichern. Java Beans, Collections, Arrays und Maps in Objekten müssen iteriert werden. ObjectIterator berücksichtigt auch die Handhabung von Zirkelverweisen zwischen Objekten.
package 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()); } } }
Generieren Sie eine Sammlung von Schlüssel-Wert-Paaren, indem Sie das gesamte Objekt durchlaufen. Verwenden Sie die Methode getValueAsString() anstelle von toString(), um die Ausgabe zu formatieren. Verwenden Sie die ursprüngliche toString()-Implementierung für primitive Typen, umschlossene Typen, Zeichenfolgen, Datumsangaben und Aufzählungen. Bei anderen Typen werden Klassenname und Hashwert ausgegeben.
ObjectIterator.getDepth() vergrößert die Einrückung und macht die Ausgabe besser lesbar. Verwenden Sie nextParent() vor dem Aufruf von next(), um den aktuellen Zweig zu verkürzen und zum nächsten Attribut zu springen.
some department=com.stackhunter.example.employee.Department@780324ff deptId=5775 employeeList=java.util.ArrayList@6bd15108 employeeList[0]=com.stackhunter.example.employee.Employee@22a79c31 firstName=Bill ...
Konkrete Implementierung des Java-Objektiterators
Der erste Schritt zur Implementierung des Iteratormusters besteht darin, eine allgemeine Iteratorschnittstelle zu erstellen: IObjectIterator. Diese Schnittstelle kann unabhängig davon verwendet werden, ob das durchquerte Objekt eine Java-Bean, ein Array oder eine Map ist.
public interface IObjectIterator { boolean next(); String getName(); Object getValue(); }
Verwenden Sie diese Schnittstelle, um den Namen und den Wert des aktuellen Attributs in einer einzigen Reihenfolge abzurufen.
Eine Klasse, die IObjectIterator implementiert, wird zum Verarbeiten von Objekten eines bestimmten Typs verwendet. Die meisten Klassen rufen getName() auf, um das Namenspräfix zurückzugeben. ArrayIterator verwendet den Index des Elements: Rückgabename + „[“ + nextIndex + „]“;.
Property Iterator
PropertyIterator ist wahrscheinlich die wichtigste Iterationsklasse. Es nutzt Java-Bean-Introspektion, um Objekteigenschaften zu lesen und sie in eine Folge von Schlüssel-Wert-Paaren umzuwandeln.
public 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); } } @Override public boolean next() { if (nextIndex + 1 >= properties.length) { return false; } nextIndex++; currentProperty = properties[nextIndex]; if (currentProperty.getReadMethod() == null || "class".equals(currentProperty.getName())) { return next(); } return true; } @Override public String getName() { if (currentProperty == null) { return null; } return currentProperty.getName(); } @Override public 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); } } }
Array Iterator
ArrayIterator ermittelt die Länge des Arrays durch Reflektion und ruft dann jedes Datenelement ab. ArrayIterator kümmert sich nicht um die spezifischen Details des von der Methode getValue() zurückgegebenen Werts. Sie werden normalerweise an PropertyIterator übergeben.
public 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) { this.name = name; this.array = array; this.length = Array.getLength(array); } @Override public boolean next() { if (nextIndex + 1 >= length) { return false; } nextIndex++; currentElement = Array.get(array, nextIndex); return true; } @Override public String getName() { return name + "[" + nextIndex + "]"; } @Override public Object getValue() { return currentElement; } }
集合迭代器
CollectionIterator与ArrayIterator非常相似。使用java.lang.Iterable调用它的Iterable.iterator()方法初始化内部迭代器。
Map迭代器
MapIterator遍历java.util.Map的entry。它并不深入到每个entry的键值对,这个工作由MapEntryIterator类完成。
public 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) { this.name = name; this.entryIterator = map.entrySet().iterator(); } @Override public 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()方法为调用者展示当前进度。
private 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); } }
字符串生成器的实现
已经看到如何遍历对象中的所有属性。最后的工作就是让输出更加美观,以及增加一些限制条件(比如不能创建一个GB级大小的字符串)。
public static String generate(Object object) { String s = ""; ObjectIterator iterator = new ObjectIterator("object", object); ... while (iterator.next()) { if (s.length() >= MAX_STRING_LENGTH) { return s; } if (iterator.getChild() >= MAX_CHILDREN) { iterator.nextParent(); continue; } String valueAsString = iterator.getValueAsString(); s += System.lineSeparator(); s += indent(iterator.getDepth()) + truncateString(iterator.getName()); if (valueAsString == null) { s += " = null"; } else { s += " = " + truncateString(valueAsString); } } return s; }
代码第21行完成了格式化,增加了缩进和层次结构使显示更美观。
同时增加了一些限制条件:
第9行——限制字符串长度在16k内。
第13行——限制任何父节点下子节点数量小于64.
第21&25行——限制键和值长度在64个字符。
总结
本文介绍了如何使用迭代器模式遍历包含各种复杂属性的对象。关键是将每种类型的迭代委派给各自的类实现。可以在你自己的软件中使用这两个工具。

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

In der Java-Programmierung sind die Schnittstellen Iterator und Iterable wichtige Werkzeuge zur Verarbeitung von Elementen in Sammlungen. Die Iterator-Schnittstelle stellt Methoden für den iterativen Zugriff auf Sammlungselemente bereit, während die Iterable-Schnittstelle die Iterierbarkeit der Sammlung definiert, sodass über Iterator auf die Elemente in der Sammlung zugegriffen werden kann. Die enge Zusammenarbeit zwischen den beiden bietet uns eine allgemeine Methode zum Durchlaufen von Sammlungselementen. Iterator-Schnittstelle Die Iterator-Schnittstelle definiert die folgenden Methoden: booleanhasNext(): Prüft, ob noch Elemente in der Sammlung vorhanden sind. Enext(): Gibt das nächste Element in der Sammlung zurück. voidremove(): Entfernen Sie das aktuelle Element. Wiederholbar

Konzeptionelle Unterschiede: Iterator: Iterator ist eine Schnittstelle, die einen Iterator darstellt, der Werte aus einer Sammlung erhält. Es bietet Methoden wie MoveNext(), Current() und Reset(), mit denen Sie die Elemente in der Sammlung durchlaufen und das aktuelle Element bearbeiten können. Iterable: Iterable ist ebenfalls eine Schnittstelle, die ein iterierbares Objekt darstellt. Es stellt die Methode Iterator() bereit, die ein Iterator-Objekt zurückgibt, um das Durchlaufen der Elemente in der Sammlung zu erleichtern. Verwendung: Iterator: Um Iterator zu verwenden, müssen Sie zuerst ein Iterator-Objekt abrufen und dann die Methode MoveNext() aufrufen, um zum nächsten zu wechseln

Iterator-Schnittstelle Die Iterator-Schnittstelle ist eine Schnittstelle zum Durchlaufen von Sammlungen. Es bietet mehrere Methoden, darunter hasNext(), next() und remove(). Die Methode hasNext() gibt einen booleschen Wert zurück, der angibt, ob es ein nächstes Element in der Sammlung gibt. Die Methode next() gibt das nächste Element in der Sammlung zurück und entfernt es aus der Sammlung. Die Methode „remove()“ entfernt das aktuelle Element aus der Sammlung. Das folgende Codebeispiel zeigt, wie die Iterator-Schnittstelle zum Durchlaufen einer Sammlung verwendet wird: Listnames=Arrays.asList("John","Mary","Bob");Iterator

Einführung in IteratorIterator ist eine Schnittstelle in Java zum Durchlaufen von Sammlungen. Es bietet eine Reihe von Methoden, mit denen Sie sequentiell auf Elemente in einer Sammlung zugreifen können. Mit Iterator können Sie Sammlungstypen wie List, Set und Map durchlaufen. Democode: Listlist=newArrayList();list.add("one");list.add("two");list.add(" three");Iteratoriterator=list.iterator();while(iter

Iterator (Iterator) und Iterable Object (Iterable) sind zwei sehr wichtige Schnittstellen im Java Collection Framework. Sie ermöglichen es Ihnen, die Elemente in einer Sammlung zu durchlaufen, ohne die spezifische Implementierung der Sammlung zu kennen. Die Iterator-Schnittstelle definiert Methoden zum Durchlaufen von Sammlungen, einschließlich hasNext() und next(). Die Methode hasNext() prüft, ob weitere Elemente in der Sammlung vorhanden sind, während die Methode next() das nächste Element in der Sammlung zurückgibt. Die Iterable-Schnittstelle definiert eine Methode zum Erstellen eines Iterators, die iterator()-Methode. Diese Methode gibt ein Iterator-Objekt zurück, das zum Durchlaufen der Sammlung verwendet werden kann. Im Folgenden wird Itera verwendet

In Java ist eine Sammlung eine Sammlung von Elementen, die eine einheitliche Schnittstelle und Methoden zum Speichern, Abrufen und Betreiben dieser Elemente bereitstellt. Iterator und Iterable sind zwei wichtige Java-Schnittstellen, die einen gemeinsamen Mechanismus zum Durchlaufen von Sammlungselementen bereitstellen. Die Iterator-Schnittstelle definiert die Methoden hasNext() und next() zum Durchlaufen von Sammlungen. Die Methode hasNext() wird verwendet, um zu prüfen, ob es in der Sammlung nicht durchquerte Elemente gibt, und die Methode next() wird verwendet, um das aktuelle Element zurückzugeben und es zum nächsten Element zu verschieben. Die Iterable-Schnittstelle definiert die Methode iterator(), die ein Iterator-Objekt zum Durchlaufen der Elemente in der Sammlung zurückgibt.

Iterator-Schnittstelle Die Iterator-Schnittstelle ist eine Low-Level-Schnittstelle im Java-Sammlungsframework zum Durchlaufen von Sammlungen. Es definiert zwei Hauptmethoden: hasNext(): prüft, ob weitere Elemente in der Sammlung vorhanden sind. next(): Gibt das nächste Element in der Sammlung zurück. Die Iterator-Schnittstelle definiert auch einige optionale Methoden, beispielsweise die Methode „remove()“, mit der das aktuelle Element aus der Sammlung entfernt wird. Verwenden der Iterator-Schnittstelle Sie können die Iterator-Schnittstelle verwenden, um eine Sammlung mit den folgenden Schritten zu durchlaufen: Rufen Sie das Iterator-Objekt der Sammlung ab. Verwenden Sie die Methode hasNext(), um zu überprüfen, ob die Sammlung weitere Elemente enthält. Wenn mehr Elemente vorhanden sind, verwenden Sie die Methode next(), um das nächste Element abzurufen

In Java ist eine Sammlung eine allgemeine Datenstruktur, die es uns ermöglicht, große Datenmengen zu speichern und zu verarbeiten. In vielen Fällen müssen wir eine Sammlung durchlaufen, um ihre Elemente zu bearbeiten. Um diesen Zweck zu erreichen, stellt Java die Iterator-Funktion bereit, mit der wir die Elemente in der Sammlung einfach durchlaufen können. In diesem Artikel erklären wir, wie man die Iterator-Funktion in Java zum Durchlaufen von Sammlungen verwendet. 1. Die Definition der Iterator-Funktion in Java lautet Iterator
