使用regexp作为键的hashmap,groovy / java

时间:2016-09-09 13:47:54

标签: regex groovy hashmap

我遇到了一个问题:

是否可以将regexp用作hashmap中的键? 例如:

def unitsMap=[
    (~/(?i).*ABC.*nM.*/):'AAA',
    (~/(?i).*DEF.*nM.*/):'DDD'
]
println unitsH3HashMap['ABC (122344345P)']

当然,返回null值。

祝你好运

2 个答案:

答案 0 :(得分:3)

不,但你可以在开关中使用它:

def unitsMap(key) {
    switch(key) {
        case ~/(?i).*ABC.*/: return 'AAA'
        case ~/(?i).*DEF.*/: return 'DDD'
    }
}

println unitsMap('ABC (122344345P)')

答案 1 :(得分:0)

为了获得你想要的东西,你必须编写自己的Map实现,它使用模式匹配来执行getAt,putAt,contains等。但是,在我看来,在这种情况下查找的算法复杂性总是 O(n)。与HashMap( O(0))或TreeMap( O(log n))相比并不是很好。

@tim_yates的解决方案解决了所提出问题的原始轮廓,但不允许您动态添加新密钥(案例),就像您原来想要的代码一样。如果在飞行中改变你的地图"对你来说并不重要,那么你应该绝对使用他的解决方案(我现在赞同它现在给它+1)。如果没有,你可以调整他的代码来生成和调用一个可以做你想做的Map的脚本。

这个脚本:

// generate unitMapper
def generateUnitMapper(baseMap) {
    def script = '''{ key ->
    switch (key) {
'''
    script += baseMap.collect { k, v ->
        """        case ~/${k}/: return '${v}'
"""
    }.join("")
    script += '''        default: return null
    }
}
'''
}

// notice this map is just using the regular expression STRINGS as keys,
// not the PATTERN objects from the original poster's code
def starterMap = [
    /(?i).*ABC.*[\dA-Z]+.*/:'AAA',
    /(?i).*DEF.*[\dA-Z]+.*/:'DDD'
]
def closureScript = generateUnitMapper(starterMap)
def unitsClosure = Eval.me(closureScript)
println closureScript
println unitsClosure('ABC (122344345P)')
println()

// regenerate map and closure and rerun
def changedMap = [ /ABC .*/:'000' ] + starterMap
closureScript = generateUnitMapper(changedMap)
unitsClosure = Eval.me(closureScript)
println closureScript
println unitsClosure('ABC (122344345P)')

产生此输出:

{ key ->
    switch (key) {
        case ~/(?i).*ABC.*[\dA-Z]+.*/: return 'AAA'
        case ~/(?i).*DEF.*[\dA-Z]+.*/: return 'DDD'
        default: return null
    }
}

AAA

{ key ->
    switch (key) {
        case ~/ABC .*/: return '000'
        case ~/(?i).*ABC.*[\dA-Z]+.*/: return 'AAA'
        case ~/(?i).*DEF.*[\dA-Z]+.*/: return 'DDD'
        default: return null
    }
}

000