0

I have 2 classes and contains the below property languageMap

class Person {
    Map<String, String> languageMap;
}

class Employee {
    Map<String, String> languageMap;
}

There are two methods addressMap(List<Person> persons) and employeeMap(List<Employee> employee) it calls Function interface,

public Map<String, String addressMap(List<Person> persons){
        Function<Collection<Person>,
                Map<String, String>> personFunc = CommonUtils::buildPersonMap;

               return personFunc.apply(persons);
  }

public Map<String, String employeeMap(List<Employee> employee){
    Function<Collection<Employee>,
         Map<String, String>> addressFunc = CommonUtils::buildEmployeeMap;

         return addressFunc.apply(employee);
  }

private static Map<String, String> buildPersonMap(Collection<Person> personItem) {
    return personItem.stream()
            .filter(element -> element.getLanguageMap() != null)
            .flatMap(element -> element.getLanguageMap()
                    .entrySet()
                    .stream())
            .filter(map -> map.getKey() != null && map.getValue() != null)
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a));
}

private static Map<String, String> buildEmployeeMap(Collection<Employee> employeeItem) {
    return employeeItem.stream()
            .filter(element -> element.getLanguageMap() != null)
            .flatMap(element -> element.getLanguageMap()
                    .entrySet()
                    .stream())
            .filter(map -> map.getKey() != null && map.getValue() != null)
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a));
}

I wanted to make the 2 buildXXX() methods to be common, and tried to use Generics as below,

private static Map<String, String> buildMap(Collection<?> input) {

    return input.stream()
      .filter(element -> element.getLanguageMap() != null). // ERROR
      .flatMap(element -> element.getLanguageMap().entrySet().stream()) // ERROR
      .filter(map -> map.getKey() != null && map.getValue() != null)
      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a));
  }

any Generics or Stream technique to overcome the issue?

1 Answer 1

1

You can make the caller send in a getter for each type, and have your method implemented in this way:

private static <T> Map<String, String> buildMap(Collection<T> input,
        Function<T, Map<String, String>> languageMapGetter) {

    return input.stream()
            .map(languageMapGetter) //you can also call it yourself
            .filter(Objects::nonNull)
            .flatMap(element -> element.entrySet().stream())
            .filter(map -> map.getKey() != null && map.getValue() != null)
            .collect(Collectors.toMap(Map.Entry::getKey, 
                    Map.Entry::getValue, (a, b) -> a));
}

Which will make your type-specific methods look like this:

public Map<String, String> addressMap(List<Person> persons) {
    return CommonUtils.buildMap(persons, Person::getLanguageMap);
}

public Map<String, String> employeeMap(List<Employee> employee) {
    return CommonUtils.buildMap(employee, Employee::getLanguageMap);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.