【问题标题】:Linear search over an ArrayList using a String as a parameter使用字符串作为参数对 ArrayList 进行线性搜索
【发布时间】:2016-07-29 14:22:04
【问题描述】:

我正在尝试使用 for-each 循环在我的方法 findContactsByName 中搜索包含在 ArrayList 中的字符串,如果在联系人中找到该字符串,则返回联系人,如果未找到该字符串,则返回 null被退回。但是,在测试我的代码时,一直返回 null,这是我的代码:

import java.util.*;

public class Phonebook {
    private String owner;
    private ArrayList<Contact> contacts = new ArrayList<Contact>();

    public void addContact(Contact contact) {
        contacts.add(contact);
    }

    public void show() {
        System.out.println(owner + "'s phonebook");
        for (Contact contact : contacts) {
            System.out.println(contact);
        }
    }

    public Contact findContactByName(String name) {
        for (Contact contact : contacts) {
            if (contacts.contains(name)) {
               return contact;
           }
       }
       return null;
    }
}

【问题讨论】:

  • 尝试以下命名约定:Contact 称为 Contact 很容易混淆。变量名应该是contact。
  • 考虑使用HashMap,而不是自己遍历ArrayList
  • 在你增强的 for 循环中做 (Contact contact : contacts) 代替,它更容易阅读,同时也是一个正确的实现,不使用类的名称作为变量的名称..跨度>
  • 请同时输入你的Contact pojo 类的代码

标签: java bluej


【解决方案1】:

您的 findContactByName 方法不正确。您正在遍历 ArrayList,但每个循环都使用ArrayList.contains 检查数组列表,它将列表本身中的对象与name 进行比较。

正确的做法是:

public Contact findContactByName(String name) {
    for (Contact contact : contacts) {
        if (contact.getName().equals(name)) {
            return contact;
        }
   }
   return null;
}

假设Contact 对象有一个名为getName 的方法。请注意,在每个循环中,我如何使用 for 循环中的 contact (Contact contact : contacts) 而不是 ArrayList 本身。

【讨论】:

  • 这不是空安全的。最好做 Objects.equals(contact.getName().name)
【解决方案2】:
public Contact findContactByName(String name) {
    for (Contact Contact : contacts) {
        if (contacts.contains(name)) {
            return Contact;
        }
   }
   return null;
}

这个函数是你问题的根本原因。您在if 块中的条件为:contacts.contains(name) 其中contacts 是整个联系人列表,您正在那里寻找一个字符串对象。那是行不通的。您想了解您的联系人是否包含具有特定姓名的联系人。比如:contact.getName().equals(name)。

所以你的函数应该是这样的:

public Contact findContactByName(String name) {
    for (Contact contact : contacts) {
        if (contact.getName().equals(name)) {
            return contact;
        }
   }
   return null;
}

【讨论】:

    【解决方案3】:

    使用 contains 的示例

    List<String> fruitsList = new ArrayList<>();
    fruitsList.add("Apple");
    fruitsList.add("Mango");
    fruitsList.add("Grapes");
    
    if(fruitsList.contains("Grapes")) {
    S.o.p("Found Grapes");
    }
    

    但是对于您的情况,您需要从 dto 中找到一个特定元素,如果找到特定名称,则将其返回,因此您的用例是:

    public Contact findContactByName(String name) {
        for (Contact contact : contacts) {
            if ((null!=contact.getName()) && contact.getName().equals(name)) {
                return contact;
            }
       }
       return null;
    }
    

    假设您的 Contact 类具有名称变量。 希望你能理解。

    【讨论】:

      【解决方案4】:

      除非特别需要使用ArrayList,否则我建议您最好将其替换为HashMap&lt;String, Contact&gt;,这样您就可以避免仅仅依靠Map.get(key)从头开始编写搜索算法方法。地图旨在通过某些键(索引)搜索值:

      public class Phonebook {
      
          private Map<String, Contact> contacts = new HashMap<String, Contact>();
      
          public void addContact(Contact Contact) {
              contacts.put(contact.getName(), contact);
          }
      
          public Contact findContactByName(String name) {
              return contacts.get(name);
          }
      }
      

      此外,搜索会被编入索引,因此速度会更快。

      【讨论】:

        猜你喜欢
        • 2011-12-12
        • 1970-01-01
        • 2015-02-25
        • 2014-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-09
        • 1970-01-01
        相关资源
        最近更新 更多