Search code examples
javaapache-commonsmultimapmultivalue

Apache Common MultiValueMap iteration


I have a MultiMap suppose Company which has String as a Key and another MultiMap suppose Employee as a Value. Employee Multimap has String as a key and another multimap as a value. My question is how do I retrieve and iterate multimap stored inside multimap? I am using Apache common MultiMap.

Example: compMap has 2 companies. CompA and CompB each company has 10 employee.(Employee can appear more than once hence using multimap )

Coll contains employee multimap from compA however how do I retrieve particular employee(if he appears 4 time) from employee multimap?

Code:

if (!compMap.isEmpty()){
    Set compSet = compMap.keySet( );
    Iterator compIterator = compSet.iterator();
    while( compIterator.hasNext( ) ) {
        comp= compIterator.next().toString();                                   
        Collection coll = (Collection) compMap.get(comp);
        .....  
}

Solution

  • The problem you are facing is caused because one employee should not appear two times in one collection. If you store two values under the same key in MultiValueMap than theses are different values (although they are accessible by the same key).

    You should migrate your data model to more Object-Oriented model and not use key-store container located inside another key-store container (map inside map).

    Consider following model using only Set/List. Values are differentiated basing on equals/hashcode. If you use List you can have many Employees inside company (they can have the same name if you really need it). Why do you complicate it using MultiValueMap ?

    public class AbcTest {
      public static void main(String[] args) {
    
        Address address1 = new Address("street1");
        Address address2 = new Address("street2");
    
        Employee employee1 = new Employee("employee1");
        employee1.getAddresses().add(address1);
        employee1.getAddresses().add(address2);
    
        Employee employee2 = new Employee("employee2");
        employee2.getAddresses().add(address2);
    
        Company companyA = new Company("compA");
    
        companyA.getEmployees().add(employee1);
        companyA.getEmployees().add(employee1); // you can add employee to the list as many times as you want, if you really need this?
        companyA.getEmployees().add(employee2);
    
        // now to get the employee with give name simly iterate over list of employees
    
        Iterator<Employee> employeeIt = companyA.getEmployees().iterator();
    
    
        Employee wantedEmployee = null;
    
        while (employeeIt.hasNext() && (wantedEmployee == null)) {
          Employee next = employeeIt.next();
    
          if (next.getName().equals("employee1")) {
            wantedEmployee = next;
          }
        }
    
        System.out.println(wantedEmployee);
    
    
      }
    
    
    
    }
    
    
    class Company {
      final String name;
    
      final List<Employee> employees;
    
      Company(String name) {
        this.name = name;
        this.employees = new ArrayList<>();
      }
    
      public String getName() {
        return name;
      }
    
      public List<Employee> getEmployees() {
        return employees;
      }
    
      @Override
      public boolean equals(Object o) {
        if (this == o) {
          return true;
        }
        if ((o == null) || (getClass() != o.getClass())) {
          return false;
        }
    
        Company company = (Company) o;
    
        if ((employees != null) ? (!employees.equals(company.employees)) : (company.employees != null)) {
          return false;
        }
        if ((name != null) ? (!name.equals(company.name)) : (company.name != null)) {
          return false;
        }
    
        return true;
      }
    
      @Override
      public int hashCode() {
        int result = (name != null) ? name.hashCode() : 0;
        result = (31 * result) + ((employees != null) ? employees.hashCode() : 0);
        return result;
      }
    }
    
    class Employee {
      final String name;
      final Set<Address> addresses;
    
      Employee(String name) {
        this.name = name;
        this.addresses = new HashSet<>();
      }
    
      public String getName() {
        return name;
      }
    
      public Set<Address> getAddresses() {
        return addresses;
      }
    
      @Override
      public String toString() {
        return "Employee{" +
          "name='" + name + '\'' +
          '}';
      }
    
      @Override
      public boolean equals(Object o) {
        if (this == o) {
          return true;
        }
        if ((o == null) || (getClass() != o.getClass())) {
          return false;
        }
    
        Employee employee = (Employee) o;
    
        if ((addresses != null) ? (!addresses.equals(employee.addresses)) : (employee.addresses != null)) {
          return false;
        }
        if ((name != null) ? (!name.equals(employee.name)) : (employee.name != null)) {
          return false;
        }
    
        return true;
      }
    
      @Override
      public int hashCode() {
        int result = (name != null) ? name.hashCode() : 0;
        result = (31 * result) + ((addresses != null) ? addresses.hashCode() : 0);
        return result;
      }
    }
    
    
    class Address {
      final String street;
    
      Address(String street) {
        this.street = street;
      }
    
      public String getStreet() {
        return street;
      }
    
      @Override
      public boolean equals(Object o) {
        if (this == o) {
          return true;
        }
        if ((o == null) || (getClass() != o.getClass())) {
          return false;
        }
    
        Address address = (Address) o;
    
        if ((street != null) ? (!street.equals(address.street)) : (address.street != null)) {
          return false;
        }
    
        return true;
      }
    
      @Override
      public int hashCode() {
        return (street != null) ? street.hashCode() : 0;
      }
    }