简体   繁体   中英

Which Map class should I use for data consisting of different types?

It seems that HashMap is limited to only one value, and I need a table of values like:

Joe(string) 25(Integer) 2.0(Double)

Steve(string) 41(Integer) 1.6(Double)

etc.

I want to store infomation similarly as in two-dimensional array, but I want it to have different variable types. I've look at various Map-implementing classes, but it seems that they only store value (assigned to a key), or two variables (I need at least three). What class should I use for this?

It sounds like you should be creating a separate class with a String field, an int field and a double field.

Then you can create a map with that as the value type, and whatever type you like as a key. For example:

Map<String, Person> map = new HashMap<>();
// What keys do you really want here?
map.put("foo", new Person("Joe", 25, 2.0));
map.put("bar", new Person("Steve", 41, 1.6));

Or it's possible that you don't even need a map at all at that point:

List<Person> list = new ArrayList<>();
list.add(new Person("Joe", 25, 2.0));
list.add(new Person("Steve", 41, 1.6));

Make class representing data you want to store, eg.

class Person {
    String name;
    //rest
}

and then make map like Map. Type of map is irrelevant

I would suggest that you create a simple class that stores the integer and double pair, which is then mapped to a String (I assume this is the desired outcome).

HashMap<String, Pair<Integer, Double>> map = new HashMap<String, Pair<Integer, Double>>;
map.put("Steve", new Pair<Integer, Double>(41, 1.6));

Where Pair is defined as

class Pair<T, K> {

    public T val1;
    public K val2;

    public Pair(T val1, K val2){
        this.val1 = val1;
        this.val2 = val2;
    }
}

There are a number of ways to do this.

The best way is the way that is suggested by Jon Skeet and @novy1234. Create a custom class that represents a person (or whatever the rows of the table are). Then use either a Map or a List of that class to represent the "table". (The Map allows you to select one of the fields / columns as a key ... if that is appropriate.)

So you might end up with a HashMap<String, Person> or an ArrayList<Person> ... where Person is your custom class.

A second way would be to represent each row as a Map<String,Object> so that (for example) "name" maps to "Joe" , "age" maps to 25 and "height" maps to 2.0 . (He is tall.) Then the table could be either a Map or a List of those maps.

A variation of the second way would be a Map<String, Map<String, Object>> where the keys of the outer map are each person's name, the keys of the inner map are the field names; eg "age" and "height" .

However using a Map<String, Object> to represent a row is not a good Java solution when the set of columns is known. A custom class will use significantly less space than a Map (of any flavour), and a regular getter method is orders of magnitude faster that a Map.get(key) method. In addition, the Map.get(...) method is going to return you an Object that has to be cast to the expected type before it can be used. There is a risk that the typecast will fail at runtime, because you have (somehow) populated the row / map incorrectly.

You should only contemplate using a Map to represent a row in the table if the columns are not known at compile time, or if there are an unmanageably number of columns that are populated sparsely. (Neither is the case here ...)


So, which Map class should you use?

Your alternatives include HashMap , TreeMap , LinkedHashMap and ConcurrentHashMap . Each one has different properties and different target use-cases. However, if your table is small, and in the absence of specific requirements, it probably makes no real difference.

使一个节点存储整数和双精度值?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM