【问题标题】:Searching for a value in an Array of objects [closed]在对象数组中搜索值[关闭]
【发布时间】:2017-01-10 13:18:06
【问题描述】:

除了主要课程(人 + 电话簿)之外,我还有 2 个额外的课程。我正在将 Person 对象添加到我在 Phonebook 类中创建的 ArrayList 中。

现在我想在我的电话簿类中实现一个方法,该方法将接收一个字符串(电话簿中的人的姓名),如果该人在电话簿中,则返回该号码。我尝试了几种方法,例如尝试从 Person 对象调用 getName() 方法。

这就是我现在拥有的:

人物类:

public class Person {
    private String name; 
    private String number;


    public Person(String name, String number) {
        this.name = name;
        this.number = number;                      
    }

    public String getName() {
        return this.name; 
    }

    public String getNumber() {
        return this.number; 
    }

    public void changeNumber(String newNumber) {
        this.number = newNumber; 
    }

    public String toString() {
        return getName() + " " + "number: " + getNumber(); 
    }

}

电话簿类:

import java.util.ArrayList;

public class Phonebook {
  private ArrayList<Person> person; 
    public Phonebook() {
        this.person = new ArrayList<Person>(); 
    }  


    public void add(String name, String number) {


    Person newPerson = new Person(name, number); 
    person.add(newPerson);

    }
    public void printAll() {
           for (Person prs : person) {
               System.out.println(prs);
           }
    }

    public String searchNumber(String name) {
        if (person.contains(name)) {
            return person.toString(); 
        }
            return "number not know"; 
    }




}

【问题讨论】:

  • 好吧,你不能只比较 PersonString 并期望 java 知道逻辑相等的位置;)
  • 您可以使用地图而不是列表。这样您就可以在不遍历列表的情况下搜索人员。地图的键是人员的姓名和人员对象的值。

标签: java string arraylist methods


【解决方案1】:

将此添加到您的人:

public boolean matchesName(String name) {
   return this.name.toLowerCase().indexOf(name.toLowerCase()) > -1;
}

此方法的作用是将两个名称都设为小写,以避免 Smith 与 smith 不匹配。然后它检查搜索键是否包含在人员姓名中。 如果是,则返回 true。如果不是,则返回 false。 所以smith 将匹配john smith,但也匹配jake Smithsson

然后在你的搜索方法中

public String searchNumber(String name) {
     for (Person prs : person) {
          if(prs.matchesName(name)) {
            return prs.toString();
          }
     }
     return "number not known"; 
}

您需要遍历列表才能找到它们。

如果您的数量少于 10.000,则速度非常快。如果您要添加更多名称,则需要开始考虑索引或数据库存储等问题。

但是,这只返回一个人。

最好返回所有匹配项。

public List<Person> searchNumber(String name) {
     ArrayList<Person> matchlist = new ArrayList<Person>();
     for (Person prs : person) {
          if(prs.matchesName(name)) {
            matchlist.add(prs);
          }
     }
     return matchlist; 
}

为什么不是地图?您可以根据自己的意愿修改其中的搜索功能。

例如,如果您有斯堪的纳维亚人的名字,但人们在美国搜索查询中输入:

class AccentedNamePerson extends Person {
    private String normalised;
    private String normalisedName() {
       if(normalised != null) return normalised;
       normalised = Normalizer.normalize(string, Normalizer.Form.NFD);
       /** assuming input is in unicode. if ascii use .replaceAll("[^\\p{ASCII}]", ""); **/
       normalised  = normalised.replaceAll("\\p{M}", "");
       return normalised;
    }
    @Override
    public boolean matchesName(String name) {
        String
        return this.normalisedName().toLowerCase().indexOf(name.toLowerCase()) > -1;
    }
}

【讨论】:

  • 这没问题,但使用 @Benat 建议的地图更有效。
  • 嘿,很好的答案,很好的解释。非常感谢,谢谢。
  • 是的,但是使用此解决方案,您可以进行部分匹配,并修改每个人实例的 .matchesName。也许您需要对斯堪的纳维亚名称、utf8、数据源轮询等进行特殊调整...
猜你喜欢
  • 2017-04-20
  • 2023-02-21
  • 1970-01-01
  • 2021-11-22
  • 2013-12-18
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 2021-09-03
相关资源
最近更新 更多