Maps with multiple types of values in java

2019-01-19 00:42发布

问题:

I have to accomplish a strange peculiar scenario. Its described as follows:

I have to design a Map where the 'Keys' are always of String type. However, the 'Value' for one of the key may be a String or a List(depends on the number of values a particular key can have. 'Value' will be a String if that particular key has only one value and it has to be a List if the key contains many values). How to accomplish this scenario?

For Example: there are 2 keys in a map namely "Name" and "Phone Nos". A person can have only one name and multiple phone numbers. So here the first key i.e. "Name" should have 'String' type for Value, whereas for the second key i.e. "Phone Nos" should have 'List' type for Value. How to declare such a Map. Is it possible?

回答1:

It is possible to do something like Map<String, Object>.

But: I would strongly suggest to think your design over. You should use a class for your persons instead. That way you could do: Map<String, Person> with Person having getters and setters for names, phone numbers and other information.

Example Person class:

public class Person {

    private String name;
    private List<String> phoneNumbers = Collections.emptyList();

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setPhoneNumbers(List<String> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }

    public void addPhoneNumber(String number) {
        phoneNumbers.add(number);
    }

    public List<String> getPhoneNumbers() {
        return phoneNumbers;
    }
}


回答2:

Of course there is. Pick your poison:

Map<String, Object> mixed = new HashMap<String, Object>();

Map<String, Serializable> mixed = new HashMap<String, Serializable>();

@SuppressWarnings("rawtypes")
Map mixed = new HashMap();


回答3:

Well, why not make a Map<String, List<String>>? you could always just add one element to your list if there is just one value or use a common supertype of String and List, thus you would get

Map<String, Object>


回答4:

I would do one of the following:

  1. Use a Multimap<String, String>. The Multimap would contain one or more values associated with each key.

  2. Use a Map<String, Either<String, List<String>>>. Use a Either to distinguish between a single or multiple values.



回答5:

Why not make a PhoneNumber wrapper class that exposes an API for soring either one or multipel phone numbers and then can retrieve either one or all (multiple) phone numbers and then make a map of String and PhoneNumber? Something like:

class PhoneNumber {


  private String[] phoneNumbers;


  public void storePhoneNumber(String... phoneNumbers) {
     this.phoneNumbers = phoneNumbers;
  }

  public String getPhoneNumber() {
    if(phoneNumbers.length>=1) {
      return phoneNumbers[0];
    } else {
      return null;
    }

  }

  public List<String> getPhoneNumbers() {
    if(phoneNumbers!=null) {
      return Arrays.asList(phoneNumbers);
    } else {
      return null;
    }

  }

}



标签: java types map key