Use the Power of Objects
The usage of maps in your code is an example of abuse of collections. Storing the data in such a way is inconvenient and error-prone.
Instead of trying to substitute a domain object with a Map, you need to define a class (or a record).
It'll give you many advantages that you're depriving yourself by using maps:
- Ability to use the proper type for every property instead of keeping everything as strings;
- No need to perform parsing;
- Self-explanatory method names instead of hard-coded string keys, and your code will not fail because you've misspelled a key;
- The code is easier to read and maintain.
For the sake of simplicity and conciseness, I'll go with a Java 16 record:
public record Person(String name, int age) {}
And now we have two lists of Person instead of two lists of maps.
To implement the logic when we're starting with examining the first list and only if a result was not found we proceed by iterating through the second list, we can make use of the Java 9 method or() defined by Optional. While invoked on the optional object containing a value, or() returns the same optional, otherwise it'll return an optional produced by a supplier provided as an argument.
For convenience, we can define a method that takes a List<Person> and the target age and returns an optional result.
public static Optional<Person> getPersonByAge(List<Person> people, int age) {
return people.stream().filter(pers -> pers.age() == age).findFirst();
}
We can make this method reusable by making it generic. So it would expect a List<T> and a Predicate<T> as its arguments.
public static <T> Optional<T> getPersonByAge(List<T> people,
Predicate<T> predicate) {
return people.stream().filter(predicate).findFirst();
}
And that how we can apply it:
List<Person> list1 = List.of(new Person("john", 30), new Person("marry", 31));
List<Person> list2 = List.of(new Person("mike", 40), new Person("terry", 41));
Predicate<Person> age40 = pers -> pers.age() == 40;
String name = getPersonByAge(list1, age40)
.or(() -> getPersonByAge(list2, age40))
.orElseThrow()
.name();
System.out.println(name);
Output:
mike
A link to Online Demo