JAVA HashMap 2D,无法获得制作 2D HashMap 的正确方法,我的意思是将 HashMap 转换为另一个 HashMap

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10299560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:26:45  来源:igfitidea点击:

JAVA HashMap 2D, cant get the right approach to make a 2D HashMap, i mean a HashMap into another HashMap

javahashmapnested

提问by ZelelB

I want to make a board of Students' names and Subjects and each student has a grade in each subject (or not.. he can leave the exam and doesnt write it, and then his case will be empty). I want to use just HashMaps. I mean, it will be something like that:

我想制作一个学生姓名和科目的董事会,每个学生在每个科目上都有一个成绩(或不……他可以离开考试不写,然后他的案子就空了)。我只想使用 HashMaps。我的意思是,它会是这样的:

HashMap<String,HashMap<String,String>> bigBoard = 
    new HashMap<String,HashMap<String,String>>();

but I think, I dont have the right idea, because for each subject, there will be many grades (values) so that won't be possible. Do I have to make a map for each student? with his subject? but then the table on output won't be arranged. Do you have a proposition? I would like a table that look like something like that for example.

但我认为,我没有正确的想法,因为对于每个科目,都会有很多等级(值),所以这是不可能的。我必须为每个学生制作一张地图吗?他的主题?但随后将不会安排输出表。你有什么提议吗?例如,我想要一张看起来像这样的桌子。

Column-Key →
  Rowkey↓      Mathematics         Physics       Finance

Daniel Dolter         1.3           3.7 

Micky Mouse                                      5

Minnie Mouse                        1.7          n/a

Dagobert Duck         4.0                        1.0

(I would use all the keys/values as Strings, it will be more simple like that.)

(我会将所有的键/值用作字符串,这样会更简单。)

After the implementation of our class (for example class-name is String2D), we should use it like that.

在我们的类实现之后(例如 class-name 是 String2D),我们应该这样使用它。

public static void main(String[] args) {

    String2D map2D = new String2D(); 
    map2D.put("Daniel Doster", "Practical Mathematics", "1.3"); 
    map2D.put("Daniel Doster", "IT Systeme", "3.7"); 
    map2D.put("Micky Mouse", "Finance", "5");
    map2D.put("Minnie Mouse", "IT Systeme", "1.7");
    map2D.put("Minnie Mouse", "Finance", "n/a");
    map2D.put("Dagobert Duck", "Practical Mathematics", "4.0");
    map2D.put("Dagobert Duck", "Finance", "1.0");
    System.out.println(map2D); 
} 

No "HashMap" will be seen.. and Arrays aren't allowed

不会看到“HashMap”......并且不允许使用数组

回答by Victor P.

You can use this class:

你可以使用这个类:

public class BiHashMap<K1, K2, V> {

private final Map<K1, Map<K2, V>> mMap;

public BiHashMap() {
    mMap = new HashMap<K1, Map<K2, V>>();
}

/**
 * Associates the specified value with the specified keys in this map (optional operation). If the map previously
 * contained a mapping for the key, the old value is replaced by the specified value.
 * 
 * @param key1
 *            the first key
 * @param key2
 *            the second key
 * @param value
 *            the value to be set
 * @return the value previously associated with (key1,key2), or <code>null</code> if none
 * @see Map#put(Object, Object)
 */
public V put(K1 key1, K2 key2, V value) {
    Map<K2, V> map;
    if (mMap.containsKey(key1)) {
        map = mMap.get(key1);
    } else {
        map = new HashMap<K2, V>();
        mMap.put(key1, map);
    }

    return map.put(key2, value);
}

/**
 * Returns the value to which the specified key is mapped, or <code>null</code> if this map contains no mapping for
 * the key.
 * 
 * @param key1
 *            the first key whose associated value is to be returned
 * @param key2
 *            the second key whose associated value is to be returned
 * @return the value to which the specified key is mapped, or <code>null</code> if this map contains no mapping for
 *         the key
 * @see Map#get(Object)
 */
public V get(K1 key1, K2 key2) {
    if (mMap.containsKey(key1)) {
        return mMap.get(key1).get(key2);
    } else {
        return null;
    }
}

/**
 * Returns <code>true</code> if this map contains a mapping for the specified key
 * 
 * @param key1
 *            the first key whose presence in this map is to be tested
 * @param key2
 *            the second key whose presence in this map is to be tested
 * @return Returns true if this map contains a mapping for the specified key
 * @see Map#containsKey(Object)
 */
public boolean containsKeys(K1 key1, K2 key2) {
    return mMap.containsKey(key1) && mMap.get(key1).containsKey(key2);
}

public void clear() {
    mMap.clear();
}

}

And then create use it like this:

然后像这样创建使用它:

BiHashMap<String,String,String> bigBoard = new BiHashMap<String,String,String>();

However for performance you may want to store the different grades in an array (assuming that you have a fix set of courses)

但是,为了提高性能,您可能希望将不同的成绩存储在一个数组中(假设您有一组固定的课程)

回答by eabraham

I don't think a nested hashmap is the way to go. Create a Student class and Subject class.

我不认为嵌套哈希图是要走的路。创建一个学生类和主题类。

public class Student{
    private ArrayList<Subject> SubjectList = new ArrayList<Subject>();
    private String name;

    public Student(String name){
        this.name=name;
    }
    public void addSubject(Subject s){
        SubjectList.add(s);
    }
    public String getName(){
        return this.name;
    }
    //...add methods for other operations
}
public class Subject{
    private ArrayList<double > GradeList = new ArrayList<double>();
    private String name;

    public Subject(String name){
        this.name=name;
    }
    public void addGrade(double s){
        GradeList.add(s);
    }
    //...add methods for other operations
}

Then you can store the Students instances in a hashmap.

然后,您可以将 Students 实例存储在哈希图中。

public static void main(String[] args){
    HashMap<Students> hm = new HashMap<Students>();
    Student s = new Student("Daniel Dolter");
    Subject sub = new Subject("Mathematics");
    sub.addGrades(1.3);
    s.addSubject(sub);
    hm.put(s.getName(),s);
}

回答by Claude Martin

With Java 8 it is possible to use computeIfAbsentto insert a default value if it is empty. So you can simply use this as the type of the 2d-map:

使用 Java 8,可以使用computeIfAbsent插入一个默认值(如果它是空的)。所以你可以简单地使用它作为 2d-map 的类型:

Map<RowType, Map<ColumnType, ValueType>> map = new WhateverMap<>();

let's say all types are int:

假设所有类型都是 int:

int get(int x, int y) 
  return map.computeIfAbsent(x, (key)->new WhateverMap<>()).computeIfAbsent(y,(key)->0);
}

void put(int x, int y, int value) 
  return map.computeIfAbsent(x, (key)->new WhateverMap<>()).put(y,value);
}

Note that is not atomic. therefore this is not thread-safe even if WhateverMap is.

请注意,这不是原子的。因此,即使是WhateverMap,这也不是线程安全的。

回答by Pranav A.

You can use Google Guava's Table<R, C, V>collection. It is similar to eabraham's answer. A value Vis keyed by a row Rand a column C. It is a better alternative to using HashMap<R, HashMap<C, V>>which becomes quickly unreadable and difficult to work with.

您可以使用 Google Guava 的Table<R, C, V>集合。这类似于 eabraham 的回答。一个值V由一行R和一列键控C。它是一种更好的替代方法,HashMap<R, HashMap<C, V>>它会很快变得不可读且难以使用。

See their GitHub Wikifor more information.

有关更多信息,请参阅他们的GitHub Wiki