使用String.valueOf或Float.toString时,为什么这个循环变得无限?

时间:2014-04-06 22:03:05

标签: java string floating-point infinite-loop

我使用FileInputStream从文件中读取字节数。代码(格式正确)如下:

String s = "";
try {
        File file = new File(...);
        FileInputStream file_input = new FileInputStream(file);
        DataInputStream data_in = new DataInputStream(file_input );

        while (true) {
            try {
                for (int index = 0; index < 4; index++) {
                    byteArray[index] = data_in.readByte();
                }         
            } catch (EOFException eof) {
                break;
            }

            float f = readFloatLittleEndian(byteArray); // transforms 4 bytes into a float
            //s += Float.toString(f); <- here's the problem 
        }
        data_in.close();
    } catch (IOException e) {
        System.err.println(e.toString());
    }
}
System.out.print(s);

如果我按原样运行此代码,则在读取所有文件并将每组4 bytes转换为float时,循环结束。

但是,如果我取消注释该行,文件永远不会完成,并且似乎一遍又一遍地遍历文件。此外,打印f(不使用Float.toStringString.valueOf)也不会将其转换为无限循环。

1 个答案:

答案 0 :(得分:1)

循环不会变得无限 - 只是非常低效。 += java.lang.String的问题在于它产生了一个新的不可变对象,丢弃了它之前持有的对象。每次复制时,根据文件中的条目数使该过程成为O(n 2 )。

此修复很简单 - 将String s替换为StringBuilder s,并使用append代替+=

StringBuilder s = new StringBuilder();
try {
    File file = new File(...);
    FileInputStream file_input = new FileInputStream(file);
    DataInputStream data_in = new DataInputStream(file_input );
    while (true) {
        try {
            for (int index = 0; index < 4; index++) {
                byteArray[index] = data_in.readByte();
            }         
        } catch (EOFException eof) {
            break;
        }
        float f = readFloatLittleEndian(byteArray); // transforms 4 bytes into a float
        s.append(f); 
    }
    data_in.close();
} catch (IOException e) {
    System.err.println(e.toString());
}
System.out.print(s);