Reputation:
I have a File.txt (represent NewBorn
).
I've created a class NewBorn
that has the following fields: id
, name
, age
.
Then I'm reading the file and parsing it, so I can get a nice output.
From the list of newborn (based on file.txt) I need to get the date on which the most children were born, but I have a problem filtering through that.
That's what I've tried :
public static List<NewBorn> dateInWitchMostChildrenAreBorn(List<NewBorn> newBornList) {
return newBornList.stream()
.filter(newBorn -> newBorn.getBirthdate() // in here I tried to go use = but is not good of course )
//then I want to collect that and count the one that is the most in witch children are born
.collect((Collectors.toSet()));
}
Upvotes: 2
Views: 115
Reputation:
You can also use this First List should not be there since you want to return a LocalDate If your relation between classes is correct this should be working : Any question please let me know :)
public LocalDate mostCommonDate() {
Map<LocalDate, Integer> map = new HashMap<>();
for (Newborn newborn : newborns) {
Integer value = map.get(newborn.getBirthday());
map.put(newborn.getBirthday(), (value == null) ? 1 : value + 1);
}
Entry<LocalDate, Integer> max = null;
for (Entry<LocalDate, Integer> entry : map.entrySet()) {
if (max == null || max.getValue() > entry.getValue()) {
max = entry;
}
}
return max.getKey();
}
Upvotes: 0
Reputation: 28968
There could be multiple dates for which the numbers of children have been born are equal. Therefore, there can be more than one date that corresponds to the maximum number of newborns. Maybe that's why the method listed in the question is meant to return a list.
In order to obtain the List<LocalDate>
containing all dates when number of newborns is maximal, first, we need to create map Map<LocalDate, Long>
(number of newborns by date) by using collector Collectors.groupingBy()
. The function that extracts the birthdate is used as the first argument and Collectors.counting()
, that generates the number of elements mapped to a key, as a downstream collector.
Then we can generate the resulting list in a single pass over the entries of this map with a custom collector that will collect the entries having the highest previously encountered count. If the next entry has a value greater the previous maximum, intermediate results will be cleaned up.
To implement a custom collector, we can utilize the static method of()
defined in the Collector
interface.
ArrayDeque
is used as mutable container of the collector.
The finisher function creates a stream over the resulting queue, which extracts date objects from the entries and collect them into a list.
public static List<LocalDate> dateInWitchMostChildrenAreBorn(List<NewBorn> newBornList) {
return newBornList.stream()
.collect(Collectors.groupingBy(NewBorn::getBirthdate,
Collectors.counting())) // Map<LocalDate, Long> - number of newborns by date
.entrySet().stream()
.collect(Collector.of(
ArrayDeque::new, // supplier
(Queue<Map.Entry<LocalDate, Long>> queue,
Map.Entry<LocalDate, Long> next) -> { // accumulator
if (!queue.isEmpty() && queue.element().getValue() < next.getValue()) queue.clear();
if (queue.isEmpty() || queue.element().getValue().equals(next.getValue())) queue.add(next);
},
(Queue<Map.Entry<LocalDate, Long>> left,
Queue<Map.Entry<LocalDate, Long>> right) -> { // combiner
if (left.isEmpty()) return right;
if (right.isEmpty()) return left;
if (left.element().getValue() < right.element().getValue()) return right;
if (left.element().getValue() > right.element().getValue()) return left;
else {left.addAll(right); return left;}
},
(Queue<Map.Entry<LocalDate, Long>> queue) -> // finisher
queue.stream().map(Map.Entry::getKey).toList()
));
}
main()
- demo
public static void main(String[] args) {
List<NewBorn> newBorns =
List.of(new NewBorn(LocalDate.of(2021, 1, 5)),
new NewBorn(LocalDate.of(2021, 3, 8)),
new NewBorn(LocalDate.of(2021, 3, 8)),
new NewBorn(LocalDate.of(2021, 12, 10)),
new NewBorn(LocalDate.of(2021, 12, 10)),
new NewBorn(LocalDate.of(2021, 1, 5)),
new NewBorn(LocalDate.of(2021, 5, 25)),
new NewBorn(LocalDate.of(2021, 7, 12)));
System.out.println(dateInWitchMostChildrenAreBorn(newBorns));
}
Output (expected : three dates on which the number of newborns is 2
)
[2021-12-10, 2021-03-08, 2021-01-05]
Upvotes: 0
Reputation: 1057
Here, First filtering the null birthdate
, then grouping it by birthdate then collecting it to a Map with birthdate
as key and occurrence as value, then returning the max occurrence birthdate
public static LocalDate dateInWitchMostChildrenAreBorn(List<NewBorn> newBornList) {
return newBornList.stream()
.filter(newBorn -> Objects.nonNull(newBorn.getBirthdate()))
.collect(Collectors.groupingBy(NewBorn::getBirthdate, Collectors.counting()))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey).orElse(null);
}
Upvotes: 1