将 IndexOf 与 arrayList 中的 customObject 一起使用
Using IndexOf with a customObject in an arrayList
我希望能够使用 indexOf 方法 return 对象的位置,但只想传递联系人的姓名来搜索它,有什么办法可以做到这一点完成了吗?
我目前有这个方法:
private static ArrayList<Contacts> contactList = new ArrayList<Contacts>();
public class Contacts {
private String name;
private String number;
public Contacts(String name, String number) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
public void setName(String name) {
this.name = name;
}
public void setNumber(String number) {
this.number = number;
}
public int findItem(String name) {
return contactList.indexOf(name);
}
这是一个无需遍历整个列表即可实现此功能的函数,我认为复杂度小于 O(n):
public int findItem(String name)
{
int max = contactList.size();
//you might have to subtract this by one
//I'm not sure off the top
int descCnt = max;
for(int cnt = 0; cnt <= max/2; cnt++)
{
if(contactList.get(cnt).getName().equals(name)) return cnt;
if(contactList.get(descCnt).getName().equals(name)) return descCnt;
--descCnt;
}
}
你问的不在List#indexOf(Object)的合同中,所以不,你不应该试图让清单那样工作。
相反,您可以编写自己的方法来相对轻松地完成您想要的操作。只需遍历您的列表并找到与指定名称匹配的联系人。
/**
* Returns the List index of the Contact with the specified name. If no such
* Contact is found, -1 will be returned.
*/
public int findItem(String name) {
for (int i = 0; i < contactList.size(); i++) {
Contact contact = contactList.get(i);
if (null == contact) continue;
if (java.lang.Objects.equals(name, contact.getName())) return i;
}
return -1;
}
补充一下,我已经可以这样做了:
public void searchItem(String name) {
for(int i = 0; i < contactList.size(); i++) {
if(name.equals(contactList.get(i).getName())) {
System.out.println("Found " + name);
break;
}
else {
System.out.println("Could not find name!");
}
}
}
但是,如果我有一个更大的列表,这不是相当低效吗?有更有效的方法吗?
如果您要按名称对 Contacts
进行大量查找,则可以将实例放入 Map<String, Contacts>
。 Map
的具体类型取决于您的要求;一个 HashMap
可能就足够了。
代替contactList.add(contacts)
,您可以使用:
contactMap.put(contacts.getName(), contacts);
然后使用以下方法在地图中查找项目:
contactMap.get(someName);
这将比每次扫描列表更快地进行查找:与列表相比,O(n)
与 O(n)
相比,HashMap
的每次查找都是 O(1)
。但是,它会占用更多内存。
顺便说一下,您的 Contacts
class 看起来像是代表一个联系人,因此应该将其命名为单数:Contact
.
此外,您的 find
方法当前声明为实例方法:
public int findItem(String name) {
意味着您实际上需要 Contacts
的实例才能找到 Contacts
的另一个实例。相反,声明它 static
:
public static int findItem(String name) {
那么你可以在没有实例的情况下调用它:
Contacts found = Contacts.find("name");
如果你有兴趣。更好的方法是覆盖对象中的 equals() 和 hashcode()。并以正确的方式使用 indexOf。
您的 equals 可以根据名称确定相等性,因此删除所有额外和不必要的代码。
我希望能够使用 indexOf 方法 return 对象的位置,但只想传递联系人的姓名来搜索它,有什么办法可以做到这一点完成了吗?
我目前有这个方法:
private static ArrayList<Contacts> contactList = new ArrayList<Contacts>();
public class Contacts {
private String name;
private String number;
public Contacts(String name, String number) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
public void setName(String name) {
this.name = name;
}
public void setNumber(String number) {
this.number = number;
}
public int findItem(String name) {
return contactList.indexOf(name);
}
这是一个无需遍历整个列表即可实现此功能的函数,我认为复杂度小于 O(n):
public int findItem(String name)
{
int max = contactList.size();
//you might have to subtract this by one
//I'm not sure off the top
int descCnt = max;
for(int cnt = 0; cnt <= max/2; cnt++)
{
if(contactList.get(cnt).getName().equals(name)) return cnt;
if(contactList.get(descCnt).getName().equals(name)) return descCnt;
--descCnt;
}
}
你问的不在List#indexOf(Object)的合同中,所以不,你不应该试图让清单那样工作。
相反,您可以编写自己的方法来相对轻松地完成您想要的操作。只需遍历您的列表并找到与指定名称匹配的联系人。
/**
* Returns the List index of the Contact with the specified name. If no such
* Contact is found, -1 will be returned.
*/
public int findItem(String name) {
for (int i = 0; i < contactList.size(); i++) {
Contact contact = contactList.get(i);
if (null == contact) continue;
if (java.lang.Objects.equals(name, contact.getName())) return i;
}
return -1;
}
补充一下,我已经可以这样做了:
public void searchItem(String name) {
for(int i = 0; i < contactList.size(); i++) {
if(name.equals(contactList.get(i).getName())) {
System.out.println("Found " + name);
break;
}
else {
System.out.println("Could not find name!");
}
}
}
但是,如果我有一个更大的列表,这不是相当低效吗?有更有效的方法吗?
如果您要按名称对 Contacts
进行大量查找,则可以将实例放入 Map<String, Contacts>
。 Map
的具体类型取决于您的要求;一个 HashMap
可能就足够了。
代替contactList.add(contacts)
,您可以使用:
contactMap.put(contacts.getName(), contacts);
然后使用以下方法在地图中查找项目:
contactMap.get(someName);
这将比每次扫描列表更快地进行查找:与列表相比,O(n)
与 O(n)
相比,HashMap
的每次查找都是 O(1)
。但是,它会占用更多内存。
顺便说一下,您的 Contacts
class 看起来像是代表一个联系人,因此应该将其命名为单数:Contact
.
此外,您的 find
方法当前声明为实例方法:
public int findItem(String name) {
意味着您实际上需要 Contacts
的实例才能找到 Contacts
的另一个实例。相反,声明它 static
:
public static int findItem(String name) {
那么你可以在没有实例的情况下调用它:
Contacts found = Contacts.find("name");
如果你有兴趣。更好的方法是覆盖对象中的 equals() 和 hashcode()。并以正确的方式使用 indexOf。
您的 equals 可以根据名称确定相等性,因此删除所有额外和不必要的代码。