I have 2 methods for getting average age of woman, and second for getting average age of man. I need to do one method to agregate this 2 methods.
This method as first parameter should have list of person, and as a second parameter function what will decide if we are looking for man or woman average age.
This is my methods:
public double getMenAverageAge(List<Person> personList){
return Optional.ofNullable(personList)
.orElseGet(ArrayList::new)
.stream()
.filter(Objects::nonNull)
.filter(p -> !Boolean.parseBoolean(String.valueOf(p.getFirstName().endsWith("a"))))
.mapToDouble(Person::getAge)
.average()
.orElse(0);
}
public double getAverageWomenAge(List<Person> personList){
return Optional.ofNullable(personList)
.orElseGet(ArrayList::new)
.stream()
.filter(Objects::nonNull)
.filter(p-> Boolean.parseBoolean(String.valueOf(p.getFirstName().endsWith("a"))))
.mapToDouble(Person::getAge)
.average()
.orElse(0);
}
Any ideas?
CodePudding user response:
Predicate<Person> p = p-> Boolean.parseBoolean(String.valueOf(p.getFirstName().endsWith("a")));
That's what's happening under the hood there. That's just a type and you can make a method that accepts that type as param:
public double getAverageAge(List<Person> list, Predicate<Person> filter) {
return list
.stream()
.filter(filter)
.mapToDouble(Person::getAge)
.average()
.orElse(0);
NB: You have null tourette, it's a formula for writing lots of code that is impossible to test. Don't do it. Love the NPE. The correct response to someone invoking this method passing in null
for a list is to crash with an NPE: null is best treated as 'unset' / 'unknown', and it is not possible to get the average age of an unknown list. The answer is not 0. The answer is ¯\(ツ)/¯.
Similarly, if somehow a null
got into your list of persons, then the age of that person is also unknown. It is not possible to determine the average age of a batch of persons when one of the persons in there is a complete unknown, again, just NPEing is in fact the right response.
The best way to deal with null in java is to use the tools to your advantage: If the NullPointerException is in fact the best thing that could happen, you're doing it right.
CodePudding user response:
Functions, like variables and constants, have a type. Functions take parameters using two parenthesis () and have a return type Void, Int, Bool, etc. A function that takes no parameters and returns nothing would have a type of: () -> Void
A function that takes two Int parameters and returns a String would have a type of: (Int, Int) -> String
So, if you wanted to to create a parameter that takes a function input, it would look something like this:
//We have a function named example that has a parameter
//that requires a function that takes in two parameters of type Int and returns a bool
//Example calls the function that is passed in by provided two Int parameters
func example(function: (Int, Int) -> Bool) {
let output = function(3, 3)
print(output)
}
Now, we have a function that takes in two inputs of type Int and returns a Bool
func areEqual(num1: Int, num2: Int) -> Bool {
return num1 == num2
}
//We can pass in areEqual to example as a parameter because it meets the
//same type as the function parameter of example
function example(areEqual(num1:num2:))
//The function example will print true