如何根据日期从ArrayList中获取最新记录



我有下面的记录列表。我想根据日期获取最新的记录,并将其名称设置为"H"。以同样的方式,我想将"L"设置为所有剩余记录的名称。

List<Student> studentList = new ArrayList<>();
try {
studentList.add(new Student("A", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-1990")));
studentList.add(new Student("B", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2010")));
studentList.add(new Student("C", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2011")));
studentList.add(new Student("D", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2012")));
studentList.add(new Student("E", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2018")));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();  
}
Student student = Collections.max(studentList, Comparator.comparing(s -> s.getDate()));

我已经尝试过了,但在这里我只能为最新的记录设置名称,但我无法为所有其他记录设置名称。

如有任何帮助,我们将不胜感激。

单线程版本:

// Find the latest student in the list 
Student latest = Collections.max(studentList,
Comparator.comparing(s -> s.getDate()));
// Iterate the list, setting each student's name depending on whether it
// is the latest or not. 
studentList.forEach(s -> {s.setName(s == latest ? "H" : "L");});

上面的代码对列表进行了两次遍历。还有其他方法可以完成第二步;例如

studentList.forEach(s -> {s.setName("L");});
latest.setName("H");

如果集合为空,max调用将抛出NoSuchElementException。您可以将其视为错误(即,让异常传播(,也可以在开始之前测试空列表。


使用流的单程解决方案是可能的:

Optional<Student> latest = studentList.stream()
.peek(s -> {s.setName("L")})
.max(Comparator.comparing(s -> s.getDate());
latest.ifPresent(s -> {s.setName("H")});

我们将每个学生的名字设置为"L",并在一次通行证中找到最新的。然后,我们将最新学生的姓名重置为"H"

此版本也适用于空列表。(事实上,我们需要努力让它不起作用。Optional在某些情况下很有帮助。(

如果列表足够长,可能值得使用parallel()

如果您只有日期,请使用java-8 中的LocalDateDateTimeFormatter

studentList.add(new Student("A", LocalDate.parse("01-01-1990", DateTimeFormatter.ofPattern("dd-MM-yyyy")));

所以Student类将是

public class Student {
private String name;
private date LocalDate;
//getters and setters
}

现在使用Collections.max,因为LocalDate实现Comparable

Student student =  Collections.max(studentList, Comparator.comparing(s -> s.getDate()));

设置HL

第一种方法

我在这里建议的方法是首先为每个使用forEach的学生设置name = L

studentList.forEcah(stu->stu.setName("L"));

现在只需使用比较器获取最大学生数,并设置名称=H

Student student =  Collections.max(studentList, Comparator.comparing(s -> s.getDate()));
student.setName("H");

第二种方法

您可以对List第一个进行排序

studentList.sort(Comparator.comparing(s -> s.getDate()).reversed());

然后将第一条记录的名称设置为H,其余记录的名称为L

IntStream.range(0,studentList.size())
.forEach(i->{
if(i==0) {
studentList.get(i).setName("H");
}
else {
studentList.get(i).setName("L");
}
});

只需迭代列表并根据需要设置名称:

Student student = Collections.max(studentList, Comparator.comparing(Student::getDate));
studentList.forEach(s -> s.name = s.equals(student) ? "H" : "L");

最新更新