可以用Java控制对象的身份,如果是,如何控制?

时间:2010-09-27 21:01:15

标签: java map hashmap identity

这是一个简单的编程问题。我不是Java专家。假设我使用自定义类Company和Employee的对象,方式类似于许多RDBMS示例所做的那样:

class Employee
{
    Company company;
}

class Company
{
    String name;
}

我需要保证不同的Company对象具有唯一的名称 - 即没有两个这样的对象可能具有相同的名称,因为从我的观点来看,它没有意义,也只是吃了记忆 - 如果有两个员工在IBM工作,然后有一个Companyname对象。

我现在的想法是将Company构造函数设为私有 - 以便将具有任意名称的公司对象分配的工作委托给受信任的方法 - 假设该方法将拒绝任何后续创建对象的尝试使用已存在的名称或返回现有或新对象(必要时创建一个)。

问题是,我不确定如何优雅地完成这项工作。一件好事就是每次请求带有名称的O(n)对象时都不必进行Company查找 - 所以为方便起见,可能还有哈希映射或二叉树吗?我还想覆盖Company对象的识别方式 - 这导致我:我会覆盖Object.equals和/或Object.hashCode方法吗?

5 个答案:

答案 0 :(得分:8)

看一下flyweight模式。

我会做的是:

// 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);
    }
}

答案 1 :(得分:4)

您可以覆盖equalshashCode并将其存储在HashMapHashSet

答案 2 :(得分:1)

  

一件好事不是   每次必须进行O(n)查找   名称为的公司对象是   请求 - 所以也许哈希映射或   二叉树是我的   方便?

这听起来是对的,是的。

  

我还想覆盖这种方式   确定公司对象 -   这让我想到了:我会吗?   重写Object.equals和/或   Object.hashCode方法?

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

答案 3 :(得分:1)

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

严格地说,您不需要触摸equals()hashCode()来执行此操作,因为您不将对象存储为键。正确实现equals()和hashCode()可能很难正确,而像HashMap这样的Map实现中的键(可以为您提供高效的查找)对这些方法很敏感。使用现有(并且至关重要的不可变)String类作为键可以帮助您正确地获得此查找功能。


更新:如果您将构造函数设为私有,如上所述,您可以阻止创建新的Company实例。提供一些其他创建公司实例的方法(Factory pattern)可以确保“新”公司实例只有在尚未按名称存储时才真正是新的,否则将返回给定名称的现有实例(例如Singleton

答案 4 :(得分:0)

如果对象的名称可能会随时间发生变化,请考虑为每个对象包含生成的唯一ID。您的映射将从名称到唯一ID,然后从唯一ID到实际对象。

顺便说一下,如果对象在编译时都是已知的,你可以使用Enum。