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
JAVA HashMap 2D, cant get the right approach to make a 2D HashMap, i mean a HashMap into another HashMap
提问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 V
is keyed by a row R
and 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。