如何在java中过滤对象的列表变量?

时间:2018-04-30 13:42:14

标签: java java-stream

我有一个对象Student

public class Student {
   String name;
   String[] classes;

    public Student(String name, String[] classes){
        this.name = name;
        this.classes = classes;
    }

   //getter & setter
}

我想过滤这些课程。例如,我有

Student sa = new Student("John", "math, physics")
Student sb = new Student("Jack", "math, english")
Student sc = new Student("Maria", "math, chemistry")

那么我如何获得Student math可变?我是否需要编写新谓词或是否存在现有方法?谢谢。

3 个答案:

答案 0 :(得分:1)

您可以使用seaparate find方法在数组中查找类:

List<Student> mathStudents = studentList.stream()
                  .filter(student -> findClass(student.getClasses(), "math"))
                  .collect(Collectors.toList());

二进制搜索需要排序,但在搜索之前最好完成排序,最好是Student的构造函数,suggested by AlexH

private static boolean findClass(String[] classes, String search) {

    Arrays.sort(classes); 
    return 0 <= Arrays.binarySearch(classes, search);
}

答案 1 :(得分:1)

您的代码存在很多问题。

首先:如果您的构造函数需要String[]参数,则必须提供String[]而不是String。这样称呼:

Student sa = new Student("John", new String[]{"math", "physics"});
Student sb = new Student("Jack", new String[]{"math", "english"});
Student sc = new Student("Maria", new String[]{"math", "chemistry"});

应该将您的字段设为私有并使用getter,而不是将其打包为私有。您可以阅读有关可见性here

的信息

现在,您有三个Student个目标。你不能像这样最简单的方式将它们放入Stream:

Arrays.stream(new Student[]{sa, sb, sc})

您现在可以使用以下内容过滤流:

Arrays.stream(new Student[]{sa, sb, sc})
    .filter(s -> {
        for(String className : s.classes) {
            if(className.equals("math")) return true;
        }
        return false;
    })

这将为您提供所有在math字段中具有班级classes的学生的流。您现在可以收集元素或使用它进行更多的工作。

答案 2 :(得分:1)

假设您有一个List<Student>填充了正确的数据,您可以像这样完成手头的任务:

List<Student> result = 
     students.stream()
             .filter(student -> Arrays.stream(student.getClasses())
                                      .anyMatch("math"::equals))
             .collect(Collectors.toList());

这会从学生列表中创建一个流,并对其进行过滤,以仅保留具有&#34;数学&#34;类。