【问题标题】:Java - Search for a specific property whilst iterating through a list of objects [duplicate]Java - 在遍历对象列表时搜索特定属性[重复]
【发布时间】:2019-03-22 16:59:55
【问题描述】:

我正在努力寻找相关的答案来解决我的问题。我有一个数组列表:

List<Teacher> teacherList = new ArrayList<Teacher>(11);

教师类有一个名称属性。我想浏览一下老师列表,看看有没有名字和用户输入的名字相匹配。

例如,

Scanner teacherNameScanner = new Scanner (System.in);
System.out.println("What is the teachers name");
teacherName = teacherNameScanner.nextLine();

/* Here I want to scan through the teacherList and see whether the name entered
matches the name of any of the teachers. If it does not match I want to tell the
user to enter a correct name */

【问题讨论】:

    标签: java list arraylist


    【解决方案1】:

    这真的取决于您的用例,名称是否区分大小写?此外,您可能需要考虑修剪空格。然后创建一个 Set nameSet,您可以在其中获取现有名称,这是一个 O(1) 操作。同样有很多解决方案,除非您描述确切的用例,例如您是否想用姓名或 id(通常是 id)来识别教师,否则很难想出正确的解决方案。但是按照你描述的 HashSet 应该做的。

    Set<String> nameSet = new HashSet<String>();
    
    if (nameSet.contains(teacherName))
       do what you want
    else
       other case
    

    【讨论】:

    • 不错,还没考虑过套装。如果您只想遍历一次,最好迭代并检查,也就是说,如果您重复执行,这会杀死迭代。
    • 需要填充它,new HashSet&lt;Teacher&gt;(teacherList) 或类似的东西。
    • 是的,我只是想给出伪代码和想法。
    【解决方案2】:

    Java8 中,您可以使用流:

    public static Teacher findByName(Collection<Teacher> teachers, String name) {
        return teachers.stream().filter(teacher -> teacher.getName().equals(name)).findFirst().orElse(null);
    }
    

    另外,如果您有许多不同的对象(不仅是Teacher)或者您想通过不同的属性(不仅是name)找到它,您可以构建一个实用程序类,将这个逻辑封装在其中:

    public final class FindUtils {
        public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
            return col.stream().filter(filter).findFirst().orElse(null);
        }
    }
    
    public final class TeacherUtils {
        public static Teacher findByName(Collection<Teacher> teachers, String name) {
            return FindUtils.findByProperty(teachers, teacher -> teacher.getName().equals(name));
        }
    
        public static Teacher findByAge(Collection<Teacher> teachers, int age) {
            return FindUtils.findByProperty(teachers, teacher -> teacher.getAge() == age);
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      扫描teacherList并查找输入的教师姓名(teacherName)是否匹配,可以使用以下方法之一。请注意,每个方法都将 teacherListenteredName 作为参数并返回 boolean true 或 false - 取决于是否找到匹配项。

      共有三种方法,每种方法的执行方式不同。请注意第三个构造 C - 它使用与前两个不同的方法 - A 和 B。


      方法一:

      使用 for 循环迭代 teacherList 并查找是否有名称匹配的老师:

      for (Teacher teacher : teacherList) {
          if (teacher.getName().equals(enteredName)) {
              // a match is found
              return true;
          }
      }
      
      return false;
      


      方法B:

      这与方法 A 具有相同的功能,但使用不同的代码构造 - 流和 lambda:

      boolean enteredTeacherExists =  teacherList.stream()
                                                 .anyMatch(teacher -> teacher.getName().equals(enteredName));
      

      语法teacher -&gt; teacher.getName().equals(enteredName)Predicate&lt;Teacher&gt; 类型的lambda 表达式。


      方法C:

      此方法使用不同的方法。代替测试教师的姓名 - 使用输入的姓名构造教师对象,并且该对象用于查找匹配项。

      根据输入的名字创建一个教师并测试它是否存在于列表中。

      Teacher enteredTeacher = new Teacher(enteredName);
      boolean enteredTeacherExists = teacherList.contains(enteredTeacher);
      

      如果列表中存在同名教师,则返回值为真,否则为假。

      注意Teacher 类(参见下面的定义)有一个java.lang.Object 类的覆盖equals() 方法。此方法指定两个教师对象相等的标准 - 如果它们的名称相同,则认为教师对象相等。这允许使用等于Listcontains 方法。


      守则:

      Teacher.java:

      public class Teacher {
      
          private String name;
      
          public Teacher(String name) {
              this.name = name;
          }
      
          public String getName() {
              return name;
          }
      
          @Override
          /* This returns a string representation of the teacher - the name. */
          public String toString() {
              return name;
          }
      
          @Override
          public boolean equals(Object other) {
              if ((other != null) && (other instanceof Teacher)) {
                  Teacher otherTeacher = (Teacher) other;
                  if (otherTeacher.getName().equals(this.name)) {
                      return true;
                  }
              }
              return false;
          }
      }
      


      TeacherTester.java

      public class TeacherTester {
      
          public static void main(String [] args) {
      
              // Create some teachers
              Teacher teacher1 = new Teacher("first");
              Teacher teacher2 = new Teacher("second");
              Teacher teacher3 = new Teacher("third");
              List<Teacher> teacherList = Arrays.asList(teacher1, teacher2, teacher3);
      
              System.out.println("Teachers: " + teacherList);
      
              // Look for teacher - using method A
              String enteredName = "ninth";
              System.out.println("A. Found " + enteredName + " : " + findTeacherA(teacherList, enteredName));
              enteredName = "first";
              System.out.println("A. Found " + enteredName + " : " + findTeacherA(teacherList, enteredName));
      
              // Look for teacher - using method B
              enteredName = "ninth";
              System.out.println("B. Found " + enteredName + " : " + findTeacherB(teacherList, enteredName));
              enteredName = "second";
              System.out.println("B. Found " + enteredName + " : " + findTeacherB(teacherList, enteredName));
      
              // Look for teacher - using method C
              enteredName = "third";
              System.out.println("C. Found " + enteredName + " : " + findTeacherC(teacherList, enteredName));
              enteredName = "ninth";
              System.out.println("C. Found " + enteredName + " : " + findTeacherC(teacherList, enteredName));     
      
          }
      
          private static boolean findTeacherA(List<Teacher> teacherList, String enteredName) {
      
              for (Teacher teacher : teacherList) {
      
                  if (teacher.getName().equals(enteredName)) {
                      // a match is found
                      return true;
                  }
              }
      
              return false;
          }
      
          private static boolean findTeacherB(List<Teacher> teacherList, String enteredName) {
      
              return teacherList.stream()
                                  .anyMatch(teacher -> teacher.getName().equals(enteredName));
          }
      
          private static boolean findTeacherC(List<Teacher> teacherList, String enteredName) {
      
              Teacher enteredTeacher = new Teacher(enteredName);
              return teacherList.contains(enteredTeacher);
          }
      }
      


      输出:

      Teachers: [first, second, third]
      A. Found ninth : false
      A. Found first : true
      B. Found ninth : false
      B. Found second : true
      C. Found third : true
      C. Found ninth : false
      

      【讨论】:

        【解决方案4】:

        如果您使用的是 Java 8 或更高版本,您可以使用:

        teacherList.stream().anyMatch(teacher -> teacher.getName().equals(name));
        

        其中 name 是您要搜索的名称。

        【讨论】:

          【解决方案5】:

          for each 正是医生订购的(除非您有一些花哨的订购,您可以使用它进行更有效的搜索)。

          private Teacher findTheTeacher(ArrayList<Teacher> teacherList, String teacherName) {
          
              for (Teacher teacher : teacherList) {
                  if (teacher.name.equals(teacherName)) {
                      return teacher;
                  }
              }
              return null; // or something like this
          }
          

          【讨论】:

            猜你喜欢
            • 2016-05-12
            • 1970-01-01
            • 2015-08-28
            • 2014-09-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-10
            • 2011-12-10
            相关资源
            最近更新 更多