Java-Groovy:以对象为键的映射

Java-Groovy:以对象为键的映射,java,groovy,Java,Groovy,我在如何从使用自定义对象索引的映射中检索值方面遇到了问题。在我的例子中,我有一个地图,其中一个模型对象作为键,一个对象列表作为值。 地图似乎填充得很好,因为我已经遍历了每个键,并将所有模型对象打印到控制台 我的问题是如何从地图中的特定条目中获取值 Map<Model, Parameter> mapSet = m.getMyMap() for(Entry<Model, Parameter> entry : mapSet){ println entry.key.ge

我在如何从使用自定义对象索引的映射中检索值方面遇到了问题。在我的例子中,我有一个地图,其中一个模型对象作为键,一个对象列表作为值。 地图似乎填充得很好,因为我已经遍历了每个键,并将所有模型对象打印到控制台

我的问题是如何从地图中的特定条目中获取值

Map<Model, Parameter> mapSet = m.getMyMap()

for(Entry<Model, Parameter> entry : mapSet){
    println entry.key.getModel() //prints each Model
}

List<Parameter> testListBase = mapSet.get(new Model("BASE"))

List<Parameter> testListSearch = mapSet.get(new Model("SEARCH"))

}是的,
模型
必须实现
hashCode()
等于(对象)

…如果将可变对象用作贴图键,则必须非常小心。 如果对象的值为,则不会指定贴图的行为 以影响相等比较的方式更改,而对象 是地图上的一把钥匙

您可以使用Groovy的AST转换非常轻松地实现
hashCode()
equals(Object)
。下面是一个工作示例:

@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
class Model {
    String name
}

@groovy.transform.TupleConstructor
class Parameter {
    String name
}

Map<Model, List<Parameter>> mapSet = [
    (new Model('BASE')): [
        new Parameter('Some parameter'), 
        new Parameter('Another parameter')
    ],

    (new Model('SEARCH')): [
        new Parameter('Yet another parameter'), 
        new Parameter('And yet another parameter')
    ]
]

for(Map.Entry<Model, List<Parameter>> entry: mapSet) {
    println entry.key // Prints each Model
}

List<Parameter> testListBase = mapSet.get(new Model("BASE"))
List<Parameter> testListSearch = mapSet.get(new Model("SEARCH"))

assert testListBase*.name.containsAll(['Some parameter', 'Another parameter'])
assert testListSearch*.name.containsAll(['Yet another parameter', 'And yet another parameter'])
@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
类模型{
字符串名
}
@groovy.transform.TupleConstructor
类参数{
字符串名
}
映射集=[
(新型号(“基础”):[
新参数(“某些参数”),
新参数(“另一个参数”)
],
(新型号(“搜索”):[
新参数(“另一个参数”),
新参数('还有另一个参数')
]
]
for(Map.Entry:mapSet){
println entry.key//打印每个模型
}
List testListBase=mapSet.get(新模型(“基”))
List testListSearch=mapSet.get(新模型(“搜索”))
assert testListBase*.name.containsAll(['Some parameter','other parameter'])
assert testListSearch*.name.containsAll(['另一个参数','和另一个参数']))
为了方便起见,我使用了
TupleConstructor
AST,但是这里的工作马是
EqualsAndHashCode
。请注意,我假设了您的意图,因此偏离了您的示例来编写您所说的代码:

…以模型对象作为键,以对象列表作为值的贴图


EqualsAndHashCode
文档描述了在需要时如何调整默认行为。

当然可以。否则,模型对象只与自身相等。您的hashCode和equals不起作用,因为它们考虑了模型id。例如,断言
assert new Model(“hello”)==new Model(“hello”)
失败,因为两个模型具有不同的id。您可以通过从hashCode和equals中排除id来解决此问题。我同时更改了
hashCode()
equals()
,现在我有了一个StackOverflower错误由于模型名(名为model的字段)是唯一建立相等的东西,那么您只需拥有
hashCode()
equals()
委托给
字符串
模型。例如:
public int hashCode(){model.hashCode()}
public boolean equals(Object obj){model.equals(obj)}
。即使我委托了。。。
@groovy.transform.TupleConstructor
@groovy.transform.EqualsAndHashCode
class Model {
    String name
}

@groovy.transform.TupleConstructor
class Parameter {
    String name
}

Map<Model, List<Parameter>> mapSet = [
    (new Model('BASE')): [
        new Parameter('Some parameter'), 
        new Parameter('Another parameter')
    ],

    (new Model('SEARCH')): [
        new Parameter('Yet another parameter'), 
        new Parameter('And yet another parameter')
    ]
]

for(Map.Entry<Model, List<Parameter>> entry: mapSet) {
    println entry.key // Prints each Model
}

List<Parameter> testListBase = mapSet.get(new Model("BASE"))
List<Parameter> testListSearch = mapSet.get(new Model("SEARCH"))

assert testListBase*.name.containsAll(['Some parameter', 'Another parameter'])
assert testListSearch*.name.containsAll(['Yet another parameter', 'And yet another parameter'])