如何在 Java 中实例化一组地图?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1493162/
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
How does one instantiate an array of maps in Java?
提问by Karl von L
I can declare an array of maps using generics to specify the map type:
我可以使用泛型声明一个地图数组来指定地图类型:
private Map<String, Integer>[] myMaps;
However, I can't figure out how to instantiate it properly:
但是,我不知道如何正确实例化它:
myMaps = new HashMap<String, Integer>[count]; // gives "generic array creation" error
myMaps = new HashMap[count]; // gives an "unchecked or unsafe operation" warning
myMaps = (Map<String, Integer>[])new HashMap[count]; // also gives warning
How can I instantiate this array of maps without getting a compiler error or warning?
如何在不出现编译器错误或警告的情况下实例化这个映射数组?
Update:
更新:
Thank you all for your replies. I ended up going with the List suggestion.
谢谢大家的回复。我最终选择了 List 建议。
采纳答案by Laurence Gonsalves
You can't safely create a generic array. Effective Java 2nd Edition goes into the details in the chapter on Generics. Start at the last paragraph of page 119:
您无法安全地创建通用数组。Effective Java 2nd Edition在泛型一章中详细介绍。从第 119 页的最后一段开始:
Why is it illegal to create a generic array? Because it isn't typesafe. If it were legal, casts generated by the compiler in an otherwise correct program could fail at runtime with a
ClassCastException
. This would violate the fundamental guarantee provided by the generic type system.To make this more concrete, consider the following code fragment:
// Why generic array creation is illegal - won't compile! List<String>[] stringLists = new List<String>[1]; // (1) List<Integer> intList = Arrays.asList(42); // (2) Object[] objects = stringLists; // (3) objects[0] = intList; // (4) String s = stringLists[0].get(0); // (5)
Let's pretend that line 1, which creates a generic array, is legal. Line 2 creates and initializes a
List<Integer>
containing a single element. Line 3 stores theList<String>
array into anObject
array variable, which is legal because arrays are covariant. Line 4 stores theList<Integer>
into the sole element of theObject
array, which succeeds because generics are implemented by erasure: the runtime type of aList<Integer>
instance is simplyList
, and the runtime type of aList<String>[]
instance isList[]
, so this assignment doesn't generate anArrayStoreException
. Now we're in trouble. We've stored aList<Integer>
instance into an array that is declared to hold onlyList<String>
instances. In line 5, we retrieve the sole element from the sole list in this array. The compiler automatically casts the retrieved element toString
, but it's anInteger
, so we get aClassCastException
at runtime. In order to prevent this from happening, line 1 (which creates a generic array) generates a compile-time error.
为什么创建泛型数组是非法的?因为它不是类型安全的。如果它是合法的,编译器在其他正确的程序中生成的强制转换可能会在运行时失败并带有
ClassCastException
. 这将违反泛型类型系统提供的基本保证。为了使这更具体,请考虑以下代码片段:
// Why generic array creation is illegal - won't compile! List<String>[] stringLists = new List<String>[1]; // (1) List<Integer> intList = Arrays.asList(42); // (2) Object[] objects = stringLists; // (3) objects[0] = intList; // (4) String s = stringLists[0].get(0); // (5)
让我们假设第 1 行创建了一个泛型数组,它是合法的。第 2 行创建并初始化
List<Integer>
包含单个元素的 。第 3 行将List<String>
数组存储 到Object
数组变量中,这是合法的,因为数组是协变的。第 4 行将 存储List<Integer>
到Object
数组的唯一元素中,之所以成功,是因为泛型是通过擦除实现的:List<Integer>
实例的运行时类型是 simpleList
,而实例的运行时类型List<String>[]
是List[]
,因此该赋值不会生成ArrayStoreException
. 现在我们遇到了麻烦。我们已经将一个List<Integer>
实例存储到一个数组中,该数组被声明为只保存List<String>
实例。在第 5 行,我们从该数组的唯一列表中检索唯一元素。编译器自动将检索到的元素强制转换为String
,但它是Integer
,因此我们ClassCastException
在运行时得到了 。为了防止这种情况发生,第 1 行(它创建了一个通用数组)生成了一个编译时错误。
Because arrays and generics don't combine well (as well as other reasons), it's generally better to use Collection
objects (in particular List
objects) rather than arrays.
因为数组和泛型不能很好地结合(以及其他原因),所以通常最好使用Collection
对象(特别是List
对象)而不是数组。
回答by Gandalf
myMaps = new HashMap<String, Integer>[10]();
So that's Wrong
所以这是错误的
Why not make a List of Maps instead of trying to make an array?
为什么不制作地图列表而不是尝试制作数组?
List<Map<String, Integer>> mymaps = new ArrayList<Map<String, Integer>>(count);
回答by starblue
In general it is not a good idea to mix generics and arrays in Java, better use an ArrayList.
一般来说,在 Java 中混合泛型和数组并不是一个好主意,最好使用 ArrayList。
If you must use an array, the best way to handle this is to put the array creation (your example 2 or 3) in a separate method and annotate it with @SuppressWarnings("unchecked").
如果您必须使用数组,处理此问题的最佳方法是将数组创建(您的示例 2 或 3)放在单独的方法中,并使用 @SuppressWarnings("unchecked") 对其进行注释。
回答by Bill the Lizard
Not strictly an answer to your question, but have you considered using a List
instead?
不是严格回答您的问题,但您是否考虑过使用 aList
代替?
List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
seems to work just fine.
似乎工作得很好。
See Java theory and practice: Generics gotchasfor a detailed explanation of why mixing arrays with generics is discouraged.
有关为什么不鼓励将数组与泛型混合的详细说明,请参阅Java 理论和实践:泛型陷阱。
Update:
更新:
As mentioned by Drew in the comments, it might be even better to use the Collectioninterface instead of List
. This might come in handy if you ever need to change to a Set
, or one of the other subinterfaces of Collection
. Example code:
正如 Drew 在评论中提到的,使用Collection接口而不是List
. 如果您需要更改为Set
或 的其他子接口之一,这可能会派上用场Collection
。示例代码:
Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
From this starting point, you'd only need to change HashSet
to ArrayList
, PriorityQueue
, or any other class that implements Collection
.
以此为起点,你只需要改变HashSet
到ArrayList
,PriorityQueue
或任何其他类实现Collection
。
回答by RHSeeger
Short answer appears to be that you really just can't.
简短的回答似乎是你真的不能。
See the following for a blog about it. http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/
有关它的博客,请参阅以下内容。 http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/
One of the comments to the blog states that:
该博客的评论之一指出:
Actually, the engineers made the creation of such an Array illegal. So the creation of an array from generic Class fails. The Collection.toArray method followed by a Cast to the Array works at compile time.
This solves not the problem, that the ArrayStoreCheck can't be done during Runtime, but you can create an Array of generics in this way.
实际上,工程师将创建这样的 Array 视为非法。所以从泛型类创建数组失败。Collection.toArray 方法后跟一个 Cast to the Array 在编译时工作。
这解决了不能在运行时执行 ArrayStoreCheck 的问题,但您可以通过这种方式创建泛型数组。
As suggested by Bill the Lizard, you probably are better off using a
正如比尔蜥蜴所建议的那样,您可能最好使用
List<Map<String,Integer>>
回答by Steve B.
I had a similar question, best response I got referred to this
回答by Ruju
You can create generic array of map
您可以创建地图的通用数组
Create list of map.
List<Map<String, ?>> myData = new ArrayList<Map<String, ?>>();
Initialize array.
Map<String,?>[]myDataArray=new HashMap[myData .size()];
Populate data in array from list.
myDataArray=myData.toArray(myDataArry);
创建地图列表。
List<Map<String, ?>> myData = new ArrayList<Map<String, ?>>();
初始化数组。
Map<String,?>[]myDataArray=new HashMap[myData .size()];
从列表中填充数组中的数据。
myDataArray=myData.toArray(myDataArry);
回答by Sridhar
I know its a bit late to reply but I found this workaround helpful for my case...Hope it helps!
我知道回复有点晚了,但我发现这个解决方法对我的案例有帮助......希望它有帮助!
Use an array of HashMap to store HashMaps..
使用一个 HashMap 数组来存储 HashMaps..
public static void main(String[] args) {
HashMap[] arr = new HashMap[1];//creating an array of size one..just for sake of example
HashMap<String, String> arrMap = new HashMap<String, String>();
//use loops to store desired key-value pairs into the HashMap which will be stored inside the array
arrMap.put("ABC", "Name");
//use loop to store your desired hashMap into the array at a particular index
arr[0] = arrMap;
//desired manipulation of the stored array.
System.out.println(arr[0]);
}