英文:
Java multidimensional multi type Array (Map/List/Collection)?
问题
我们有一个声明如下:
ArrayList<Map<String, Map<Integer, Object>>> parameterSet = new ArrayList<Map<String, Map<Integer, Object>>>();
可能可以这样定义(我知道,下面的是伪代码,请理解):
List<List<String, Integer, Object>> parameterSet = new ...;
我很确定,有一种更好的方法来定义这样一个二维多类型的“数组”。
英文:
We have a declaration like this:
ArrayList<Map<String, Map<Integer, Object>>> parameterSet = new ArrayList<Map<String, Map<Integer, Object>>>();
Probably it's possible to define it in a way like this (I know, it's wrong, please take it as pseudo code):
List<List<String, Integer, Object>> parameterSet = new ...;
I'm pretty sure, there is a better way to define such a two dimensional multi-type "array".
答案1
得分: 1
这里的问题不是维度,而是"多类型"。
要么找到一个通用的超类型来容纳你的元素(最后的手段总是可以是 Object
),要么创建一个包装类,可以容纳你需要的任何类型。
List<Object>
拥有 Object
对象是快速和"容易"的,但当你需要将元素转换为它们的实际类时,可能会变得混乱。根据你想在列表中保存多少不同类型,条件语句可能会变得相当复杂:
Object elem = mylist.get(i);
if (elem instanceof Float){
Float floatElem = (Float) elem;
}
...
更精确的方法是使用包装类:
public class Wrapper<T> {
private T data;
// 构造函数可以很方便
public Wrapper(Float f){this.data=f;}
public Wrapper(Double d){this.data=d;}
public Wrapper(String s){this.data=s;}
public void setData(T newData) {
data = newData;
}
public T getData() {
return data;
}
// 你可以添加便利方法来确定你的包装类包含的是什么类型
public boolean isString(){
return this.data instanceof String; // 例如
}
// 还可以添加便利方法来"转换"你的数据
public Float asFloat(){
return (Float) this.data;
}
}
然后,你的列表只需要包含你的包装类:
List<Wrapper> list = new ArrayList<>();
list.add(new Wrapper<Float>(1.2f));
要检查元素的类型,你可以使用你的便利方法:
if(list.get(i).isFloat()){
Float f = list.get(i).asFloat();
}
英文:
The problem here is not the dimension but the "multi-type".
Either you find a common super-type for your elements (last resort can always be Object
) or you create a wrapper class that can hold whatever type you need.
List<Object>
Having Object
objects is fast and "easy" but it can get messy when you need to cast the elements to their actual class. Depending on how many different types you want to hold in you list, the ifs can become quite complex:
Object elem = mylist.get(i);
if(elem instanceof Float){
Float floatElem = (Float) elem;
}
...
More precise would be the wrapper class
public class Wrapper<T> {
private T data;
// constructors can be nice
public Wrapper(Float f){this.data=f;}
public Wrapper(Double d){this.data=d;}
public Wrapper(String s){this.data=s;}
public void setData(T newData) {
data = newData;
}
public T getData() {
return data;
}
// you can add convenience methods to find out what type your wrapper holds
public boolean isString(){
return this.data instanceof String; // for example
}
// and also convenience methods to "cast" your data
public Float asFloat(){
return (Float) this.data;
}
}
Then your List will only need to hold your wrapper class
List<Wrapper> list = new ArrayList<>();
list.add(new Wrapper<Float>(1.2f));
And to check the type of your element you can use your convenience methods:
if(list.get(i).isFloat()){
Float f = list.get(i).asFloat();
}
答案2
得分: 0
使用标准的Java集合API,您基本上可以做两件事:
- 在声明中使用
List
而不是ArrayList
:List<Map<String, Map<Integer, Object>>> parameterSet = new ArrayList<Map<String, Map<Integer, Object>>>();
- 使用钻石操作符(如果您使用的是Java 7+):
List<Map<String, Map<Integer, Object>>> parameterSet = new ArrayList<>();
然而,在这种情况下,我会考虑定义一个封装复杂数据结构(map的map)的类。
英文:
Using standard Java Collection API, you can do basically 2 things:
- Use
List
instead ofArrayList
in the declaration:List<Map<String, Map<Integer, Object>>> parameterSet = new ArrayList<Map<String, Map<Integer, Object>>>();
- Use the diamond operator (if you are using Java 7+):
List<Map<String, Map<Integer, Object>>> parameterSet = new ArrayList<>();
Still, in this case, I would consider defining a class encapsulating the complex data structure (map of map).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论