我不愿提出这个建议,但是您可以将查找封装在某种Indexer
类后面,该类使用提供的对象的字段通过反射自动生成单个映射。
通过单个映射,我的意思是整个索引器只有一个映射,它基于字段名称和数据创建一个键(例如将表示字段名称的字符串与数据的字符串表示连接起来)。
针对索引器的查找将提供字段名称和数据值,然后将在索引器封装的单个映射中进行查找。
我认为这与索引器由映射映射(字段名称映射到数据到对象映射)支持的类似解决方案相比不一定有任何优势。
索引器还可以设计为使用注释,以便并非所有字段都被索引,只有那些适当注释的字段(反之亦然,带有注释以排除字段)。
总体而言,地图解决方案的地图让我印象深刻,因为它省去了复杂的密钥组装步骤(这对于某些字段数据类型可能很复杂)。在任何一种情况下,将其全部封装在Indexer
自动生成其地图的方法中似乎是要走的路。
更新:
为类型类制作了一个快速的非通用概念证明Indexer
(使用 map of maps 方法)。 这绝不是完成的工作,而是说明了上述概念。一个主要缺陷是对 bean 的依赖,因此没有访问器方法的公共和私有字段对于该索引器都是不可见的。
public class Indexer
{
private Map<String,Map<Object,Set<Object>>> index = new HashMap<String,Map<Object,Set<Object>>>();
// Add an object to the index, all properties are indexed.
public void add(Object object) throws Exception
{
BeanInfo info = Introspector.getBeanInfo(object.getClass());
PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();
for (PropertyDescriptor descriptor : propertyDescriptors)
{
String fieldName = descriptor.getName();
Map<Object,Set<Object>> map = index.get(fieldName);
if (map == null)
{
map = new HashMap<Object,Set<Object>>();
index.put(fieldName, map);
}
Method method = descriptor.getReadMethod();
Object data = method.invoke(object);
Set<Object> set = map.get(data);
if (set == null)
{
set = new HashSet<Object>();
map.put(data, set);
}
set.add(object);
}
}
// Retrieve the set of all objects from the index whose property matches the supplied.
public Set<Object> get(String fieldName, Object value)
{
Map<Object,Set<Object>> map = index.get(fieldName);
if (map != null)
{
Set<Object> set = map.get(value);
if (set != null)
{
return Collections.unmodifiableSet(set);
}
}
return null;
}
}