使用Java

时间:2018-05-20 14:13:53

标签: java arrays casting byte java-stream

嘿我正在使用Paho mqtt的应用程序

现在我试图将几个对象的内容转换为字节数组,以便将它们发送给代理。有几个不同的对象都遵循抽象类,但我开始使用的对象包含double []

这是我尝试实施的功能:

    @Override
public byte[] getBytes() {

    return Arrays.stream(driveVector).map(d -> Double.valueOf(d).byteValue()).toArray();
}

我认为这会有效,但我收到的错误是返回值为double []

我想我要么不理解地图方法,要么我总是对这一切都做错(我看过ByteBuffer类,但用它来实现它似乎很痛苦)< / p>

提前致谢

4 个答案:

答案 0 :(得分:2)

您无法将double[]转换为byte[],因为它们是不相关类型的基本原因,您只能在相关类型之间进行转换。

用Java编译,与C ++不同,实际上并没有创建一个新对象:它们只是编译器的一种方式“我比你更了解这个对象的类型;相信我。”例如,您可能知道Object类型的变量实际上包含对String的引用,这是编译器无法知道的;在这种情况下,您可以投射参考。

但是,您可以构建一个新数组:

byte[] output = new byte[input.length];
for (int j = 0; j < input.length; j++) {
  output[j] = (byte) input[j];
}

使用流无法做到这一点。或者更确切地说,您可以将此代码强制转换为Stream<double[]>上的流操作,比如说;但涉及这样的流明显没有任何好处。

答案 1 :(得分:1)

您可以使用ByteBuffer:

double[] doubles = new double[] {1,2,3,4,5};
ByteBuffer buffer = ByteBuffer.allocate(doubles.length * Double.BYTES);
Arrays.stream(doubles).forEach(buffer::putDouble);
buffer.array();

答案 2 :(得分:0)

Java Streams不是正确的工具,尤其是Java,因为Java中没有ByteStream

您的方法可以实现为简单的for循环。

@Override
public byte[] getBytes() {
    byte[] arr = new byte[driveVector.length];
    for (int i = 0; i < arr.length; i++)
        arr[i] = (byte) driveVector[i];
    return arr;
}

答案 3 :(得分:0)

在我的MQTT应用程序中,我读取了一个double值并将其发布到代理。但是,单个和双数组之间没有真正的区别。客户端需要知道数组长度,而使用单个值时,它总是知道有一个。

我确信您可以调整我的代码来编写多个值,调整toMessage来编写多个double值。

public abstract class SensorMonitor {
  protected final MqttAsyncClient client;
  protected final String topic;
  protected final Logger logger = Logger.getLogger(getClass().getName()); 
  private final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(8);
  private final DataOutputStream dataOut = new DataOutputStream(byteOut);

  public SensorMonitor(MqttAsyncClient mqttClient, String topic) {
    this.client = mqttClient;
    this.topic = topic;
  }

  public void start(ScheduledExecutorService service) {
    service.scheduleWithFixedDelay(this::publish, 0, 30, TimeUnit.SECONDS);
  }

  protected void publish() {
    try {
        MqttMessage message = toMessage(readNewValue());
        client.publish(topic, message);

    } catch (MqttException | IOException e) {
        logger.log(Level.SEVERE, "Could not publish message", e);
    }
  }

  private MqttMessage toMessage(double value) throws IOException {
    byteOut.reset();
    dataOut.writeDouble(value);
    return new MqttMessage(byteOut.toByteArray());
  }

  protected abstract double readNewValue();
}

DataOutputStream.writeDouble使用Double.doubleToLongBits创建IEEE 754浮点&#34;双重格式&#34;位布局。

在我的情况下,我可以预先分配和重用byteOut输出流,因为我事先知道byte[]所需的大小。