java基础---->集合操作--->实例---->List集合的初始化

文章内容:最近使用LeapMotion进行软件开发时,使用到了java API---->List集合,使用过程中遇到了一些小bug,特写此博客记录相关心得。

程序编写背景:使用leapMotion提供的Frame类中的deserialize()函数将byte[]数组值反序列化成Frame对象,并存放至List<Frame>集合中。具体代码参见LeapMotionFrameFileOperation.java中的readFile()函数

javaAPI--->List相关:这个程序中使用到了List<Frame> 集合,下面是从整个程序中抽离出的和List相关的代码部分




List<Frame> frames=new LinkedList<Frame>();//用于存储从文件中序列化数据解析出来的Frame对象 。 。 。 Frame newFrame = new Frame(); System.out.println("下面进行反序列化..."); newFrame.deserialize(frameData); frames.add(newFrame); 。 。 。 return frames;

bug调试:最开始时,代码中是这样写的

      List<Frame> frames=null;
     这种情况下,执行到
      frames.add(newFrame);时就会抛出如下异常,
Exception in thread "main" java.lang.NullPointerException
	at LeapMotionFrameFileOperation.readFile(LeapMotionFrameFileOperation.java:190)
	at DisplayFileData.main(DisplayFileData.java:26)

     为了修复上述bug,将代码改为

      List<Frame> frames=new LinkedList<Frame>();//当然,这里不只这一种改法,可以使用List接口的任何一个实现类的构造函数来初始化List

     修改之后bug便不存在了。

附录:LeapMotionFrameFileOperation.java中的readFile()函数

/
     * @function read the frame data from the saved file
     * @编程思路 
     *         To read the frame data from the saved file,
     *      you can then read the first 4 bytes of the file to determine
     *       how much data to read to get an entire frame. 
     *         Simply repeat the process until you reach the end of the file.
     * @param path:String 待读取文件的绝对路径   如d:/LeapMotionData/FrameData/gesture1.txt 
     * @throws IOException */
    @SuppressWarnings("null")
    public List<Frame> readFile(String path) throws IOException{
        System.out.println("进入readFile()函数内部");
        List<Frame> frames=new LinkedList<Frame>();//用于存储从文件中序列化数据解析出来的Frame对象
        File file=new File(path);
        if(!file.exists()&&file.isFile()){
            System.out.println("相应的文件并不存在,请检查您给出的文件路径是否正确:"+path);
            return null;
        }else{//也就是相应文件一定存在的情况下
            System.out.println(path+"文件是存在的,下面准备对其进行反序列化...");
            Path filePath=Paths.get(path);
            byte[] data=Files.readAllBytes(filePath);//将文件中数据一次性读出到一个byte数组中,当文件过大时,要注意内存溢出问题
            System.out.println("将上述文件中的内容全部读出,并存放在一个byte[]数组中,数组长度="+data.length);
            System.out.print("byte[] data="+data+"\n");
            int c=0;//data:byte[]的数组下标,相当于文件指针的当前位置
            int f=0;
            int nextBlockSize=0;//表示接下来一帧数据的长度(单位为byte)
            if(data.length>4){//获得初始的serializedFrame.length:int
                /*原本存储序列化后的Frame数据时,为了将来进行反序列化也存储了每个序列化Frame数据帧的数据长度(单位为byte)
                 * 序列化帧数据长度是一个4 byte 的int值
                 * 所以反序列化时就要读取4 byte的二进制值,然后使用下面的方法将其转换成十进制数字
                 */
                nextBlockSize=(data[c++] & 0x000000ff) << 24 |
                              (data[c++] & 0x000000ff) << 16 |
                              (data[c++] & 0x000000ff) <<  8 |
                              (data[c++] & 0x000000ff);
                System.out.println("nextBlockSize="+nextBlockSize+"\tc="+c);
            }
            while (c + nextBlockSize <= data.length){
                  byte[] frameData = Arrays.copyOfRange(data, c, c + nextBlockSize);//取出一帧数据
                  System.out.println("frameData:byte[]   length="+frameData.length);
                  c += nextBlockSize;//使得数组下标编程下一帧数据  数据长度  位置
                  Frame newFrame = new Frame();
                  System.out.println("下面进行反序列化...");
                  newFrame.deserialize(frameData);//反序列化,有byte数组形式数据转化成Frame Object
                  System.out.println("反序列化成功,获得一个Frame对象,frame.isvalid()="+newFrame.isValid());
                  this.diaplayFrameInfo(newFrame);
                  System.out.println("将上述Frame对象存放到List<Frame>集合中..\nlist.size="+frames.size());
                  boolean flag=frames.add(newFrame);//将反序列化所得Frame对象添加到List<Frame>中
                  System.out.println("上述Frame对象已经被添加到List<Frame> frames集合中?"+flag+",frames.size="+frames.size());
                  if(data.length - c > 4){
                      nextBlockSize = (data[c++] & 0x000000ff) << 24 |
                                        (data[c++] & 0x000000ff) << 16 |
                                        (data[c++] & 0x000000ff) <<  8 |
                                        (data[c++] & 0x000000ff);  
                  }
                                                          
            }//end while
        }//end if..else..    
        return frames;
    }//end readFile()

 

posted on 2016-11-28 17:04  LXRM-JavaWeb、ML  阅读(266)  评论(0编辑  收藏  举报

导航