Ответ 1
Вы можете использовать свой конкретный ключ:
class MyKey {
Double beta;
Double yaw;
int minute;
public int hashCode() {
/* Returns hash code from a combination of hash of the key members. */
}
@Override
public boolean equals(Object obj) {
/* Returns true if obj is a MyKey with same members. */
}
}
А потом просто:
data.put(myKey, obj);
Таким образом, "многоуровневые проверки" скрыты в MyKey.equals()
. Он держит код клиента чистым, а сложность ключа находится в надежном месте.
Изменить изменения после изменения:
Если, помимо всего прочего, вы хотите иметь карту из своей двойной beta
на свои объекты, тогда я все равно буду придерживаться плана такого плана.
Фактически вы хотите иметь несколько "индексов" для ваших данных, например, в базе данных, чтобы вы могли запрашивать объекты с такими же "бета" или "рысканием". Для этого лучше всего использовать несколько Map (фактически Multimap), по одному для каждого из ваших "индексов".
Использование мультикапа Guava:
ListMultimap<Double, Data> mapForBeta;
ListMultimap<Double, Data> mapForYaw;
Вы можете поместить все мультимары и Map<MyKey, Data>
в ваш конкретный класс. На самом деле лучшим способом было бы подкласс Map<MyKey, Data>
:
public class MyMap extends HashMap<MyKey, Data> {
ListMultimap<Double, Data> mapForBeta;
ListMultimap<Double, Data> mapForYaw;
public Data put(MyKey key, Data value) {
super.put(key, value);
mapForBeta.add(key.beta, value);
mapForYaw.add(key.yaw, value);
};
public List<Data> getFromBeta(Double beta) {
return mapForBeta.get(beta);
}
public List<Data> getFromYaw(Double yaw) {
return mapForYaw.get(yaw);
}
}
Новое редактирование с лучшим решением:
Фактически, это заставило меня задуматься, и я понял, что у вас действительно проблемы со значениями по умолчанию для ваших карт, и почему ваш код немного беспорядочен.
Вы можете решить эту проблему с помощью карты по умолчанию, используя генератор для создания базовых карт:
public class DefaultMap<K, V> extends TreeMap<K, V> {
static abstract class Generator<V>{
abstract V create();
}
final Generator<V> generator;
DefaultMap(Generator<V> generator) {
this.generator = generator;
}
@Override
public V get(Object key) {
V val = super.get(key);
if (val == null) {
val = generator.create();
put((K)key, val);
}
return val;
}
}
Теперь вы можете иметь свой древовидный класс утилиты для хранения всех ваших данных:
public class MyTree {
private final Map<Double, Map<Double, Map<Integer, Data>>> data;
public MyTree() {
data = new DefaultMap<>(new Generator<Map<Double, Map<Integer, Data>>>() {
@Override
Map<Double, Map<Integer, Data>> create() {
return new DefaultMap<>(new Generator<Map<Integer, Data>>() {
@Override
Map<Integer, Data> create() {
return new TreeMap<>();
}
});
}
});
}
void add(MyKey d, Data obj) {
data.get(d.beta).get(d.yaw).put(d.minute, obj);
}
}
Теперь вы можете получить доступ к своим данным с помощью data.get(beta).get(yaw), и у вас нет кода спагетти для хранения ваших значений.