我使用像字符串映射这样的前置泛型作为关键.他们将键映射到以下类型的值之一:
>另一张地图
>一个清单
>原始包装
您可以使用XPath或类似的查询访问集合内容:
myMap/FIRST_LIST[2]/SECOND_LIST[1]/MY_MAP/MY_PRIMITIVE
我正在寻找的是一个允许我将访问者函数应用于集合的多个元素的库.基本功能可能看起来像这样
MyMapBrowser browser = new MyMapBrowser(myMap);
browser.applyVisitor("FIRST_LIST[*]/SECOND_LIST[*]/MY_MAP/MY_PRIMITIVE",
new AbstractVisitor<String>() {
visit(String s) {
// do something with the strings
}
});
如果有可能首先为不同级别的集合注册多个访问者,然后开始访问迭代,那也是很棒的.它可能看起来像这样:
browser.registerVisitor(SECOND_LIST, new AbstractVisitor<MyList> { ... )
browser.doVisiting("FIRST_LIST[*]/SECOND_LIST[*]/MY_MAP/MY_PRIMITIVE");
事实上,我已经开始实现这样的浏览器,但我无法摆脱我重新发明轮子的印象.
最佳答案 你看过
JXPath吗?它允许您使用XPath表达式来查询和操作Java对象图.如果您只想提取字符串值,则
JXPathContext
类允许您迭代所选节点的值,或者您可以使用selectNodes方法来获取JDOM包装器.
例如,我认为您的示例查询看起来像:
// untested
JXPathContext context = JXPathContext.newContext(myMap);
Iterator iter = context.iterate("FIRST_LIST/SECOND_LIST/MY_MAP/MY_PRIMITIVE");
while (iter.hasNext()) {
String str = (String) iter.next();
// do something with strings
}
不幸的是我实际上并没有使用JXPath(虽然我之前也尝试过实现类似XPath的遍历),但显然你也可以配置它来自动为特定路径创建对象.我没有看到任何访问者功能,但是iterate,getValue和setValue应该能够完成同样的事情.您还可以装配一个简单的包装类来运行查询,遍历节点,并将值传递给您自己的访问者界面.就像是:
public class JXPathVisitBrowser {
private JXPathContext context;
public JXPathVisitBrowser(Object object) {
context = JXPathContext.newContext(object);
}
public <T> void applyVisitor(String query, AbstractVisitor<T> visitor) {
Iterator iter = context.iterate(query);
while (iter.hasNext())
visitor.visit((T) iter.next());
}
}
还有一个非常详细的JXPath user guide.