簡體   English   中英

如何在Java中將布爾數組轉換為二進制,反之亦然?

[英]How to convert boolean array to binary and vice versa in Java?

在Java中向布局數據輸出(和輸入)的最有效方法是什么? 我打算用一個字符串,每個字符都是't'或'f'然后我想,為什么不減少8倍的空間?

注意

我實際上不知道哪個答案是更好的方法,我剛剛選擇了彼得,因為我理解它。 感謝兩位回答者!

假設你有一個布爾[]

boolean[] ar = {true,false,false,true,false,true,true,true,false,true,false,false,false,true,tr‌​ue};

並且您想將其寫入磁盤,而不關心它在內存中的實現方式。

public static void main(String... args) throws IOException {
    boolean[] ar = {true, false, false, true, false, true, true, true, false, true, false, false, false, true, true};

    FileOutputStream out = new FileOutputStream("test.dat");
    writeBooleans(out, ar);
    out.close();

    FileInputStream in = new FileInputStream("test.dat");
    boolean[] ar2 = new boolean[ar.length]; 
    readBooleans(in, ar2);
    in.close();

    System.out.println(Arrays.toString(ar));
    System.out.println(Arrays.toString(ar2));
    System.out.println("The file size was "+new File("test.dat").length()+" bytes.");
}

private static void writeBooleans(OutputStream out, boolean[] ar) throws IOException {
    for (int i = 0; i < ar.length; i += 8) {
        int b = 0;
        for (int j = Math.min(i + 7, ar.length-1); j >= i; j--) {
            b = (b << 1) | (ar[j] ? 1 : 0);
        }
        out.write(b);
    }
}

private static void readBooleans(InputStream in, boolean[] ar) throws IOException {
    for (int i = 0; i < ar.length; i += 8) {
        int b = in.read();
        if (b < 0) throw new EOFException();
        for (int j = i; j < i + 8 && j < ar.length; j++) {
            ar[j] = (b & 1) != 0;
            b >>>= 1;
        }
    }
}

版畫

[true, false, false, true, false, true, true, true, false, true, false, false, false, true, true]
[true, false, false, true, false, true, true, true, false, true, false, false, false, true, true]
The file size was 2 bytes.

但如果我看看文件實際有多大

$ ls -l test.dat
-rw-rw-r-- 1 peter peter 2 2012-02-19 14:04 test.dat
$ du -h test.dat 
4.0K    test.dat

它表示長度為2個字節,但使用的磁盤空間實際為4 KB。

注意:大約1分鍾的時間值與80 MB的SSD大致相同(昂貴的磁盤,更多用於硬盤驅動器)因此,如果你不認為使用它可以節省至少80 MB,你可能會浪費你的時間。 ;)


您可以使用BitSet,每個字符為16位,占用的空間可減少16倍。

新創造的,適合您。 我將把BooleanInputStream作為一個BooleanInputStream 請注意,第一位現在是文件中最右邊的(MSB)位(刪除Byte.SIZE - 1 -在其他字節順序的示例中,無論您喜歡什么)。 只需使用例如DataOutputStream來首先將文件的大小寫入文件。 10K應該是一個整數。

請注意,存儲10K元素的布爾數組是非常低效的內存,你當然應該使用BitSet (最后,需要BitSet )!

public final class BooleanOutputStream extends FilterOutputStream {

    private int bitIndex;
    private byte buffer;

    public BooleanOutputStream(final OutputStream out) {
        super(out);
    }

    public void writeBoolean(final boolean value) throws IOException {
        buffer ^= (value ? 1 : 0) << (Byte.SIZE - 1 - bitIndex++);
        if (bitIndex == Byte.SIZE) {
            write(buffer & 0xFF);
            buffer = 0;
            bitIndex = 0;
        }
    }

    /**
     * This is an encoder and does therefore not close the underlying stream.
     * Please close underlying stream separately.
     */
    public void close() throws IOException {
        if (bitIndex != 0) {
            out.write(buffer);
            buffer = 0;
            bitIndex = 0;
        }
    }
}

public class BooleanInputStream extends FilterInputStream {

    private int bitIndex;
    private byte buffer;

    public BooleanInputStream(final InputStream in) {
        super(in);
    }

    public boolean readBoolean() throws IOException {
        if (bitIndex == 0) {
            int b = read();
            if (b == -1) {
                throw new EOFException();
            }
            buffer = (byte) b;
        }

        boolean value = (buffer & (1 << (Byte.SIZE - 1 - bitIndex++))) != 0;
        if (bitIndex == Byte.SIZE) {
            bitIndex = 0;
        }
        return value;
    }

    /**
     * This is a decoder and therefore does not close the underlying stream.
     * Please close underlying stream separately.
     */    
    public void close() throws IOException {
        buffer = 0;
        bitIndex = 0;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM