【问题标题】:List of Integers into byte array将整数列表转换为字节数组
【发布时间】:2014-10-17 02:55:39
【问题描述】:

我有一个大尺寸(3912984 或更大)的 LinkedList ,我想将这些元素复制到一个字节数组中。整数是 0 或 1,所以我不需要改变数组的大小,我只想一个一个地复制元素,它们是怎样的。当然,我知道最简单的方法是:

 for(int i = 0; i < list.size(); i++)      
 array[i] = (byte)(int) list.get(i);

但是这种方法太慢了,我的程序没有在几个小时前结束!你能知道另一种方式(更快,比如 .NET 的 Buffer.BlockCopy())还是我必须更改数据结构?

【问题讨论】:

    标签: java arrays list integer bytearray


    【解决方案1】:

    使用 Java 8 的另一种方法:

    List<Integer> enteros = Stream.of(1, 2, 3, 4, 5).collect(Collectors.toList());
    Byte[] bytes = enteros.stream().map(entero -> entero.byteValue()).toArray(Byte[]::new);
    

    这是另一个测试转换时间的复杂示例:

    List<Integer> enteros = new LinkedList<>();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    
    System.out.println("Init list: " + LocalTime.now().format(formatter));
    // Fill array with 0 and 1
    for(int i = 0; i < 9999999; i++) enteros.add(ThreadLocalRandom.current().nextInt(0, 2));
    System.out.println("List complete: " + LocalTime.now().format(formatter));
    
    System.out.println("Init list convert: " + LocalTime.now().format(formatter));
    Byte[] bytes = enteros.stream().map(entero -> entero.byteValue()).toArray(Byte[]::new);
    System.out.println("End convert! " + LocalTime.now().format(formatter));
    

    【讨论】:

      【解决方案2】:
      // example input list
      List<Integer> list = new LinkedList<Integer>();
      list.add(1);
      list.add(0);
      list.add(1);
      list.add(0);
      list.add(1);
      list.add(1);
      
      // write to byte array
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      DataOutputStream out = new DataOutputStream(baos);
      for (int element : list) {
          out.writeUTF(Integer.toString(element));
      }
      byte[] bytes = baos.toByteArray();
      
      // read from byte array
      ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
      DataInputStream in = new DataInputStream(bais);
      while (in.available() > 0) {
          String element = in.readUTF();
          System.out.println(element);
      }
      

      【讨论】:

      • 这不是所要求的 - 它不会保留字节原样,而是将它们转换为 ASCII。
      【解决方案3】:

      Number 类中有可用的 byteValue() 方法。数字扩展为 Integer、Double、Float 等。

      List<Integer> list = getNumbers();
      
      Iterator<Integer> iterator = list.iterator();
      
      while(iterator.hasNext())
      {
         Integer i = iterator.next()
         byteArray[index] = i.byteValue();
      }
      

      您也可以使用java.nio.MappedByteBuffer 类进行块复制。见http://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html

      MappedByteBuffer 等价于 .NET 中的 Buffer.BlockCopy()

      【讨论】:

      • @Fabrizio,影响性能的一个因素是list.get(index)LinkedList 的线性时间运算。鉴于您正在遍历整个列表,这会使您的算法写成二次方。如果您在这里使用 D Luffy 先生的方法,使用迭代器,它将变得整体线性并且快得多
      • @msandiford 对于 java 中的每个循环都在内部使用迭代器,对吗?它需要实现可迭代接口来迭代每个循环。我不确定。
      • @MonkeyDLuffy 是的,foreach 循环使用了一个迭代器。
      猜你喜欢
      • 2015-12-06
      • 2018-11-19
      • 1970-01-01
      • 1970-01-01
      • 2011-03-11
      • 2010-12-28
      • 1970-01-01
      相关资源
      最近更新 更多