在Java 8中,通过可选选项筛选ArrayList

在Java 8中,通过可选选项筛选ArrayList,java,lambda,java-8,Java,Lambda,Java 8,我在尝试使用Java8过滤和迭代一个可选文件时遇到了一个异常。我有一个对象主题,它被添加到数组列表中,值也为null 问题陈述:我有一个ArrayList,我想迭代它,过滤它,然后基于它,只打印满足条件的记录 package com.example.app; import java.util.ArrayList; import java.util.List; import java.util.Optional; public class Option

我在尝试使用Java8过滤和迭代一个可选文件时遇到了一个异常。我有一个对象主题,它被添加到数组列表中,值也为null

问题陈述:我有一个ArrayList,我想迭代它,过滤它,然后基于它,只打印满足条件的记录

    package com.example.app;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Optional;


    public class OptionalTest {

        public static void main(String[] args) {

           System.out.println("getSubject: " + getSubjects());
           // print the Subject with the name "Math"
            System.out.println("getSubject " + getSubjects().filter((Subject s) -> s.getName().equalsIgnoreCase("Math")));

        }


        private static Optional getSubjects() {

            Subject subject1 = new Subject(1, "Math", (short)2, "");
            Subject subject2 = new Subject(2, "Social Science", (short)4, "Social Science");
            Subject subject3 = new Subject(3, "English", (short)6, "Literature");

            List<Subject> subjects = new ArrayList<>();
            Optional<List<Subject>> optional = Optional.of(subjects);

            subjects.add(subject1);
            subjects.add(subject2);
            subjects.add(null); 
            subjects.add(subject3);

            return optional;
        }

    }

    class Subject {
        int id;
        String name;
        short type;
        String description;

        public Subject(int id, String name, short type, String description) {
            this.id = id;
            this.name = name;
            this.type = type;
            this.description = description;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public short getType() {
            return type;
        }

        public void setType(short type) {
            this.type = type;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        @Override
        public String toString() {
            return "\nSubject{" + "id=" + id + ", name=" + name + ", type=" + type + ", description=" + description + '}'+"\n";
        }


    }
package com.example.app;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Optional;
公共类选项测试{
公共静态void main(字符串[]args){
System.out.println(“getSubject:+getSubjects());
//打印名为“数学”的主题
System.out.println(“getSubject”+getSubjects().filter((Subject s)->s.getName().equalsIgnoreCase(“Math”));
}
私有静态可选getSubjects(){
科目1=新科目(1,“数学”,(简称)2“”;
学科2=新学科(2,“社会科学”,(简称)4,“社会科学”);
科目3=新科目(3,“英语”,简称)6,“文学”);
列表主题=新建ArrayList();
可选=可选的(受试者);
主题。添加(主题1);
主题。添加(主题2);
subjects.add(空);
主题。添加(主题3);
返回可选;
}
}
班级科目{
int-id;
字符串名;
短型;
字符串描述;
公共主题(int-id、字符串名称、短类型、字符串描述){
this.id=id;
this.name=名称;
this.type=type;
this.description=描述;
}
公共int getId(){
返回id;
}
公共无效集合id(内部id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共短getType(){
返回类型;
}
公共void集合类型(短类型){
this.type=type;
}
公共字符串getDescription(){
返回说明;
}
公共void集合描述(字符串描述){
this.description=描述;
}
@凌驾
公共字符串toString(){
返回“\n对象{”+“id=“+id+”,name=“+name+”,type=“+type+”,description=“+description+'}”+”\n”;
}
}

使用
可选。过滤器将用于根据您的代码片段筛选列表实例。这不是你想要的:

Optional.of(getSubjects()).filter(predicate) //filters lists, not subjects in lists
您的意图可能是使用
主题
对象列表,然后进行筛选。是
接口的
过滤器
方法返回一个
可选
实例:

我会改变这个方法:

private static List<Subject> getSubjects(){

    Subject subject1 = new Subject(1, "Math", (short)2, "");
    Subject subject2 = new Subject(2, "Social Science", (short)4, "Social Science");
    Subject subject3 = new Subject(3, "English", (short)6, "Literature");

    List<Subject> subjects = new ArrayList<>();

    subjects.add(subject1);
    subjects.add(subject2);
    subjects.add(null); 
    subjects.add(subject3);

    return subjects;
}
private静态列表getSubjects(){
科目1=新科目(1,“数学”,(简称)2“”;
学科2=新学科(2,“社会科学”,(简称)4,“社会科学”);
科目3=新科目(3,“英语”,简称)6,“文学”);
列表主题=新建ArrayList();
主题。添加(主题1);
主题。添加(主题2);
subjects.add(空);
主题。添加(主题3);
返回主题;
}
然后按如下方式使用:

Optional<Subject> filtered = getSubjects()
  .stream().filter(s -> s.getName().equalsIgnoreCase("Math"))
  //Find first is just one of the many Stream methods
  //returning an optional
  //It's correct to use it in this case because you know
  //only one value is expected to match the filter predicate.
  .findFirst();
Optional filtered=getSubjects()
.stream().filter(s->s.getName().equalsIgnoreCase(“数学”))
//findfirst只是众多流方法中的一种
//返回可选的
//在这种情况下使用它是正确的,因为你知道
//预期只有一个值与筛选器谓词匹配。
.findFirst();
事实上,如果你希望多个主题与你的过滤器匹配,你应该收集,而不是挑选一个。在这种情况下,您不需要可选的:

List<Subject> mathSubjects = getSubjects()
  .stream().filter((s -> s.getName().equalsIgnoreCase("Math")))
  .collect(Collectors.toList());
List mathSubjects=getSubjects()
.stream().filter((s->s.getName().equalsIgnoreCase(“数学”))
.collect(Collectors.toList());

您可以使用lambda表达式非常简单地完成此操作,我提供了一个示例,以便您可以根据需要进行修改

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class Java8Optional {

public static void main(String[] args) {

    List<Employee> employeeList = new ArrayList<>();

    employeeList.add(new Employee(1, "syed"));
    employeeList.add(new Employee(2, "az"));
    employeeList.add(null);
    employeeList.add(new Employee(4, "Rof"));

    employeeList.forEach(n -> Optional.ofNullable(n).ifPresent(e -> System.out.println("Employee ID="+e.employeeId+"\tEmployee Name="+e.employeeName)));

}

static class Employee {

    Integer employeeId;
    String employeeName;

    public Integer getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public Employee(Integer employeeId, String employeeName) {
        super();
        this.employeeId = employeeId;
        this.employeeName = employeeName;
    }
  }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.Optional;
公共类Java8Optional{
公共静态void main(字符串[]args){
List employeeList=新建ArrayList();
添加(新员工(1,“syed”);
添加(新员工(2,“az”);
employeeList.add(空);
新增(新员工(4名,“Rof”);
employeeList.forEach(n->可选的.ofNullable(n).ifPresent(e->System.out.println(“Employee ID=“+e.employeeId+”\tEmployee Name=“+e.employeeName));
}
静态类员工{
整数employeeId;
字符串employeeName;
公共整数getEmployeeId(){
返回员工ID;
}
public void setEmployeeId(整数employeeId){
this.employeeId=employeeId;
}
公共字符串getEmployeeName(){
返回员工姓名;
}
public void setEmployeeName(字符串employeeName){
this.employeeName=employeeName;
}
公共雇员(整数employeeId,字符串employeeName){
超级();
this.employeeId=employeeId;
this.employeeName=employeeName;
}
}
}

1。请提供。2.我看不出你试图解决这个问题。3.您不能迭代
可选
——它是一个值或null。4.你为什么想要
列表的
可选的
呢?同意,但是可选的可以有任何对象,我正在给它传递一个主题的数组列表。所以为了避免null异常,我尝试使用optional来设计API。因为当我们从数据库中获取数据时,它通常不是一条记录,可能会得到多条记录,或者可能是零。您想要一个
列表
?这将使更多的敏感话题成为研究的首要主题:@Eugene不太可能。OP正在交易一个
Nul