“无法创建通用数组..” - 如何创建Map <String,object =“”>?</string,>

时间:2013-02-17 02:25:13

标签: java arrays map hashmap

我想使用simpleJdbcInsert类和executeBatch方法

public int[] executeBatch(Map<String,Object>[] batch)

http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/simple/SimpleJdbcInsert.html

所以我需要传递一个Map<String,Object>数组作为参数。如何创建这样的数组? 我试过的是

Map<String, Object>[] myArray = new HashMap<String, Object>[10]

错误:无法创建Map<String, Object>

的通用数组

List<Map<String, Object>>会更容易,但我想我需要一个数组。那么如何创建Map<String, Object>数组? 谢谢

6 个答案:

答案 0 :(得分:57)

由于Java中的泛型如何工作,您无法直接创建泛型类型的数组(例如Map<String, Object>[])。而是创建一个原始类型(Map[])的数组并将其强制转换为Map<String, Object>[]。这将导致不可避免(但可以抑制)的编译器警告。

这应该适合您的需要:

Map<String, Object>[] myArray = (Map<String, Object>[]) new Map[10];

您可能希望使用@SupressWarnings("unchecked")注释此方法,以防止显示警告。

答案 1 :(得分:1)

您可以创建地图的通用数组。

  1. 创建地图列表。

    List<Map<String, ?>> myData = new ArrayList<Map<String, ?>>();
    
  2. 初始化数组。

    Map<String,?>[] myDataArray = new HashMap[myData.size()];
    
  3. 从列表中填充数组中的数据。

    myDataArray = myData.toArray(myDataArray);
    

答案 2 :(得分:0)

我遇到了一些困难,但我已经想出了一些我将尽可能简单分享的事情。

我对泛型的经验仅限于集合,所以我在类定义中使用它们,例如:

public class CircularArray<E> {

包含数据成员:

private E[] data;

但你不能制作类型泛型的数组,所以它有方法:

@SuppressWarnings("unchecked")
private E[] newArray(int size)
{
    return (E[]) new Object[size];  //Create an array of Objects then cast it as E[]
}

在构造函数中:

data = newArray(INITIAL_CAPACITY);  //Done for reusability

这适用于泛型泛型,但我需要一个可以排序的列表:可比较的列表。

public class SortedCircularArray<E extends Comparable<E>> { 
//any E that implements Comparable or extends a Comparable class

包含数据成员:

private E[] data;

但我们的新类抛出了java.lang.ClassCastException:

@SuppressWarnings("unchecked")
private E[] newArray(int size)
{
    //Old: return (E[]) new Object[size];  //Create an array of Objects then cast it as E[]
    return (E[]) new Comparable[size];  //A comparable is an object, but the converse may not be
}

在构造函数中,一切都是一样的:

data = newArray(INITIAL_CAPACITY);  //Done for reusability

我希望这会有所帮助,我希望如果我犯错误,我们更有经验的用户会纠正我。

答案 3 :(得分:0)

来自Oracle tutorial [ sic ]:

  

您无法创建参数化类型的数组。例如,以下代码无法编译:

List<Integer>[] arrayOfLists = new List<Integer>[2];  // compile-time error
     

以下代码说明了将不同类型插入数组时会发生什么:

Object[] strings = new String[2];
strings[0] = "hi";   // OK
strings[1] = 100;    // An ArrayStoreException is thrown.
     

如果您使用通用列表尝试相同的操作,则会出现问题:

Object[] stringLists = new List<String>[];  // compiler error, but pretend it's allowed
stringLists[0] = new ArrayList<String>();   // OK
stringLists[1] = new ArrayList<Integer>();  // An ArrayStoreException should be thrown,
                                            // but the runtime can't detect it.
     

如果允许参数化列表数组,则前面的代码将无法抛出所需的ArrayStoreException。

对我来说,这听起来很微弱。我认为任何对泛型有足够理解的程序员都会非常好,甚至可以预期,在这种情况下不会抛出ArrayStoredException。

更多的是,大多数程序员只会这样做:

List<Integer> arrayOfLists = (List<Integer>) new List[2];

这将使它们与ArrayStoreException的风险完全相同。

答案 4 :(得分:0)

据我所知

首先尝试创建一个java.lang.Object数组,然后转换为Generic类型T

示例:

class Example<DataType>{
    public DataType array = (DataType[]) new Object[5] ; 
}

通过这种方式,您可以创建一个通用数据类型

的数组

答案 5 :(得分:0)

@SuppressWarnings("unchecked")
private Map<String,?>[] newArray(int n) {
  return new Map[n];
}

Stream中的Map<String,?>一起使用:

  sql.executeBatch(myStream.toArray(this::newArray));

List中的Map<String,?>一起使用:

  sql.executeBatch(myList.toArray(newArray(0));

注意:SuppressWarnings技巧已在JDK src-https://github.com/AdoptOpenJDK/openjdk-jdk14/blob/master/src/java.base/share/classes/java/util/ArrayList.java#L395:L404

中积极使用

致谢:@JonathanCallen