我们可以在以下情况下使用Java流吗?

时间:2020-03-17 08:02:56

标签: java java-8 java-stream

我有一个说Student的类,该类的字段marks的类型为Double。我正在创建list个Student对象。每个学生对象可以将marks字段设置为null或在不同的学生对象中设置相同的值。我有一个问题,我想根据以下条件从此list返回单个学生对象:

  1. 当所有学生的marks都相同时,返回null。
  2. 最高marks
  3. 其他回国学生。

我想知道是否有使用Java流api的更好方法来完成它。预先谢谢你。

学生班:

public class Student {
    private Double marks;

    public Double getMarks() {
        return marks;
    }

    public void setMarks(Double marks) {
        this.marks = marks;
    }

    @Override
    public String toString() {
        return "Student [marks=" + marks + "]";
    }

    public Student(Double marks) {
        super();
        this.marks = marks;
    }
}

4 个答案:

答案 0 :(得分:4)

使用Stream,您可以在收集到TreeMap并验证lastEntry的同时进行以下操作:

private Student highestMarkUniqueStudent(List<Student> studentList) {
    if(studentList.size() == 0) return null;
    if(studentList.size() == 1) return studentList.get(0);
    TreeMap<Integer, List<Student>> map = new TreeMap<>(studentList.stream()
            .collect(Collectors.groupingBy(Student::getMarks)));

    List<Student> highestMarkStudents = map.lastEntry().getValue();
    // only one highest or all same marks or more than one with highest mark
    return highestMarkStudents.size() == 1 ? highestMarkStudents.get(0) : null; 
}

答案 1 :(得分:1)

您可以这样做:

实际上,通过使用 TreeMap ,您在第一项中的得分最高。因此,通过检查其值,您可以返回期望的结果。如果所有分数均具有相同的值,则第一个条目的价值必须大于一个;如果您有两个或多个最高分数,则列表中的第一个条目仍具有多个学生对象。

TreeMap<Integer, List<Student>> map = list.stream()
            .collect(Collectors.groupingBy(
                    Student::getMarks,
                    () -> new TreeMap<Integer, List<Student>>(Comparator.reverseOrder()),
                    Collectors.mapping(Function.identity(), Collectors.toList())));

Map.Entry<Integer, List<Student>> firstEntry = map.firstEntry();   
if (firstEntry.getValue().size() <= 1) {
     result = firstEntry.getValue().get(0);
}

答案 2 :(得分:0)

您可能不需要流。排序列表中最高分数的首位,如果前2个相同,则返回null,否则返回第一个学生。

students.sort(Comparator.comparing(Student::getMarks).reversed());
boolean firstTwoHaveSameMarks = students.get(0).getMarks().equals(students.get(1).getMarks());
return firstTwoHaveSameMarks ? null : students.get(0);

如果2个或更多学生的最高分数相同,则返回null,否则返回该学生。

答案 3 :(得分:0)

您可以使用流,但需要一个能够收集数据的帮助对象。

现在可以通过还原或集合来完成工作。

减少后,您会做

students.stream().reduce(
       new Helper(),
       (helper, student) -> new Helper(helper, student));

class Helper {
    private Student bestStudent = null;
    private boolean different = false;
    public Helper() {
    }
    public Helper(Helper oldHelper, Student newStudent) {
        if (oldHelper.bestStudent == null) {
            bestStudent = newStudent;
        } else if (student.getMark() > oldHelper.bestStudent.getMark()) {
            different = true;
            bestStudent = student;
        } else if (student.getMark() < oldHelper.bestStudent.getMark()) {
            different = true;
        }
    }
    public Student getResult() {
        return different ? bestStudent : null;
    }
}

但这会为每个学生创建一个新的Helper对象。

有了收藏,我们会做

students.stream().collect(Helper::new, Helper::accept, Helper::combine);

class Helper {
    private Student bestStudent = null;
    private boolean different = false;
    public Helper() {
    }
    public void accept(Student newStudent) {
        if (bestStudent == null) {
            bestStudent = newStudent;
        } else if (newStudent.getMark() > bestStudent.getMark()) {
            different = true;
            bestStudent = newStudent;
        } else if (newStudent.getMark() < bestStudent.getMark()) {
            different = true;
        }
    }
    public void combine() (Helper other) {
        if (bestStudent == null) {
            bestStudent = other.bestStudent;
            different = other.different;
        } else if (other.bestStudent != null && other.bestStudent.getMark() > bestStudent.getMark()) {
            different = true;
            bestStudent = other.bestStudent;
        } else if (other.bestStudent != null && other.bestStudent.getMark() < bestStudent.getMark()) {
            different = true;
        }
    }
    public Student getResult() {
        return different ? bestStudent : null;
    }
}

(注意:1.未经测试的代码,2.部分基本逻辑取自another answer。)