Java 在地图中正确使用存储对象
假设我需要存储一组学生对象,每个学生都有一个唯一的id。一个选项是将所有学生都存储在一个列表中,但在搜索学生时,我必须执行线性搜索并检查他们的id。另一个选项是使用映射,类似于:map,其中键是映射到实际学生对象的学生id 对于给定的问题,这是一种合理的方法吗?一方面,它感觉不错,因为我可以通过学生的id轻松检索学生,然而,另一方面,它感觉我稍微冗余地存储了id,该id已经存在于学生对象中-因此我存储了两次,但关键是查找机制 我的add是这样的:Java 在地图中正确使用存储对象,java,dictionary,collections,Java,Dictionary,Collections,假设我需要存储一组学生对象,每个学生都有一个唯一的id。一个选项是将所有学生都存储在一个列表中,但在搜索学生时,我必须执行线性搜索并检查他们的id。另一个选项是使用映射,类似于:map,其中键是映射到实际学生对象的学生id 对于给定的问题,这是一种合理的方法吗?一方面,它感觉不错,因为我可以通过学生的id轻松检索学生,然而,另一方面,它感觉我稍微冗余地存储了id,该id已经存在于学生对象中-因此我存储了两次,但关键是查找机制 我的add是这样的: public void add(Student
public void add(Student s) {
lookup.put(s.getId(), s);
}
希望这种冗余是您在编程中遇到的唯一冗余 在性能和可读性方面,使用具有唯一对象id的映射的附加值值得这种做法产生的少量开销
如果您真的觉得这项开销太大,则可以将放置在地图数据结构中的对象从ID属性中剥离,并且ID属性将仅用作键,然后在检索过程中,您可以从地图键推断ID。在这种情况下,没有真正正确的用法。你必须考虑你将如何处理这个集合,一旦你完成了它。你要重复它吗?你想把它分类吗 当然,可以创建一个
映射
,自动将键从值中拉出,但是,由于迭代或排序可能变得更加困难,该结构的可用性也受到限制
这里有一个CurriedHashMap
,它可以满足您的需求。忽略它正在引擎盖下使用HashMap
功能这一事实
class CurriedHashMap<K, V> extends HashMap<K, V> {
/**
* Function that extracts key from value.
*/
final Function<V, K> curry;
public CurriedHashMap(Function<V, K> curry) {
this.curry = curry;
}
/**
* One-value put - the key is intuited from the value using the `curry` function.
*/
public V put(V value) {
return super.put(curry.apply(value), value);
}
}
类CurriedHashMap扩展了HashMap{
/**
*从值中提取键的函数。
*/
最后功能咖喱;
公共货币地图(功能货币){
this.curry=咖喱;
}
/**
*一个值put-使用'curry'函数从值中插入键。
*/
公共V值(V值){
返回super.put(curry.apply(value),value);
}
}
我就是这么做的。您还可以在student objectdata结构上实现equals()和hashCode方法。数据结构与感觉无关