Вот пример чуть выше моей головы (я не реализовывал методы удаления):
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class IndexedCollection<E> extends ArrayList<E> {
private Map<String, Map<Object, Set<E>>> indices = new HashMap<String, Map<Object, Set<E>>>();
public IndexedCollection(String...indices) {
for (String index: indices) {
this.indices.put(index, new HashMap<Object, Set<E>>());
}
}
public boolean add(E entry) {
try {
Map<String, Object> objectIndices = collectIndices(entry);
for (Entry<String, Object> objectIndex: objectIndices.entrySet()) {
Map<Object, Set<E>> map = this.indices.get(objectIndex.getKey());
Set<E> set = map.get(objectIndex.getValue());
if (set == null) {
set = new HashSet<E>();
map.put(objectIndex.getValue(), set);
}
set.add(entry);
}
return super.add(entry);
}
catch (Exception e)
{
throw new RuntimeException("Failed to collect object indices", e);
}
};
public Set<E> findByIndex(String name, Object value) {
Map<Object, Set<E>> index = this.indices.get(name);
if (index != null)
return index.get(value);
return null;
}
public Set<E> findByIndices(Index...indices) {
Set<E> results = null;
for (Index index: indices) {
Set<E> tmp = findByIndex(index.name, index.value);
if (tmp.size() == 0)
return null;
if (results == null)
results = tmp;
else {
Set<E> newResult = new HashSet<E>();
for (E value: results) {
if (tmp.contains(value))
newResult.add(value);
}
results = newResult;
}
}
return results;
}
private Map<String, Object> collectIndices(E e) throws IllegalArgumentException, IllegalAccessException {
Map<String, Object> indices = new HashMap<String, Object>();
Field[] fields = e.getClass().getDeclaredFields();
for (Field field: fields) {
if (this.indices.containsKey(field.getName())) {
boolean accessible = field.isAccessible();
field.setAccessible(true);
indices.put(field.getName(), field.get(e));
field.setAccessible(accessible);
}
}
return indices;
}
public static class Index {
private String name;
private Object value;
public Index(String name, Object value) {
this.name = name;
this.value = value;
}
}
}