Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从java中的HashMap返回通配符匹配列表_Java_String_Hashmap_Wildcard - Fatal编程技术网

从java中的HashMap返回通配符匹配列表

从java中的HashMap返回通配符匹配列表,java,string,hashmap,wildcard,Java,String,Hashmap,Wildcard,我有一个Hashmap,它可能在字符串中包含通配符(*) 比如说, HashMap<String, Student> students_; HashMap学生; 可以把约翰*当作一把钥匙。我想知道JohnSmith是否匹配学生的任何元素。我的字符串可能有几个匹配项(John*、Jo*Smith等)。有没有办法从HashMap中获取这些匹配项的列表 是否有另一个我可以使用的对象不需要我遍历集合中的每个元素,或者我必须吸收它并使用列表对象 仅供参考,我的集合中只有不到200个元素,最

我有一个Hashmap,它可能在字符串中包含通配符(*)

比如说,

HashMap<String, Student> students_;
HashMap学生;
可以把约翰*当作一把钥匙。我想知道JohnSmith是否匹配学生的任何元素。我的字符串可能有几个匹配项(John*、Jo*Smith等)。有没有办法从HashMap中获取这些匹配项的列表

是否有另一个我可以使用的对象不需要我遍历集合中的每个元素,或者我必须吸收它并使用列表对象


仅供参考,我的集合中只有不到200个元素,最终我希望找到与最少通配符匹配的元素对。

由于哈希函数,使用hasmap无法实现。它必须将
“John*”
的哈希值和
“John Smith”
等的哈希值赋值相同

如果您编写自己的自定义类
WildcardString
包装字符串,并以
“John*”的方式实现
compareTo
,则可以使用树形图来实现。compareTo(“John Smith”)
返回0。你可以用正则表达式来实现这一点,就像你已经指出的那样

看到您想要widlcard匹配列表,您可以随时删除找到的条目,并迭代
TreeMap.get()
。记着一旦写完名字就把钥匙放回去

这只是实现这一目标的可能途径。使用少于200个元素,可以进行良好的迭代


更新:要正确地对
树集
施加顺序,您可以区分比较两个
通配符字符串
和将
通配符字符串
字符串
进行比较(将键与搜索值进行比较)。

您可以使用正则表达式进行匹配,但是您必须首先将
“John*”
转换为与regex等价的
“John.*”
,尽管您可以随时这样做

以下是一些有效的代码:

String name = "John Smith"; // For example
Map<String, Student> students_ = new HashMap<String, Sandbox.Student>();

for (Map.Entry<String, Student> entry : students_.entrySet()) {
    // If the entry key is "John*", this code will match if name = "John Smith"
    if (name.matches("^.*" + entry.getKey().replace("*", ".*") + ".*$")) {
        // do something with the matching map entry
        System.out.println("Student " + entry.getValue() + " matched " + entry.getKey());
    }
}
String name=“John Smith”//例如
Map students_u2;=新建HashMap();
对于(Map.Entry:students\uu.entrySet()){
//如果输入键为“John*”,则如果name=“John Smith”,则此代码将匹配
if(name.matches(“^.*”+entry.getKey()。替换(“*”,“*”+“*$”)){
//对匹配的地图条目执行一些操作
System.out.println(“学生”+entry.getValue()+“匹配”+entry.getKey());
}
}

您只需迭代地图,而无需将其转换为列表,并使用字符串匹配函数,使用regexp

如果你想避免循环,你可以像这样使用番石榴

@Test
public void hashsetContainsWithWildcards() throws Exception {
Set<String> students = new HashSet<String>();
students.add("John*");
students.add("Jo*Smith");
students.add("Bill");

Set<String> filteredStudents = Sets.filter(students, new Predicate<String>() {
  public boolean apply(String string) {
    return "JohnSmith".matches(string.replace("*", ".*"));
  }
});

assertEquals(2, filteredStudents.size());
assertTrue(filteredStudents.contains("John*"));
assertTrue(filteredStudents.contains("Jo*Smith"));
@测试
public void hashsetcontainswithildcards()引发异常{
Set students=newhashset();
学生。添加(“John*”;
学生。添加(“Jo*Smith”);
学生。添加(“法案”);
Set filteredStudents=Set.filter(学生,新谓词(){
公共布尔应用(字符串){
返回“JohnSmith”.matches(string.replace(“*”,“*”));
}
});
assertEquals(2,filteredStudents.size());
assertTrue(filteredStudents.contains(“John*”));
assertTrue(filteredStudents.contains(“Jo*Smith”);

}

散列函数通常是以一种方式构造的,即对
John SmitH
进行微小更改(例如:
John SmitH
)会产生完全不同的散列。为什么不进行迭代?这并不是那么糟糕(尤其是少于200个元素),最终任何其他解决方案都可能涉及到类似的性能。少于200个元素时,只需对
entrySet()
进行线性搜索,并根据每个键计算通配符。如果可以的话,我建议使用一个(嵌入式)数据库和类似于的查询。谢谢大家。名单并不多,但我可能不得不经常做get。我很好奇是否有一种更有效的方法来做到这一点,但也许不可能复制谢谢你,哈维。对于200个列表,您认为使用树集会对性能有什么好处吗?在WildCardString类中创建compareTo(string)方法会破坏compareTo方法的契约,因为:
WildCardString。compareTo(string)
可能不是相反的符号或
string.compareTo(WildCardString)
。此外,我们建议compareTo与equals保持一致。@Guillaume不,他没有明确表示。具体地说,他说:我是否可以使用另一个不需要遍历集合中的每个元素的对象,或者我是否必须吸收它并使用列表对象?。我通过确认或部分来回答这个问题。波希米亚人,你这个诡辩家:-)无论如何,我同意你的回答。我不明白他为什么不想重复。