按特定条件查找列表中的对象



我有一个列表,必须找到特定的对象。我必须按学生平均值对列表进行排序标记值,并创建函数搜索值第二高的学生。如果它与其他学生重复,则函数将返回较年轻的学生。这个任务的另一个要求(要妥善解决(是我不能创建任何对象。下面我留下了我正在使用的类的代码:

import java.time.LocalDate;
import java.util.Comparator;
import java.util.List;
public class Student implements Comparator<Student>{
private String firstName;
private String lastName;
private LocalDate dateOfBirth;
private double averageMark;
public double getAverageMark() {
return averageMark;
}

//function below must find student that I described upper. Currently 
//function is incomplete because I still try to find correct solution 
public static Student findSecondBestStudent(List<Student> students) {

return students.stream().sorted(Comparator.reverseOrder());
}
@Override
public int compare(Student o1, Student o2) {
return (int) (o1.getAverageMark() - o2.getAverageMark());
}
}

目前,我确实试图通过对流进行反向排序来解决这个问题,然后删除流的第一个值,比较流的下两个对象并返回正确的对象。我可以使用for循环来解决它,但这个解决方案与任务(创建对象的要求(的条件不匹配

实现Comparable而不是Comparator

使您的compareTo函数按所需顺序(反向(对学生进行排序

stream进行排序,跳过1个条目,返回下一个条目。

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class Student implements Comparable<Student> {
private String firstName;
private String lastName;
private LocalDate dateOfBirth;
private double averageMark;

public Student(String firstName, String lastName, LocalDate dateOfBirth, double averageMark) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
this.averageMark = averageMark;
}
public double getAverageMark() {
return averageMark;
}
//function below must find student that I described upper. Currently 
//function is incomplete because I still try to find correct solution 
public static Student findSecondBestStudent(List<Student> students) {
return students.stream().sorted().skip(1).findFirst().orElse(null);
}
@Override
public int compareTo(Student other) {
if (other == null)
return 1;
if (other.averageMark == averageMark) {
if (other.dateOfBirth == null)
return -1;
return other.dateOfBirth.compareTo(dateOfBirth);
}
return Double.compare(other.averageMark, averageMark);
}
@Override
public String toString() {
return "Student [firstName=" + firstName + ", lastName=" + lastName + ", dateOfBirth=" + dateOfBirth
+ ", averageMark=" + averageMark + "]";
}

public static void main(String[] args) {
final List<Student> students = new ArrayList<>(6);
students.add(new Student("Peter", "Tibbitts", LocalDate.of(2001, 4, 6), 5));
students.add(new Student("Leon", "Gaston", LocalDate.of(1951, 6, 17), 12));
students.add(new Student("Eric", "Carter", LocalDate.of(1945, 12, 24), 9));
students.add(new Student("Richard", "Heard", LocalDate.of(1984, 5, 9), 4));
students.add(new Student("Frankie", "Bonner", LocalDate.of(1970, 4, 19), 10));
students.add(new Student("Donald", "Pascal", LocalDate.of(2000, 3, 26), 10));

final Student result = Student.findSecondBestStudent(students);
System.out.println(result);
}

}

您应该能够通过提供一个自定义比较器来实现这一点,该比较器首先比较averageMarks,然后比较dateOfBirth(如果发现相等(:

public static Student findSecondBestStudent(List<Student> students) {
return students.stream().sorted((o1, o2) -> {
int marksCompareResult = Double.compare(o2.getAverageMark(), o1.getAverageMark());
return marksCompareResult == 0 ?
o1.getDateOfBirth().compareTo(o2.getDateOfBirth()) :
marksCompareResult;
}).collect(Collectors.toList()).get(1);
}

我用以下代码测试了它:

List<Student> students = new ArrayList<>();
students.add(new Student("Rupert", "Brik", LocalDate.of(1994, 12, 30), 51.1));
students.add(new Student("Marc", "Felix", LocalDate.of(1995, 6, 30), 59.1));
students.add(new Student("Max", "Peters", LocalDate.of(1997, 8, 21), 69.1));
students.add(new Student("Mike", "Ermentraut", LocalDate.of(1998, 9, 21), 76.1));
students.add(new Student("Bartosz", "Mazack", LocalDate.of(1999, 10, 12), 76.1));

Student secondBest = Student.findSecondBestStudent(students);
System.out.printf("%s %s %f ", secondBest.firstName, secondBest.lastName, secondBest.averageMark);

它打印:

Bartosz Mazack 76.100000 

我不会在Student类中以这种方式实现Comparator<Student>Comparable<Student>,因为我不一定希望学生总是以这种方式进行比较。但我想这也取决于你的用例。

你可以做:

public static Student findSecondBestStudent(List<Student> students) {
return students.stream()
.sorted(Comparator.comparingDouble((Student o) -> o.averageMark)
.thenComparing(o -> o.dateOfBirth).reversed())
.skip(1)
.findFirst()
.get();
}

输入:

List<Student> students = Arrays.asList(
new Student("John", "Wall", LocalDate.of(2005, 1,1), 87),
new Student("Russel", "Westbrook",  LocalDate.of(2001, 1,1), 88),
new Student("Micheal", "Jordan",  LocalDate.of(2002, 1,1), 80),
new Student("Kevin", "Durant",  LocalDate.of(2001, 1,1), 87),
new Student("Carmelo", "Anthony",  LocalDate.of(2004, 1,1), 80)
);

输出:

Student(firstName=John, lastName=Wall, dateOfBirth=2005-01-01, averageMark=87.0)

最新更新