UTC ISO-8601 date strings can be compared lexicographically. The most elegant Java 8 solution in my opinion would therefore be:
Person youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> p.dateOfBirth)).get();
If you don't trust the string comparison, or your timezones are all over the place, you can parse the date if you wish:
Person youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> LocalDateTime.parse(p.dateOfBirth, DateTimeFormatter.ISO_DATE_TIME)))
.get();
Or even:
Person youngest = listOfPersons.stream()
.max(Comparator.comparing(p -> Instant.parse(p.dateOfBirth))).get();
Note that you should probably use LocalDateTime
(or Instant
) rather than Date
, as Java 8 has moved away from the old date/time APIs (a good rundown here). You'll need to use the ISO_DATE_TIME
formatter to handle the Z
zone at the end if you're using LocalDateTime
.
Runnable example is here.
API of interest:
Stream
is Java 8's sort of ... iterable transformation interface supporting lots of handy methods and method chaining. All Collection
objects have a stream()
member for obtaining one.
Stream.max()
returns the maximum value in a stream according to some Comparator
that you specify (which could be a lambda function, or, as in the above case, just a Comparator
object).
- The return value is actually an
Optional<Person>
in this case (e.g. if the list was empty there might be no value), so get()
gets the value, or you could just leave it as an Optional
if you want, or you could use e.g. orElse(null)
instead of get()
if you'd rather it be null for an empty list.
Comparator.comparing()
is a handy little utility that constructs a Comparator<T>
given a function that maps a T
to a comparable value.
So in the above code:
p -> p.dateOfBirth
(or p -> LocalDateTime.parse(p.dateOfBirth)
, your call) is a lambda function which maps a person to their birthdate.
Comparator.comparing(...)
, when given said key mapping function, returns a Comparator
that compares the birth date of two persons, performing the appropriate comparison depending on whether you used the String
or the LocalDateTime
version.
max()
returns the object with the maximum date, i.e. the youngest person.
get()
just gets the Person
out of the Optional<Person>
.
Full example (linked to ideone above):
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));
}
}
Outputs:
helga 2000-06-23T03:07:26.084850Z
mortimer 1974-06-23T03:07:26.126628Z
gertrude 2016-06-23T03:07:26.126894Z
jebediah 1983-06-23T03:07:26.127948Z
youngest is: gertrude 2016-06-23T03:07:26.126894Z
youngest is: gertrude 2016-06-23T03:07:26.126894Z