Java数组:无法将新值存储到数组

时间:2015-07-09 17:10:19

标签: java arrays oop

我从无人机获得电池值。我可以在JLabel上显示新的电池值。但是,当我尝试将这些电池值存储到int数组中时,它只存储阵列上的第一个电池值。后续数组值仅填充第一个电池值。

我会显示一个输出,以便您了解正在发生的事情。第一个值来自无人机而第二个值表示数组索引。输出清楚地表明阵列不能接受新数据,原因不明。

P / S:我不知道阵列的最佳尺寸是什么,因为我每秒都从无人机获取值。所以我已经声明了一个大小为9999999的int数组。任何想法如何设置一个数组到它的最大大小,以满足从无人机获得连续电池值的需要?这些值稍后用于绘制图形。

我的代码:

public class arDroneFrame extends javax.swing.JFrame implements Runnable, DroneStatusChangeListener, NavDataListener {

      private String text; // string for speech
      private static final long CONNECT_TIMEOUT = 10000;
      public ARDrone drone;
      public NavData data;
      public Timer timer = new Timer();
      public int batteryGraphic=0;
      public int [] arrayBatt = new int[9999999];

      public arDroneFrame(String text) {
          this.text=text;          
      }

      public arDroneFrame() {
         initComponents();             
         initDrone();       
      }

      private void initDrone() {
        try {
          drone = new ARDrone();
          data = new NavData();          
        } catch (UnknownHostException ex) {
        return;     
      } 
        videoDrone.setDrone(drone);        
        drone.addNavDataListener(this);
}

     public void navDataReceived(NavData nd) { 
         getNavData(nd);    
         int battery = nd.getBattery();  
         cmdListOK.jlblBatteryLevelValue.setText(battery + " %"); 
         //JLabel can get updated & always display new battery values 
      }

     public void getNavData(NavData nd){
          for(int i=0;i<arrayBatt.length;i++){
              batteryGraphic= nd.getBattery();
              arrayBatt[i] = batteryGraphic;
              System.err.println("This is stored battery values : " + arrayBatt[i] + "   " + i + "\n");
          }
     }
}

     public static void main(String args[]) {
          java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {

              String text = "Welcome!";
              arDroneFrame freeTTS = new arDroneFrame(text);
              freeTTS.speak();

              new arDroneFrame().setVisible(true);
              }
      });
   }

结果:

This is stored battery values : 39   0

This is stored battery values : 39   1

This is stored battery values : 39   2

This is stored battery values : 39   3

This is stored battery values : 39   4

This is stored battery values : 39   5

2 个答案:

答案 0 :(得分:1)

问题在于此方法:

public void getNavData(NavData nd){
      for (int batteryValue : arrayBatt){
           arrayBatt[i] = nd.getBattery();
               System.err.println("This is stored battery values : " + arrayBatt[i] + "   " + i + "\n");
      }
   }

通过传递NavData实例来调用此方法。这意味着无论nd包含nd.getBattery()的值,都会被分配给数组中的每个索引,因为循环会在电池阵列上进行交互。

你应该做的是将循环移到getNavData(NavData nd)方法之外,并为每个调用传递一个NavData的新实例。当您将此与以下ArrayList建议结合使用时,您应该拥有一组不同的电池值动态

旁边解决方案

您声明此数组的方式是真正的SCARY 。 你应该只使用你需要的空间而不是更多。 我知道你不确定实际需要什么尺寸,但不要过度使用它。

你应该用更小的东西初始化你的数组;

public int [] arrayBatt = new int[10000];

作为旁注:通常不建议将您的班级成员公开。您应该将它们设为私有,并分别创建getter / setter方法来检索和修改数据。

然后,有一个方法来检查您的阵列是否已满。如果已满,则将数组大小增加n/2,其中n是数组的初始大小。

这种方法的缺点是,随着阵列变大,您将花费大量时间将旧阵列复制到新阵列,这是非常不受欢迎的。

更好的解决方案

将使用内置的ArrayList库,然后只需将项目附加到列表中,让Java完成繁重的任务。

ArrayList<Integer> batteryArray = new ArrayList <Integer>();

只需致电:

即可将项目添加到列表中
batteryArray.add(item);

这个解决方案的好处是:

  1. 电池阵列尺寸在幕后处理
  2. 可以轻松检索数组的大小以及元素
  3. ArrayList是一种非常快速的存储结构。
  4. 在你的循环中打印出电池值,你可以通过实现for-each循环使它更清洁。

    • 为什么使用System.err打印出电池对话框?这不是System.err用于和违反Principle of Least Astonishment

      的内容
      public void getNavData(NavData nd){
        for (int batteryValue : arrayBatt){
            arrayBatt[i] = nd.getBattery();
            System.err.println("This is stored battery values : " + arrayBatt[i] + "   " + i + "\n");
        }
      

      }

答案 1 :(得分:0)

我认为有些事件是由无人机硬件触发的。 您的循环运行速度太快,可能每秒数千次,因此没有时间更换电池并且nd.getBattery()返回相同的值。

这似乎是重复这些值的原因。

另一方面,我怀疑只有在硬件检测到更改时才会调用navDataReceived,这就是显示新值的原因。当调用getNavData时,您正在运行一个紧密的循环来锁定执行并阻止您的应用程序在循环执行时接收此事件。

只有在收到某些更改通知时才应存储值。

我认为您getNavData的实施从根本上说是错误的。

在这种情况下,你的1000万个int数组是没用的。

我不知道您的应用程序如何与无人机的硬件进行交互,但界面名称DroneStatusChangeListenerNavDataListener表示您在发生更改时会收到一些通知。