如果您有基于 int 的 equals/hashcode,那么匹配“完整”字符串的最佳方法是什么?来自另一个集合的对象?

发布于 2024-12-06 17:05:03 字数 628 浏览 0 评论 0原文

假设您有这个 DTO 类:

public class MyObj{
 private int id;

 private String displayName;
 private String backendData;

 public boolean equals(Object obj){
  return id.equals(obj);
 }

 private int hashCode(){
  return id.hashCode();
 }
}

假设用户必须从仅显示 displayName 的列表中选择几个 MyObj 实例,并且 id# 在后台关联。为了节省带宽,您不发送 backendData。当他们将选择提交给您时,客户只需向您发送 id#。

现在,您已经在 Collection中维护了原始选项服务器端的列表。从集合中获取“完整”对象的简单方法是迭代集合并对每个对象调用“.equals()”。不过,这在 O(n) 中扩展:(

似乎对于像 HashSet 这样的恒定时间操作集合,如果我知道它的身份,我应该能够在恒定时间内检索一个对象。但是 HashSet 只有一个“contains()”方法并且不返回它找到的对象。

有什么建议吗?谢谢 stackOverFlow!

Say you had this DTO class:

public class MyObj{
 private int id;

 private String displayName;
 private String backendData;

 public boolean equals(Object obj){
  return id.equals(obj);
 }

 private int hashCode(){
  return id.hashCode();
 }
}

Lets say a user got to pick several instances of MyObj from a list that only showed the displayName and the id# is associated in the background. To save bandwidth, you don't send backendData. When they submit their selection back to you, the client just sends you the id#.

Now, you've maintained the list of original options server side in a Collection<MyObj>. The naive approach to geting the "full" object back from the collection would be to iterate through the Collection and call ".equals()" on every object. This scales in O(n) though :(

It seems like with constant time operations collections like HashSet, I should be able to retrieve an object in constant time, if I know it's identity. But HashSet only has a "contains()" method and doesn't return the object it found.

Any advice? As always, thanks a bunch stackOverFlow!

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

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

发布评论

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

评论(4

摘星┃星的人 2024-12-13 17:05:03

我假设 id 在整个集合中是唯一的?

您几乎可以使用 Map ,然后 map.get(id) 是渐近常数时间。

I assume id is unique across the collection?

You are almost there use a Map<Integer, MyObj> then map.get(id) is asymptotically constant time.

一萌ing 2024-12-13 17:05:03

你的对象不起作用(因为你不能调用原始数据类型的方法)。将您的 id 更改为 Integer,并在哈希集合中使用它。

Map<Integer, T> objectMap = ...;
Integer id = someidfromfrontend;
T anObj = objectMap.get(id);

You're object doesn't work (because you can't call methods on primitive data types). Change your id into an Integer, and use it in a hashed collection.

Map<Integer, T> objectMap = ...;
Integer id = someidfromfrontend;
T anObj = objectMap.get(id);
萌酱 2024-12-13 17:05:03

hashCode 旨在快速获取对象的编号。 equals 应该对要验证对象相等性的所有字段进行完整比较。

public class MyObj
{
    private final Integer id;

    private String displayName;
    private String backendData;

    public boolean equals(Object obj)
    {
        final MyObj other;

        if(obj == null || obj.getClass() != MyObj.class)
        {
            return (false);
        }

        other = (MyObj)obj;

        if(!(displayName.equals(other.displayName))
        {
            return (false);
        }

        if(!(backendData.equals(other.backendData))
        {
            return (false);
        }

        return (true);
    }

    private int hashCode()
    {
        return id.hashCode();
    }
}

这假设所有字段都不能为空,如果它们可以为空,则 if 语句中的情况会稍微复杂一些。

hashCode is intended to just get a quick number for an object. equals should do a full comparison of all the fields that you want to verify for object equality.

public class MyObj
{
    private final Integer id;

    private String displayName;
    private String backendData;

    public boolean equals(Object obj)
    {
        final MyObj other;

        if(obj == null || obj.getClass() != MyObj.class)
        {
            return (false);
        }

        other = (MyObj)obj;

        if(!(displayName.equals(other.displayName))
        {
            return (false);
        }

        if(!(backendData.equals(other.backendData))
        {
            return (false);
        }

        return (true);
    }

    private int hashCode()
    {
        return id.hashCode();
    }
}

This assumes none of the fields can be null, it is a bit more complex in the if statements if they can be null.

音盲 2024-12-13 17:05:03

恕我直言,您的问题提出了多个问题:首先不要使用数据库 ID 作为哈希键,如果该东西是自动生成的,您可能会遇到麻烦。第二个 hashset/map 使用 hashcode 和 equals 方法来检索对象(当您使用 get 方法时)。首先,哈希码用于快速查找对象可能所在的存储桶。然后,如果哈希集合中存在冲突并且该存储桶中有多个对象,则将使用 equals 来检索该对象。因此,当您在此处将 get 与您的类的实例一起使用时,只有 hashcode 和 equals 中使用的字段需要具有正确的值才能检索您的对象。在这种情况下,如果您的对象具有正确的 id(但其他字段错误),则可以使用它来检索填充了其他字段的对应对象。或者你可以使用地图。

Your question presents multiple issues IMHO: first off don't use the db id as a hash key, you could get in trouble if that thing is autogenerated. Second hashset/map use hashcode and equals methods to retrieve objects (when u use the getmethod). First the hashcode is used to quickly find the bucket where your object might be. Then if there were collisions in your hash collection and there s multiple objects in the in that bucket then equals will be used to retrive the object. So when u use get with an instance of your class here only the fields that are used in hashcode and equals need to have the correct value in order to retrieve your object. In this case if ur object has the right id (but wrong other field) it could be used to retrieve its counterpart with the otherfield populated. That or u can use a map.

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