当前位置: 首页 > 知识库问答 >
问题:

Javahashmap-键基于两个不同类型的对象

严朝明
2023-03-14

我想编写一个Java类,根据相关的时间戳计算一些规则(对于每个rueleId)的出现次数。

例如

输入:

{"ruleId": "1", "timestamp":"Thu Jun 18 16:25:56 PDT 2015"}
{"ruleId": "1", "timestamp":"Thu Jun 18 16:25:56 PDT 2015"}
{"ruleId": "2", "timestamp":"Thu Jun 18 16:25:56 PDT 2015"}
{"ruleId": "2", "timestamp":"Thu Jun 18 16:25:56 PDT 2015"}
{"ruleId": "2", "timestamp":"Thu Jun 18 16:27:56 PDT 2015"}

输出:

timestamp: "Thu Jun 18 16:25:56 PDT 2015", ruleId: "1", count: 2
timestamp: "Thu Jun 18 16:25:56 PDT 2015", ruleId: "2", count: 2
timestamp: "Thu Jun 18 16:27:56 PDT 2015", ruleId: "2", count: 1

我想我可以利用HashMap。

我认为这里的键是基于ruleId(type:String)和timestamp(type:Calendar)的,值是计数。

我怎样才能拥有基于两个不同对象的密钥?我的方法错了吗?

共有2个答案

鲜于谦
2023-03-14

HashMap只有一种键类型。事情就是这样。

所以你有两个选择。

生成一个密钥字符串,作为HashMap的密钥。在你的情况下,这是一件很容易做到的事情,可能正是你所需要的。您可以生成类似于“time:”时间戳的内容。toString()“-rule:”ruleId,并将其用作键。在你的情况下,它会起作用的。

第二种方法稍微复杂一点,但是如果您想再次分离键中使用的值,或者如果您将更复杂的值作为键,这种方法更适合。这个想法是创建一个新的类作为键值的载体。

对于第二个想法,重要的是覆盖载体对象的hashCodeequals函数,以使其与HashMap正常工作。

基本上你需要这样的东西:

public class Carrier {
    private final Calendar timestamp;
    private final String ruleId;

    public Carrier(Calendar timestamp, String ruleId) {
        this.timestamp = timestamp;
        this.ruleId = ruleId;
    }

    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 17 + timestamp.hashCode();
        hash = hash * 17 + ruleId.hashCode();
        return hash;
    }

    @Override 
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceOf Carrier) {
            return false;
        }

        Carrier other = (Carrier) obj;
        return Objects.equals(ruleId, other.ruleId) && Objects.equals(timestamp, other.timestamp);
    }
}
公冶谦
2023-03-14

您必须创建一个复合密钥:

public final class CompositeKey {
    private final String ruleType;
    private final Calendar timeStamp;

    public CompositeKey(String ruleType, Calendar timeStamp) {
        this.ruleType = Objects.requireNonNull(ruleType);
        this.timeStamp = (Calendar) Objects.requireNonNull(timeStamp).clone();
    }

    public String ruleType() { return ruleType; }
    public Calendar timeStamp() { return (Calendar) timeStamp.clone(); }

    @Override public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        CompositeKey other = (CompositeKey) obj;
        return Objects.equals(ruleType, other.ruleType) && Objects.equals(timeStamp, other.timeStamp);
    }

    @Override public int hashCode() { return Objects.hash(ruleType, timeStamp); }
}

HashMap中用作键时,不能修改对象,这一点至关重要。因此,它必须是不变的。上面的类通过成为final,不提供setter,并克隆时间戳(因为日历不是不变的)来实现这一目标。

另一件非常重要的事情是,键类必须提供适当的equalshashCode方法。

有了这个类,您可以在HashMap中使用它:

String ruleType = ...
Calendar timeStamp = ...
CompositeKey key = new CompositeKey(ruleType, timeStamp);
Object value = ...

Map<CompositeKey, Object> map = new HashMap<>();
map.put(key, value);
 类似资料:
  • 我有两个数组: 阵列 1: 和阵列 2: 我需要根据合并这两个数组并得到这个: 不通过< code>Object.keys进行迭代,我如何做到这一点?

  • 我有三节课: 人类 父亲 孩子。 儿童阶级延伸父亲,父亲延伸人类。 我已经创建了每个类的一些实例并将它们存储到ArrayList中。 现在,我想编写一个方法来检查对象father1是否与对象child1地址字段(类Father和Child的实例)具有相同的字段地址(例如:“21 str Goodwin”),并将此方法提供给我的ArrayList,如果发现任何结果,则打印。 我怎么能这样呢? 为了更

  • 我使用一个Android库,它要求我创建两个类,每个类继承自不同的类 (具有公共基类) 现在我有这个代码: 我必须复制这个类来创建一个扩展,即使我的两个类共享完全相同的代码。 我简化了示例的代码,但重复可能很重要 我决定将代码放在这两个类之外的静态方法中,并在类重写的方法中调用它们,但我认为必须有一种更干净的方法来做到这一点。 你能帮我解决这个问题吗? 和都继承自。

  • 问题内容: 我们是否可以用一个键和两个值实现HashMap。就像HashMap一样? 还请告诉我(如果没有办法)通过其他任何方法来实现三个值的存储(以一个为键)的方法,对我有帮助吗? 问题答案: 你可以: 使用具有列表作为值的地图。 创建一个新的包装器类,并将该包装器的实例放置在地图中。。 使用类似类的元组(节省创建许多包装器)。。 并排使用多个地图。 例子 1.使用列表作为值进行映射 这种方法的

  • 假设我有两个列表,现在listOld包含旧员工信息,listNew包含新员工信息 我如何比较这两个列表并返回新列表,其中包含,添加的新员工列表,包含,删除的员工列表,包含上次更新已更改的员工的新列表? 我只能想到迭代列表和比较,可能最终几乎是O(n2)时间,这可以由任何util类更有效地完成吗?

  • 我正在使用Mockito编写单元测试,但我在模仿注入的类时遇到了问题。问题是两个注入的类是相同的类型,仅通过它们的注释来区分。如果我试图简单地模拟,那么在我的测试中,该模拟不会被注入,并且该对象为。我如何模拟这些对象?