Van*_*vic 1 java datetime java-stream
class Person {
String name;
String id;
String dateOfBirth;
int salary;
}
List <Person> listOfPersons; // Consider that list is filled with some data
Run Code Online (Sandbox Code Playgroud)
例如dateOfBirth = "2018-12-10T13:49:51.141Z";
出生日期采用 ISO8601 格式,
如果可以帮助对列表进行排序,则可以将其转换为java.util.Date
with 。Date.from(Instant.parse(dateOfBirth));
那么,有什么方法可以使用 JAVA 8 中的流或不错的解决方案来从人员列表中获取最年轻的人员吗?
附加注释:Person 类不能更改。
小智 5
你可以这样做
Person youngestPerson = listOfPersons.stream()
.reduce((p1, p2) -> LocalDateTime.parse(p1.getStringDateofBirth()).isAfter(LocalDateTime.parse(p2.getStringDateofBirth()))?p1:p2)
.orElse(null)
Run Code Online (Sandbox Code Playgroud)
UTC ISO-8601 日期字符串可以按字典顺序进行比较。因此,我认为最优雅的 Java 8 解决方案是:
Person youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> p.dateOfBirth)).get();
Run Code Online (Sandbox Code Playgroud)
如果您不信任字符串比较,或者您的时区到处都是,您可以根据需要解析日期:
Person youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> LocalDateTime.parse(p.dateOfBirth, DateTimeFormatter.ISO_DATE_TIME)))
.get();
Run Code Online (Sandbox Code Playgroud)
甚至:
Person youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> Instant.parse(p.dateOfBirth))).get();
Run Code Online (Sandbox Code Playgroud)
请注意,您可能应该使用LocalDateTime(或Instant) 而不是Date,因为 Java 8 已经放弃了旧的日期/时间 API(这里有一个很好的概述)。如果您使用的是,则需要使用ISO_DATE_TIME格式化程序来处理Z末尾的区域LocalDateTime。
感兴趣的API:
Stream是 Java 8 的...可迭代转换接口,支持许多方便的方法和方法链接。所有Collection对象都有stream()一个用于获取对象的成员。Stream.max()根据您指定的值返回流中的最大值Comparator(可以是 lambda 函数,或者如上例所示,只是一个Comparator对象)。
Optional<Person>(例如,如果列表为空,则可能没有值),因此get()获取该值,或者如果您愿意,您可以将其保留为 an Optional,或者您可以使用 egorElse(null)代替get()if you' d 宁愿它是 null 对于空列表。Comparator.comparing()是一个方便的小实用程序,它构造Comparator<T>给定的函数,将 a 映射T到可比较的值。所以在上面的代码中:
p -> p.dateOfBirth(或者p -> LocalDateTime.parse(p.dateOfBirth),您的调用)是一个 lambda 函数,它将一个人映射到他们的出生日期。Comparator.comparing(...),当给定所述键映射函数时,返回一个Comparator比较两个人的出生日期的值,根据您是否使用String或LocalDateTime版本执行适当的比较。max()返回日期最大的对象,即最小的人。get()只是得到了Person出来Optional<Person>。完整示例(链接到上面的 ideone):
import java.util.*;
import java.lang.*;
import java.io.*;
import java.time.*;
import java.time.format.*;
class Ideone {
public static void main (String[] args) throws java.lang.Exception {
Person youngest;
// you could do string comparison if you know the timezones are consistent:
youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> p.dateOfBirth)).get();
System.out.println("youngest is: " + youngest.name + " " + youngest.dateOfBirth);
// or you could just parse the date, a safer option:
youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> LocalDateTime.parse(p.dateOfBirth, DateTimeFormatter.ISO_DATE_TIME))).get();
System.out.println("youngest is: " + youngest.name + " " + youngest.dateOfBirth);
}
//------------------------------------
// types from OP:
static class Person{
String name;
String id;
String dateOfBirth;
int salary;
}
static List <Person> listOfPersons;
//------------------------------------
// boring example data initialization:
// make an iso birthdate string given an age (for initializing data)
static String fromAge (int years) {
//return LocalDateTime.now().minusYears(years).toString();
// add zone to emulate OP's input:
return LocalDateTime.now().minusYears(years).toString() + 'Z';
}
// make up some data
static {
listOfPersons = List.of(
// fine for example, but i wouldn't init like this in production
new Person() {{ name="helga"; dateOfBirth=fromAge(22); }},
new Person() {{ name="mortimer"; dateOfBirth=fromAge(48); }},
new Person() {{ name="gertrude"; dateOfBirth=fromAge(6); }},
new Person() {{ name="jebediah"; dateOfBirth=fromAge(39); }}
);
listOfPersons.forEach(p -> System.out.println(p.name + ' ' + p.dateOfBirth));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Person youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> p.dateOfBirth)).get();
Run Code Online (Sandbox Code Playgroud)