由于peopleCode不能调用Java含参数构建方法,且有些重载方法由于输入类型无法准确识别而抛出多方法重载异常,所以需要使用Java反射机制
为什么要设置HashMap初始大小
HashMap和数组一样,是有初始长度的,创建时初始容量(initialCapacity)为16 ,initialCapacity = (需要存储的元素个数 / 加载因子) + 1
其查找数据是利用key计算出的哈希表对应value地址从而快速查找到数据,每当长度不足时,map都会自动的将容量扩充一倍,这时要对哈希表进行rehash操作(即重建内部数据结构,之前所有数据的key都要重新计算hash值,并重新将这些键值对存放到相应的位置),这对性能上的影响将是一场灾难,尤其是数据较多的时候。所以,如果想使用此类储存较多的数据,那么建议提前设置好大小,这对写入性能将会有较大的提升。
初始容量(initialCapacity)和加载因子(loadFactor):
这两个参数是影响HashMap性能的重要参数,其中容量表示哈希表中桶的数量,初始容量是创建哈希表时的容量,加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。对于使用链表法的散列表来说,查找一个元素的平均时间是O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。系统默认负载因子为0.75,一般情况下我们是无需修改的。
默认加载因子(.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。
------------------------------------代码分割线------------------------------------
代码实现:
/*
&desiredSize 需要储存元素的个数
&loadFactor 加载因子
*/
method rebuildAndSetLoadFactor
/+ &desiredSize as Integer, +/
/+ &loadFactor as Float +/
local JavaObject &map = Null;
/* number 转 integer时自动四舍五入,加 0.4 是为了实现进1取整 */
Local integer &initialCapacity = (&desiredSize / &loadFactor + 1) + 0.4;
/* 通过反射创建类,调用带有参数的构造方法 */
/* 根据类名获取Class对象 */
Local JavaObject &ClassC = GetJavaClass("java.lang.Class");
/* 参数类型数组 */
Local JavaObject ¶meterTypes = CreateJavaArray("java.lang.Class[]", 2);
Local JavaObject &RefArray = GetJavaClass("java.lang.reflect.Array");
Local JavaObject &javaInteger = GetJavaClass("java.lang.Integer");
Local JavaObject &javaFloat = GetJavaClass("java.lang.Float");
&RefArray.set(¶meterTypes, 0, &javaInteger.TYPE);
&RefArray.set(¶meterTypes, 1, &javaFloat.TYPE);
/* 根据参数类型获取相应的构造函数 */
Local JavaObject &mapClassType = &ClassC.forName("java.util.HashMap");
Local JavaObject &constructor = &mapClassType.getConstructor(¶meterTypes);
/* 参数数组 */
Local JavaObject ¶meters = CreateJavaArray("java.lang.Object[]", 2);
&RefArray.set(¶meters, 0, &javaInteger.valueOf(&initialCapacity));
&RefArray.set(¶meters, 1, %This.getJavaFloat(&loadFactor));
rem &RefArray.set(¶meters, 1, &javaInteger.valueOf("1"));
/* 根据获取的构造函数和参数,创建实例 */
Local JavaObject &o = &constructor.newInstance(¶meters);
&map = &mapClassType.cast(&o);
return ↦
end-method;
method getJavaFloat
/+ &value as Float +/
/+ Returns JavaObject +/
Local JavaObject &RefArray = GetJavaClass("java.lang.reflect.Array");
/* 根据类名获取Class对象 */
Local JavaObject &ClassC = GetJavaClass("java.lang.Class");
/* 参数类型数组 */
Local JavaObject ¶meterTypes = CreateJavaArray("java.lang.Class[]", 1);
Local JavaObject &javaDouble = GetJavaClass("java.lang.Double");
&RefArray.set(¶meterTypes, 0, &javaDouble.TYPE);
/* 根据参数类型获取相应的构造函数 */
Local JavaObject &floatClassType = &ClassC.forName("java.lang.Float");
Local JavaObject &constructor = &floatClassType.getConstructor(¶meterTypes);
/* 参数数组 */
Local JavaObject ¶meters = CreateJavaArray("java.lang.Double[]", 1);
&RefArray.set(¶meters, 0, &javaDouble.valueOf(&value));
/* 根据获取的构造函数和参数,创建实例 */
Local JavaObject &o = &constructor.newInstance(¶meters);
Return &floatClassType.cast(&o);
end-method;