Итерация Apache Common MultiValueMap

У меня есть MultiMap, предположим, что компания имеет String в качестве ключа, а другой MultiMap предполагает, что сотрудник является значением. Сотрудник Multimap имеет String в качестве ключа и другой multimap в качестве значения. Мой вопрос: как мне получить и перебрать мультикарту, хранящуюся внутри мультикарты? Я использую общий MultiMap Apache.

Пример: compMap имеет 2 компании. В CompA и CompB в каждой компании по 10 сотрудников. (Сотрудник может появляться более одного раза, поэтому используется мультикарта)

Coll содержит мультикарту сотрудников из compA, однако как мне получить конкретного сотрудника (если он появляется 4 раза) из мультикарты сотрудников?

Код:

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

person Mind Peace    schedule 21.05.2015    source источник
comment
Какая версия вашей библиотеки Apache Commons?   -  person Konstantin Yovkov    schedule 28.05.2015
comment
А какая у вас версия Java? :)   -  person Konstantin Yovkov    schedule 28.05.2015
comment
Этот поток кажется потенциальным дубликатом stackoverflow.com/ вопросы/11852535/.   -  person Anand Pandey    schedule 28.05.2015
comment
@Kocko - JDK1.6 и Apache Commons 3.2.1   -  person Mind Peace    schedule 28.05.2015
comment
Не могли бы вы поделиться, как вы определяете MultiValueMap?   -  person Konstantin Yovkov    schedule 29.05.2015


Ответы (2)


Проблема, с которой вы столкнулись, вызвана тем, что один сотрудник не должен фигурировать два раза в одной коллекции. Если вы храните два значения под одним и тем же ключом в MultiValueMap, это будут разные значения (хотя они доступны по одному и тому же ключу).

Вы должны перенести свою модель данных на более объектно-ориентированную модель и не использовать контейнер хранилища ключей, расположенный внутри другого контейнера хранилища ключей (карта внутри карты).

Рассмотрим следующую модель, используя только набор/список. Значения различаются на основе равенства/хэш-кода. Если вы используете список, у вас может быть много сотрудников внутри компании (они могут иметь одно и то же имя, если вам это действительно нужно). Почему вы усложняете это, используя 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;
  }
}
person walkeros    schedule 01.06.2015

person    schedule
comment
или вы можете использовать логику через рекурсию. - person Shriram; 29.05.2015