我有ContactList,其中包含firstName和lastName的联系人。我想通过FirstName或lastName执行搜索。
我已经编写了可以正常运行的代码,但我希望在速度和内存方面改进搜索。
public class Contact implements Comparable<Contact> {
private String firstName;
private String lastName;
private String name;
public Contact(String name) {
this.name = name;
if (name.contains(" ")) {
this.firstName = name.split("\\s+")[0];
this.lastName = name.split("\\s+")[1];
} else {
this.firstName = name;
this.lastName = "";
}
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Contact{" + name + '}';
}
@Override
public int compareTo(Contact contact) {
System.out.println("in compareto");
return this.name.compareToIgnoreCase(contact.getName());
}
@Override
public int hashCode() {
return (firstName.hashCode() * (lastName != null ? lastName.hashCode() : 0));
}
@Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(!(obj instanceof Contact))
return false;
Contact other = (Contact) obj;
if(! this.name.equalsIgnoreCase(other.name)) return false;
return true;
}
}
public class ContactService {
private Set<Contact> contacts;
public ContactService() {
this.contacts = new TreeSet<>();
}
public void addContact(String name) {
Contact contact = new Contact(name);
contacts.add(contact);
}
public void searchContact(String searchStr) {
System.out.println(contacts);
for (Contact contact : contacts) {
if (contact.getName().equalsIgnoreCase(searchStr)||(searchStr.contains(" ") && contact.getName().contains(searchStr))) {
System.out.println(contact.getName());
} else if (contact.getFirstName().toLowerCase().startsWith(searchStr) || contact.getLastName().toLowerCase().startsWith(searchStr)) {
System.out.println(contact.getName());
}
}
}
}
请在上面的代码中建议如何提高效果。
答案 0 :(得分:1)
您可以使用java.util.HashMap
来存储搜索字词的“联系人”查找表。
这个想法是用可能的搜索词(例如名字的名字或前三个字母)预填充查找表。如果您的查找未返回任何匹配项,则您始终可以执行完整搜索。如果您想要更强大的搜索功能,可以查看类似Apache Lucene的内容。
E.g。
Map<String, Set<Contact>> contactLookup = new HashMap<>();
然后,您首先在地图中查找搜索词。这样可以缩小使用上面使用的相同方法迭代的小集合的可能性。
您还可以查看来自Guava的Multimap
,它可以更优雅地提供相同的功能。
顺便说一句(在不相关的说明中)当您覆盖compareTo()
方法时,最好还是覆盖equals()
以便
(x.compareTo(y)==0) == (x.equals(y))
。
当您覆盖equals()
时,您还需要覆盖hashCode()
!
答案 1 :(得分:0)
我没有预定义的searchTerms,我的要求就像User 进入了像“Manoj Pathak”,“Manoj”这样的联系人。如果用户输入“Man”和 点击搜索然后结果将是Manoj Pathak Manoj如果用户输入“Manoj” 并点击搜索然后结果将是Manoj(完全匹配)Manoj Pathak“
在这种情况下,我建议你实现最长前缀匹配 - 基于Trie的Java解决方案,内部将使用HashMap。