Java:最终字段树图更改大小

时间:2011-04-22 01:46:19

标签: java

我有一个java代码,其中包含一个包含交易历史记录的TRADE_HISTORY类。

类TRADE_HISTORY有一个名为fMapDateOutputPriceRatios的final字段,它在构造函数中设置。 fMapDateOutputPriceRatios是日期和双数组(TreeMap)之间的映射。在构造函数中,使用

将字段绑定到argurment
fMapDateOutputPriceRatios = new TreeMap<Date, double[]>(aOutputPriceRatioData); 

使用

获取日期数
Set<Date> dates = fMapDateOutputPriceRatios.keySet();

日期的大小在构造函数中打印出来。该类只有一个构造函数。

添加新交易时出现问题。添加新日期时,将使用双向量,并从

获取
 double[] outputPriceRatios = fMapDateOutputPriceRatios.get( aDate );

发生错误是因为日期不可用。

在尝试调试错误时,正在打印日期的大小。

在施工期间,尺寸为1973个元素。

发生错误时,大小为1964个元素。

特别是,错误发生时,2011年4月11日的日期不可用。

我正在使用eclipse,并在变量fMapDateOutputPriceRatios上设置了一个中断,以便在修改字段时中断。它只在构造函数中断开。

有关如何确定fMapDateOutputPriceRatios大小变化的原因的任何建议?

访问fMapDateOutputPriceRatios的唯一行是

TRADE_HISTORY::TRADE_HISTORY(Map<Date, double[]> aOutputPriceRatioData )
        fMapDateOutputPriceRatios = new TreeMap<Date, double[]>(aOutputPriceRatioData); 
        Set<Date> dates = fMapDateOutputPriceRatios.keySet();  // Used to debug error

TRADE_HISTORY::public void addTradeDistribution_0_to_100(Date aDate, ...)
        outputPriceRatios = fMapDateOutputPriceRatios.get( aDate )  // Causes error
        Set<Date> dates = fMapDateOutputPriceRatios.keySet();   // Used to debug error

3 个答案:

答案 0 :(得分:3)

对象实例的最终引用不会使该实例不可变!它只会阻止更改引用以指向不同的对象实例。引用是最终的 - 而不是它引用的对象实例的状态。

请注意keySet()返回的密钥集由地图支持。如果从中删除密钥,则会从fMapDateOutputPriceRatios中删除相应的映射。您是在修改dates还是将其用于调试以外的任何其他内容?

答案 1 :(得分:0)

首先,重要的问题是:你确定用作密钥的日期在任何地方都没有被修改吗? Date应该是一个不可变对象,但它仍然包含遗留的弃用方法,允许用户更改密钥内容。这会对TreeMap造成不可预测的后果,包括你描述的那些。

此外,请确保所有日期都将小时/分钟/秒/毫秒清除为0。

现在,假设日期是不可变的:

您实际上已经观察到密钥集大小的减少,这意味着内容的物理修改发生了。我知道它是如何发生的唯一方法是通过两个或多个线程并发访问地图。

添加新密钥时,TreeMap必须重建树。也就是说,取消链接树的一部分,并将其重新链接到树中的其他位置。在此期间,如果另一个线程访问相同的结构并执行相同的操作,则该子树可能会丢失,导致密钥数量减少。

因此,作为第一步,尝试在同步块中访问此字段:

synchronized(fMapDateOutputPriceRatios) {
    outputPriceRatios = fMapDateOutputPriceRatios.get( aDate )
}

P.S。我实际上并没有在你的代码中看到put(),但它必须在那里,没有奇迹

答案 2 :(得分:0)

感谢您的反馈。

将日期/输出价格图移动到驱动功能可消除日期/输出价格图出现问题的可能性。 但是,仍然会出现意外错误。

在TRADE_HISTORY的构造函数中添加了一个静态计数器,以跟踪构造的TRADE_HISTORY的数量。此外,整数id被添加到构造函数并设置为等于计数器,因此id应为1,2,3 ......

当发生当前错误时,将打印TRADE_HISTORY id并为零,这不应发生。在TRADE_HISTORY实例的构造函数中需要进行更多调试。似乎有一个没有正确构建的TRADE_HISTORY。

如果需要更多帮助,将启动另一个问题。