可以控制 Java 中对象的身份吗?如果可以,如何控制?

发布于 2024-09-25 03:25:57 字数 704 浏览 8 评论 0 原文

这是一个简单的编程问题。我不是 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

乙白 2024-10-02 03:25:57

看看蝇量级模式。

我会做的是这样的:

// incomplete, but you get the idea hopefully
CompanyFactory
{
    private Map<String, Company> companies;

    public getCompany(final String name)
    {
        Company company;

        company = compaines.get(name);

        if(company == null)
        { 
            company = new Company(name);
            companies.put(name, company);
        }

        return (company);
    }
}

Take a look at the flyweight pattern.

What I would do is something like:

// incomplete, but you get the idea hopefully
CompanyFactory
{
    private Map<String, Company> companies;

    public getCompany(final String name)
    {
        Company company;

        company = compaines.get(name);

        if(company == null)
        { 
            company = new Company(name);
            companies.put(name, company);
        }

        return (company);
    }
}
じее 2024-10-02 03:25:57

您可以覆盖 equalshashCode 并将它们存储在 HashMapHashSet 中。

You could override equals and hashCode and store them in a HashMap or HashSet.

祁梦 2024-10-02 03:25:57

有一件事会很好,但不是
每次都必须进行 O(n) 查找
一个名为的 Company 对象是
请求 - 所以可能是哈希映射或
二叉树是我的
方便吗?

听起来不错,是的。

我也想重写这个方法
公司目标已确定 -
这让我想到了这一点:我会吗?
重写 Object.equals 和/或
Object.hashCode 方法?

如果您确保永远不会有两个实例具有相同的键值,那么实际上您不必这样做。

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?

That sounds right, yes.

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?

If you ensure that there are never two instances with the same key value, you actually don't have to do that.

蒗幽 2024-10-02 03:25:57

当我想要创建可以通过唯一名称查看的对象集合时,我存储一个 字符串(名称)到对象的映射。然后我可以查找与名称相关的对象。

严格来说,您不需要触摸 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)

自找没趣 2024-10-02 03:25:57

如果对象的名称可能会随着时间的推移而改变,请考虑为每个对象添加一个生成的唯一 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文