这个问题已经在这里有了答案 :
7年前关闭。
在Java中将值(“ o”)保留在像这样的树结构中的最佳方法是什么:
obj1
/\
/ \
/ \
obj2 obj3
/\ /\
/ \ / \
/ \ / \
obj4 obj5 obj6 obj7
/\ /\ /\ /\
/ \ / \ / \ / \
o8 oN...
它看起来像一棵树,但是我不需要任意深度。我宁愿需要强大的数据类型和预定义的美观方法来处理最终结构。
我需要能够通过键获取某种值列表-就像在我的图片上一样。换句话说,结构应 不 以任何方式变得平坦。
我需要.get(obj3)
回来{obj6, obj7}, .get(obj1) - {obj2, obj3}
。
现在,我使用Map来实现此功能,但是由于需要检查结构的每个级别,因此夸大此类地图是很丑陋的。看起来像这样( 数据 就是地图):
if(data.get(somedouble) == null) {
Map<Integer, Data> inm = new TreeMap<>();
inm.put(someint, obj);
Map<Double, Map<Integer, Data>> m = new TreeMap<>();
m.put(somedouble2, inm);
data.put(somedouble, m);
}
else {
if(data.get(somedouble).get(somedouble2) == null) {
Map<Integer, Data> inm = new TreeMap<>();
inm.put(someint, obj);
data.get(somedouble).put(somedouble2, inm);
}
else
data.get(somedouble).get(somedouble2).put(someint, obj);
}
性能不是问题,但是代码美才是。
您可以使用您的特定密钥:
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
精度对象到对象的映射,那么我仍然会像这样保持平面。
您真正想要的是为数据提供多个“索引”(例如在数据库中),以便您可以查询具有相同“ beta”或“
yaw”的对象。为此,最好的方法是使用多个Map(实际上是Multimap),每个“索引”使用一个。
使用番石榴的Multimap:
ListMultimap<Double, Data> mapForBeta;
ListMultimap<Double, Data> mapForYaw;
您可以将所有的multimap和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)访问数据,并且没有意大利面条代码来存储您的值。
问题内容: 目前,我有这样的结构: 它使用联接表与每个子类一个表映射。由于历史原因,我也使用了一个鉴别器,因此当前情况如《 Hibernate手册》第9.1.3节所述 。 问题: 如何为这样的结构扩展映射: 我可以在hibernate映射中吗?什么我需要S’ 问题答案: 未测试, 但根据发布的链接(如果您使用的是hibernate3)
我有多个数组映射。 我想从多个地图中获取重复地图键的列表。 例如 除了遍历所有地图键,检查集合是否包含键,如果不将键添加到集合中,我想不出任何更干净的方法。有没有办法通过streams来实现这一点?
问题内容: 我正在寻找一种存储键值对的方法。我需要双向查询,但同时我需要为同一个键存储多个值。换句话说,类似于BidiMap,但是对于每个键,可以有多个值。例如,它需要能够保存以下对:“ s1”-> 1,“ s2”-> 1,“ s3”-> 2,并且我需要能够将值映射到每个键,并且对于每个值,获取与其关联的所有键。 问题答案: 因此,你需要多对多关系的支持吗?你可以得到的最接近的是Guava,Mul
问题内容: 特定实体存在映射例外。不能弄清楚问题出在哪里。我从头到尾检查了所有映射3次。我仍然收到映射异常。 发送给员工的电子邮件仅映射一次。但它仍然报告错误重复映射 错误是: 电子邮件Pojo email.hbm.xml 相关脚本 发送给员工的电子邮件仅映射一次。但它仍然报告错误重复映射 问题答案: 您是否将Employee中的集合设置为逆?
问题内容: 我正在创建一个需要存储键值对的程序。该程序需要接受键形式的请求,并返回相应的值。 问题在于每个键有时有多个值,并且map类不允许重复的键。 这些值是数字,因此无法像使用字符串那样有意义地连接这些值。 对于每个键可以有多个数值的事实,是否有任何优雅的解释方法?我希望返回每个数字,而不是随机返回一个数字。 问题答案: $ cat YourMap.java public class Your
我想使用Java流按对用户列表进行分组。 例如,我有。