首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java :无法将新值存储到数组中

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

Stack Overflow用户
提问于 2015-07-09 17:10:19
回答 2查看 985关注 0票数 1

我从无人机那里得到电池值。我能够在JLabel上显示新的电池值。但是,当我试图将这些电池值存储到int数组中时,它只是存储数组上的第一个电池值。随后的数组值将只填充第一个电池值。

我展示了一个输出,这样您就可以了解正在发生的事情了。第一个值来自无人驾驶飞机,而第二个值表示数组索引。输出清楚地显示,由于未知的原因,数组不能接受新的数据。

P/S:我不知道什么是最好的数组大小,因为我每秒钟都会从无人机那里得到值。所以我已经声明了一个大小为9999999的int数组。我怎样才能设置一个阵列的最大大小,以满足从无人机获得连续电池值的需要?这些值稍后将用于绘制图形。

我的代码:

代码语言:javascript
复制
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);
              }
      });
   }

结果:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2015-07-09 17:35:53

问题在于这个方法:

代码语言:javascript
复制
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实例来调用该方法。这意味着,无论ndnd.getBattery()包含什么值,都将分配给数组中的每个索引,因为循环在电池数组上进行交互。

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

边解

声明这个数组的方式是,非常可怕的。你应该只使用你需要的空间,而不是更多。我知道你不知道实际需要多大的尺寸,但不要太过分。

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

代码语言:javascript
复制
public int [] arrayBatt = new int[10000];

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

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

这种方法的缺点是,随着数组变得更大,您将花费大量时间将旧数组复制到新数组,这是非常不可取的。

一个更好的解决方案

就是使用内置的ArrayList库,然后将项添加到列表中,让Java来做繁重的工作。

代码语言:javascript
复制
ArrayList<Integer> batteryArray = new ArrayList <Integer>();

只需调用以下命令即可将项添加到列表中:

代码语言:javascript
复制
batteryArray.add(item);

这一解决办法的好处是:

  1. batteryArray大小是在幕后处理的。
  2. 数组的大小以及元素都很容易检索。
  3. ArrayList是一种非常快速的存储结构。

在您的循环打印电池值,您可以使它更干净,通过实现一个for-每个循环。

  • 你为什么要用System.err打印电池的对话框?这不是System.err应该用于的,也不是违反最小惊讶原则的 getNavData(NavData nd){ for (int batteryValue : arrayBatt){ arrayBatti = nd.getBattery();System.err.println(“这是存储的电池值:”+ arrayBatti +“+i+”);} }
票数 1
EN

Stack Overflow用户

发布于 2015-07-09 18:20:58

我认为无人机的硬件引发了某种事件。您的循环运行太快,可能是每秒数千次,因此没有时间进行任何电池的更改,并且nd.getBattery()返回相同的值。

似乎这就是为什么这些值被重复的原因。

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

只有在收到有关更改的通知时,才应存储值。

我认为getNavData的实现是根本错误的。

在这种情况下,您的1000万int数组是无用的。

我不知道您的应用程序如何与无人机的硬件交互,但是接口名称DroneStatusChangeListenerNavDataListener建议您在发生更改时收到一些通知。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31324063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档