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) 编辑 收藏 举报