当前位置: 首页 > 知识库问答 >
问题:

用于数据存储的Java静态变量与本地变量

彭畅
2023-03-14

我用动物代替了我真正的代码,所以这可能看起来有点傻,但这是一个真正的问题。

我的java程序得到一个不同动物的列表,一次遍历一个动物,对每个动物做以下事情:动物被创建,动物做一些随机运动,每个运动被计数,然后程序收集运动数据,做一些分析,并继续到列表中的下一个动物。

我有一个抽象的动物类,由不同的动物对象扩展,狗,猫等等。每个都有自己的动作。在基础动物类中,有一个散列表计算动物的随机运动。

updateMap接收移动字符串键作为输入,然后检查给定的移动是否作为键在HashMap中,如果不是,它将移动添加为键,值为1。如果移动已经是HashMap中的键,它将增加数字值。

当前的设置是HashMap在Animal类中,所以每个动物都有自己的HashMap。我的问题是,用静态updateMap方法将HashMap作为静态变量移动到一个单独的实用程序类中,会违反Java最佳实践吗?当我需要运动数据时,我必须添加一个getter方法来调用,并添加一个方法来清除将在Animal构造函数中调用的map。动物一次迭代一个,并且只迭代一次,所以更新不会有冲突。

我想创建静态实用程序类的原因是我希望它能提高性能。动物列表有数百万个项目,我想如果每个项目都不需要用这个HashMap作为类变量来创建,我可以加快一点速度(即使它几乎不引人注目)。但是我不知道对静态方法的调用是否会减慢它。如果你知道一个更好的(性能方面的)设计来跟踪运动,我将不胜感激。

伪代码:

当前:

动物.java

 public abstract class Animal {
      private HashMap counter;

      public Animal(String input){
           counter = new HashMap();
           .
           .
      }

      protected void updateMap(String key){
           if(counter.contains(key)){
                counter.update(key, counter.get(key)+1);
           } else {
                counter.add(key, 1);
           }
      }

      protected void analyze(){
           some code using counter;
      }
 }

狗.java

 public class Dog extends Animal {

      public Dog(String input){
           super(input);
      }

      private void jump(){
           .
           .
           updateMap("jump");
      }

      private void run(){
           .
           .
           updateMap("run");
      }

      private void dance(){
           .
           .
           updateMap("dance");
      }

改变:

动物.java

 public abstract class Animal {

      public Animal(String input){
           AnimalUtil.clearCounter();
           .
           .
      }

      protected void analyze(){
           HashMap count = AnimalUtil.getCounter();
           some code using counter;
      }
 }

狗.java

 public class Dog extends Animal {

      public Dog(String input){
           super(input);
      }

      private void jump(){
           .
           .
           AnimalUtil.updateMap("jump");
      }

      private void run(){
           .
           .
           AnimalUtil.updateMap("run");
      }

      private void dance(){
           .
           .
           AnimalUtil.updateMap("dance");
      }
 }

动物玩具.java

 public class AnimalUtil {
      private static HashMap counter;

      public static void updateMap(String key){
           if(counter.contains(key)){
                counter.update(key, counter.get(key)+1);
           } else {
                counter.add(key, 1);
           }
      }

      public static HashMap getCounter(){
           return counter;
      }

      public static void clearCounter(){
           counter = new HashMap();
      }
 }

谢谢。

共有2个答案

荣晨朗
2023-03-14

问题是,大多数时候,当你创建一个实用程序类时,是因为你不知道里面的代码的责任。根据《清洁代码》,所有语言的最佳实践是,你编写的每一个代码都有自己的领域和自己的责任。因此,将您要全局使用的HashMap放在一个负责计数和观察不同动物运动的类中。这就是我的建议。

陆俊捷
2023-03-14

有一个问题要问你自己:每个动物都有自己的HashMap有意义吗?听起来答案是否定的,因为这是“共享的”数据,是“全球性的”。

将其设置为静态变量是合理的。我建议也考虑其他选择。例如,听起来哈希地图存储有关动物所居住世界的信息。因此,也许这个变量属于另一个类,世界农场,而不是动物类。

 类似资料:
  • 问题内容: 我已经定义了一个对象并声明了一个静态变量。在该方法中,当我尝试打印实例和类变量时,两者都打印相同的值。 不是实例变量吗?它应该打印0而不是50吗? 问题答案: 不,只有一个变量-您尚未声明任何实例变量。 不幸的是,Java允许您访问静态成员,就像通过相关类型的引用访问静态成员一样。这是IMO的设计缺陷,某些IDE(例如Eclipse)允许您将其标记为警告或错误- 但这是语言的一部分。您

  • 问题内容: 通常,最终静态成员,尤其是变量(或静态最终变量,当然可以以任何顺序使用,而不会重叠含义)已广泛用于Java接口中,以定义实现类的 协议行为 ,这意味着实现该类的类(继承)接口必须包含该接口的所有成员。 我无法区分 final 和 final静态 成员。final静态成员是一个声明为final或其他东西的静态成员?在哪些特定情况下应专门使用它们? 永远不能在方法内部,静态方法内部或实例方

  • 问题内容: 例如: 这些变量将在Java,堆或堆栈存储器中存储在哪里?它们如何存储? 问题答案: 静态方法(实际上是所有方法)以及静态变量都存储在PermGen堆的部分中,因为它们是反射数据(与类相关的数据,而不与实例相关的数据)的一部分。 更新说明: 请注意,只有变量及其技术值(原始或引用)存储在空间中。 如果你的静态变量是对对象的引用,则对象本身存储在堆的常规部分(青年/旧世代或幸存者空间)中

  • 问题内容: 我有一个带有静态实例的android java类,其中包含一个用户信息。但是,在极少数情况下,当用户使用我的应用程序时,该静态实例中的变量之一会在一段时间后变为null。该Java类是全局的(未附加到任何活动)。是什么原因造成的? 编辑:该变量永远不会更改,除非在应用程序启动期间。我已经检查过调用它的函数永远不会被调用一次以上(adb logcat证明了当我添加一条日志表明正在被调用时

  • 问题内容: 根据Java,静态变量可以通过类名访问,但是即使Java不建议使用静态变量,类对象也可以访问它们,并且给出相同的答案。 我知道该变量只有一个副本,并且所有对象和其他事物的值都相同。Java为什么建议使用类名而不是类对象? 问题答案: 因为可能会造成混淆!静态成员上没有动态调度。 看一下这个令人困惑的代码:(可能是语法错误;我的Java生锈了) 看起来很混乱,因为方法似乎是多态的,所以输

  • 静态变量和实例变量之间的区别是什么。下面这句话是我无法理解的: 在某些情况下,一个类的所有对象只能共享一个特定变量的副本——这里使用静态变量。 静态变量代表类范围的信息。一个类的所有对象共享相同的数据。 我认为实例变量在类范围内使用,而静态变量只在它们自己的方法中有作用域?