这是一个简单的编程问题。我不是 Java 专家。假设我使用自定义类 Company 和 Employee 的对象,其方式类似于许多 RDBMS 示例的做法:
class Employee
{
Company company;
}
class Company
{
String name;
}
我需要保证不同的 Company 对象具有唯一的名称 - 即没有两个这样的对象可能具有相同的名称名称,因为从我的角度来看,它没有任何意义,而且只会消耗内存 - 如果两个员工在 IBM 工作,那么就会有一个具有该名称的 Company
对象, 时期。
我现在的想法是将 Company
构造函数设为私有 - 以便将具有任意名称的 Company 对象分配的工作委托给受信任的方法 - 假设该方法将拒绝任何后续创建对象的尝试使用已存在的名称或返回现有或新对象(如有必要,创建一个)。
问题是,我不知道如何优雅地完成这个任务。一件好事是不必在每次请求具有名称的 Company
对象时都进行 O(n)
查找 - 所以可能是哈希映射或二进制文件树是为了我的方便吗?我还想覆盖 Company
对象的识别方式 - 这导致我这样做:我会覆盖 Object.equals
和/或 Object.hashCode方法?
This is a trivial programming question. I am not an expert in Java. Say I use objects of custom classes Company and Employee, in a manner similar to what many RDBMS examples do:
class Employee
{
Company company;
}
class Company
{
String name;
}
I need to guarantee that different Company
objects have unique names - i.e. no two such objects may have the same name, because from my point of view it makes no sense, and also simply eats memory - if two employees work at IBM, then there is a single Company
object with that name
, period.
My thoughts right now go along of making Company
constructor private - so that the job of allocating Company objects with arbitrary names is delegated to a trusted method - which, suppose, will reject any subsequent attempt to create an object with a name that already exists or return an existing or new object (creating one if necessary).
The problem is, I am not sure how to accomplish this elegantly. One thing that would be nice is not having to do a O(n)
lookup every time an Company
object with a name is requested - so maybe a hash map or a binary tree is there for my convenience? I would also like to override the way the Company
objects are identified - which leads me to this: will I be overriding Object.equals
and/or Object.hashCode
methods?
发布评论
评论(5)
看看蝇量级模式。
我会做的是这样的:
Take a look at the flyweight pattern.
What I would do is something like:
您可以覆盖
equals
和hashCode
并将它们存储在HashMap
或HashSet
中。You could override
equals
andhashCode
and store them in aHashMap
orHashSet
.听起来不错,是的。
如果您确保永远不会有两个实例具有相同的键值,那么实际上您不必这样做。
That sounds right, yes.
If you ensure that there are never two instances with the same key value, you actually don't have to do that.
当我想要创建可以通过唯一名称查看的对象集合时,我存储一个 字符串(名称)到对象的映射。然后我可以查找与名称相关的对象。
严格来说,您不需要触摸 equals() 和 hashCode() 来做到这一点,因为您没有将对象存储为键。正确实现 equals() 和 hashCode() 可能很难,并且像 HashMap(可以为您提供高效查找)这样的 Map 实现中的键对这些方法很敏感。使用现有的(并且至关重要的是不可变的)String 类作为键可以帮助您正确获得此查找功能。
更新:如果您将构造函数设置为私有,正如您所提到的,您可以阻止创建新的 Company 实例。提供一些其他创建 Company 实例的方法(工厂模式)可让您确保“新”Company 实例仅当尚未按名称存储时才真正是新的,否则返回给定名称的现有实例(单例)
When I want to create a collection of objects that can be looked by by unique names, I store a Map of Strings (names) to Objects. I can then look up the object related to a name.
Strictly speaking, you don't need to touch equals() and hashCode() to do that, as you are not storing your objects as keys. Implementing equals() and hashCode() correctly can be difficult to get right, and keys in a Map implementation like HashMap (which can give you efficient lookups) is sensitive to these methods. Using the existing (and crucially immutable) String class as keys helps you get this lookup functionality right.
Update: If you make your constructor private, as you mentioned, you can prevent the creation of new Company instances. Providing some other method of creating Company instances (Factory pattern) allows you ensure that 'new' Company instances are only really new if they are not already stored by name, otherwise the existing instance for a given name is returned (example of Singleton)
如果对象的名称可能会随着时间的推移而改变,请考虑为每个对象添加一个生成的唯一 ID。您的映射将从名称到唯一 ID,然后从唯一 ID 到实际对象。
顺便说一句,如果对象在编译时都是已知的,则可以使用枚举。
If the name of an object can change over time, consider including a generated unique ID for each object. Your mapping would be from name to unique ID, then from unique ID to the actual object.
By the way, if the objects were all known at compile time, you could use an Enum.