【问题标题】:Handling Static Collections in Java在 Java 中处理静态集合
【发布时间】:2012-04-07 13:06:42
【问题描述】:

假设我有一个 A 类,如下所示

    public class A {
      protected static float[] floatArray = null;
      protected static Map<Integer, float[]>  history = new HashMap<Integer,float[]>();
      protected static Integer historyCount = 0;

      public void runEverySecond(Populator objPopulator) {
         floatArray = objPopulator.getValues();
         history.put(historyCount, floatArray);
         historyCount++;
      }  
    }

B 类如下所示

    public class B {
      private A objA;
      protected final static Populator objPopulator = new Populator();

      public void run(Integer numOfTime) {
        for(int i = 0; i < numOfTime; i++)
           objA.runEverySecond(objPopulator);
      }
    }

类填充器如下所示

    public class Populator {
      protected float[] randomValues = new float[2];
      public float[] getValues() {
        randomValues[0] = //some new random float value generated for every call
        randomValues[1] = //some new random float value generated for every call
        return randomValues;
      }
    }

包含 main 的类如下所示

    public class MainClass {
      public static void main() {
        final B objB = new B();
        objB.run(10);
      }
    }

这是我面临的问题,地图历史记录包含地图中每个条目的相同值。我希望地图历史记录存储 objPopulator.getValues() 方法生成的所有值。我该怎么做?

一些帮助将非常明显。 提前致谢:)

A 类表示的实际代码(已删除无关代码)

public class MySuperAgent implements Agent {
protected static float[] marioFloatPos = null;
protected static Map<Integer, float[]> levelRecord = new HashMap<Integer, float[]>();
protected static Integer mapCount = 0;
/*  protected static int testCount = 0;
protected static float[] testx = new float[2];
protected static float[] testy = new float[2];*/

@Override
public void integrateObservation(Environment environment) {
    marioFloatPos = environment.getMarioFloatPos();
    levelRecord.put(mapCount, marioFloatPos);
    mapCount++;

   /*if(testCount < 2){
        testx[testCount] = marioFloatPos[0];
        testy[testCount] = marioFloatPos[1];
        testCount++;
    } else {
        testCount = 0;
    }*/
  }
}

C类代表环境对象 从类似于B类的类调用integrateObservation方法 如果我使用注释块中的代码,那么我只能记录马里奥的 x 和 y 的 2 个过去值。我需要一种方法来存储马里奥的所有 x 和 y 值:)

【问题讨论】:

  • 我自己,一开始我不会处理所有这些静态问题。
  • 这些东西在 Java 中称为“引用”,在其他语言中称为“指针”。如果您知道如何使用它们,它们就是美妙的东西。
  • @HovercraftFullOfEels: 哈哈.. 是的,所有这些静态数据都搞砸了.. 不幸的是,我无法更改此类中的代码,因为还有其他数量的类正在使用这些值,我无法更改代码在那些课程中,因为我不允许:(..
  • @HotLicks: 是的,引用很好,但我不能更改我不负责的其他类中的代码:)
  • @Pazuzu:您可能想向您的团队提出更灵活的代码所有权流程:martinfowler.com/bliki/CodeOwnership.html 当然,您仍然必须确保解决向后兼容性问题。

标签: java collections static hashmap


【解决方案1】:

Map 中的每个条目都引用了相同的静态字段 floatArray 作为其值。

考虑将floatArray 作为A 中的静态成员变量,而不是:

  public void runEverySecond(Populator objPopulator) {
     float[] floatArray = objPopulator.getValues();
     history.put(historyCount, floatArray);
     historyCount++;
  }   

编辑 另外,我不知道您的 A 类代码将如何编译。 runEverySecond 不应该使用Populator 参数而不是Object 吗?参见上面修改过的 sn-p。

【讨论】:

  • 您好 milkplusvellocet,感谢您的回复。这不是实际代码,它只是真实事物的示例代码,感谢您指出我在 A 类中犯的错误 :),是的,您是正确的,它应该是 Populator 而不是 Object。无论如何,我尝试了您的建议,结果仍然相同:(。我只想知道如何维护生成值的历史记录。如果我在我的示例代码历史被正确记录,但仅适用于最后 2 代。我需要一种方法来存储所有代 :)
  • 我刚刚尝试过,它完全按预期工作。您能否发布实际代码,包括您在我回答后所做的更改?然后我们可以为您提供更多帮助。
  • 请看一下上面的实际代码。感谢您的帮助
  • 您还没有实现我最初建议的更改。而不是marioFloatPosMySuperAgent 的静态成员变量,您应该在integrateObservation 方法中将其声明为局部变量。所以这条线是float[] marioFloatPos = environment.getMarioFloatPos();
  • 我尝试了完全相同的事情..以前存储在地图中的值都更改为最后一个插入地图的值。很抱歉没有发布您的更改,我认为这会让新读者感到困惑。
【解决方案2】:

只有一个floatArray,你不断地重新分配它。

这段代码几乎不可能以合理的方式遵循——真是一团糟。

【讨论】:

  • 嗨 Dave Newton,感谢您的回复,我知道代码是一团糟,但这只是代表真实代码的示例,更加混乱:D.. 不幸的是,我不允许修改我不负责的类:(。我只负责 A 类,我不能拥有多个 floatArray :(。无论如何我可以存储 Populator 类的所有输出的历史记录吗?
  • @Pazuzu 你需要更具体——如果你调用的代码实际上返回一个新数组,使用本地就可以了。跨度>
  • 我调用的代码没有返回一个新的数组,它只是修改了数组以前的值。是不是因为这个原因,HashMap 中之前的值发生了变化?
  • @Pazuzu 如果它没有创建一个新数组,那么你需要将它复制到一个新数组中。如果你说的是真的,那么这个问题有点误导,因为它显示了你正在调用的代码来创建一个新数组。
  • 抱歉代码中的错误。我现在已经纠正了它们。我试过你的建议,现在效果很好:D..谢谢你,你真棒:)
猜你喜欢
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多