HashMap with multiple values under the same key

前端 未结 22 1870
旧时难觅i
旧时难觅i 2020-11-22 06:49

Is it possible for us to implement a HashMap with one key and two values. Just as HashMap?

Please do help me, also by telling (if there is no way) any other way to

相关标签:
22条回答
  • 2020-11-22 06:56

    You could:

    1. Use a map that has a list as the value. Map<KeyType, List<ValueType>>.
    2. Create a new wrapper class and place instances of this wrapper in the map. Map<KeyType, WrapperType>.
    3. Use a tuple like class (saves creating lots of wrappers). Map<KeyType, Tuple<Value1Type, Value2Type>>.
    4. Use mulitple maps side-by-side.

    Examples

    1. Map with list as the value

    // create our map
    Map<String, List<Person>> peopleByForename = new HashMap<>();    
    
    // populate it
    List<Person> people = new ArrayList<>();
    people.add(new Person("Bob Smith"));
    people.add(new Person("Bob Jones"));
    peopleByForename.put("Bob", people);
    
    // read from it
    List<Person> bobs = peopleByForename["Bob"];
    Person bob1 = bobs[0];
    Person bob2 = bobs[1];
    

    The disadvantage with this approach is that the list is not bound to exactly two values.

    2. Using wrapper class

    // define our wrapper
    class Wrapper {
        public Wrapper(Person person1, Person person2) {
           this.person1 = person1;
           this.person2 = person2;
        }
    
        public Person getPerson1 { return this.person1; }
        public Person getPerson2 { return this.person2; }
    
        private Person person1;
        private Person person2;
    }
    
    // create our map
    Map<String, Wrapper> peopleByForename = new HashMap<>();
    
    // populate it
    Wrapper people = new Wrapper();
    peopleByForename.put("Bob", new Wrapper(new Person("Bob Smith"),
                                            new Person("Bob Jones"));
    
    // read from it
    Wrapper bobs = peopleByForename.get("Bob");
    Person bob1 = bobs.getPerson1;
    Person bob2 = bobs.getPerson2;
    

    The disadvantage to this approach is that you have to write a lot of boiler-plate code for all of these very simple container classes.

    3. Using a tuple

    // you'll have to write or download a Tuple class in Java, (.NET ships with one)
    
    // create our map
    Map<String, Tuple2<Person, Person> peopleByForename = new HashMap<>();
    
    // populate it
    peopleByForename.put("Bob", new Tuple2(new Person("Bob Smith",
                                           new Person("Bob Jones"));
    
    // read from it
    Tuple<Person, Person> bobs = peopleByForename["Bob"];
    Person bob1 = bobs.Item1;
    Person bob2 = bobs.Item2;
    

    This is the best solution in my opinion.

    4. Multiple maps

    // create our maps
    Map<String, Person> firstPersonByForename = new HashMap<>();
    Map<String, Person> secondPersonByForename = new HashMap<>();
    
    // populate them
    firstPersonByForename.put("Bob", new Person("Bob Smith"));
    secondPersonByForename.put("Bob", new Person("Bob Jones"));
    
    // read from them
    Person bob1 = firstPersonByForename["Bob"];
    Person bob2 = secondPersonByForename["Bob"];
    

    The disadvantage of this solution is that it's not obvious that the two maps are related, a programmatic error could see the two maps get out of sync.

    0 讨论(0)
  • 2020-11-22 06:56

    I prefer the following to store any number of variables without having to create a separate class.

    final public static Map<String, Map<String, Float>> myMap    = new HashMap<String, Map<String, Float>>();
    
    0 讨论(0)
  • 2020-11-22 06:57

    I am so used to just doing this with a Data Dictionary in Objective C. It was harder to get a similar result in Java for Android. I ended up creating a custom class, and then just doing a hashmap of my custom class.

    public class Test1 {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.addview);
    
    //create the datastring
        HashMap<Integer, myClass> hm = new HashMap<Integer, myClass>();
        hm.put(1, new myClass("Car", "Small", 3000));
        hm.put(2, new myClass("Truck", "Large", 4000));
        hm.put(3, new myClass("Motorcycle", "Small", 1000));
    
    //pull the datastring back for a specific item.
    //also can edit the data using the set methods.  this just shows getting it for display.
        myClass test1 = hm.get(1);
        String testitem = test1.getItem();
        int testprice = test1.getPrice();
        Log.i("Class Info Example",testitem+Integer.toString(testprice));
    }
    }
    
    //custom class.  You could make it public to use on several activities, or just include in the activity if using only here
    class myClass{
        private String item;
        private String type;
        private int price;
    
        public myClass(String itm, String ty, int pr){
            this.item = itm;
            this.price = pr;
            this.type = ty;
        }
    
        public String getItem() {
            return item;
        }
    
        public void setItem(String item) {
            this.item = item;
        }
    
        public String getType() {
            return item;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public int getPrice() {
            return price;
        }
    
        public void setPrice(int price) {
            this.price = price;
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 06:58

    If you use Spring Framework. There is: org.springframework.util.MultiValueMap.

    To create unmodifiable multi value map:

    Map<String,List<String>> map = ...
    MultiValueMap<String, String> multiValueMap = CollectionUtils.toMultiValueMap(map);
    

    Or use org.springframework.util.LinkedMultiValueMap

    0 讨论(0)
  • 2020-11-22 06:58

    You can do it implicitly.

    // Create the map. There is no restriction to the size that the array String can have
    HashMap<Integer, String[]> map = new HashMap<Integer, String[]>();
    
    //initialize a key chosing the array of String you want for your values
    map.put(1, new String[] { "name1", "name2" });
    
    //edit value of a key
    map.get(1)[0] = "othername";
    

    This is very simple and effective. If you want values of diferent classes instead, you can do the following:

    HashMap<Integer, Object[]> map = new HashMap<Integer, Object[]>();
    
    0 讨论(0)
  • 2020-11-22 06:59

    I use Map<KeyType, Object[]> for associating multiple values with a key in a Map. This way, I can store multiple values of different types associated with a key. You have to take care by maintaining proper order of inserting and retrieving from Object[].

    Example: Consider, we want to store Student information. Key is id, while we would like to store name, address and email associated to the student.

           //To make entry into Map
            Map<Integer, String[]> studenMap = new HashMap<Integer, String[]>();
            String[] studentInformationArray = new String[]{"name", "address", "email"};
            int studenId = 1;
            studenMap.put(studenId, studentInformationArray);
    
            //To retrieve values from Map
            String name = studenMap.get(studenId)[1];
            String address = studenMap.get(studenId)[2];
            String email = studenMap.get(studenId)[3];
    
    0 讨论(0)
提交回复
热议问题