For my own purposes, I still had to implement a wrapper class for the existing BitSet class. I would also like to note that the .length() and .toByteArray() methods (as well as the opposite method for converting ByteArray to BitSet) work quite adequately. The least significant bit to which BitSet assigns an index of 0 corresponds to the least significant bit in the byte that is the “rightmost”. I already needed to move away from the standard recording.
And here is the same class:
public class MyBitSet { public MyBitSet(BitSet bs, int length) { bitset = bs; this.bitLength = length; } BitSet bitset; private int bitLength; // количество полезных бит private int bitcount; // счётчик бит для временного байта. Используется для сдвига private int tmpByte; // буфферный байт private ByteArrayOutputStream baos; private ByteArrayInputStream bais; public long getBitLength() { return this.bitLength; } public MyBitSet getSubBitSet(int start, int end) { MyBitSet mbs = new MyBitSet(end - start); for(int i = start, j = 0; i < end; i++) { mbs.bitset.set(j, this.bitset.get(i)); } return mbs; } public MyBitSet(String filename) { bais = null; FileInputStream fis = null; try { File f = new File(filename); fis = new FileInputStream(f); byte[] byteFile; byteFile = new byte[(int) f.length()]; fis.read(byteFile, 0, (int) f.length()); this.bitset = new BitSet((int) f.length()); for (int i = 0; i < byteFile.length; i++) { byte b = byteFile[i]; for (int j = 0; j < 8; j++) { bitset.set(i*8 + j, getBit(b, 7 - j)); } } } catch (FileNotFoundException ex) { Logger.getLogger(MyBitSet.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(MyBitSet.class.getName()).log(Level.SEVERE, null, ex); } finally { if(fis != null){ try { fis.close(); } catch (IOException ex) { Logger.getLogger(MyBitSet.class.getName()).log(Level.SEVERE, null, ex); } } } } @Override public int hashCode() { return this.bitset.hashCode(); } @Override public boolean equals(Object obj) { if (!(obj instanceof MyBitSet)) { return false; } if (this == obj) { return true; } MyBitSet set = (MyBitSet) obj; if (this.bitset.equals(set.bitset) && this.bitLength == set.bitLength) { return true; } else { return false; } } public void concatenate(BitSet bs, int length) { for (int i = 0; i < length; i++, bitLength++, bitcount--) { int myInt = (bs.get(i)) ? 1 : 0; // true = 1, false = 0 tmpByte |= (myInt << (bitcount)); if (bitcount == 0) { bitcount = 8; baos.write(tmpByte); tmpByte = 0; } } } void writeToFile(String filename) { if (bitcount != 7) { baos.write(tmpByte);//добавить последние биты, оставшиеся во временном байте } OutputStream outputStream = null; try { outputStream = new FileOutputStream(filename); baos.writeTo(outputStream); } catch (FileNotFoundException ex) { Logger.getLogger(MyBitSet.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(MyBitSet.class.getName()).log(Level.SEVERE, null, ex); } finally { if (outputStream != null) { try { outputStream.flush(); outputStream.close(); } catch (IOException ex) { Logger.getLogger(MyBitSet.class.getName()).log(Level.SEVERE, null, ex); } } } } byte[] getByteArray() { if (bitcount != 7) { baos.write(tmpByte);//добавить последние биты, оставшиеся во временном байте } return baos.toByteArray(); } public MyBitSet() { bitLength = 0; bitcount = 7; baos = new ByteArrayOutputStream(); } public MyBitSet(int bitSetLength) { this.bitset = new BitSet(bitSetLength); this.bitLength = bitSetLength; } private static boolean getBit(byte b, int i) { return ((b >> i) & 1) == 1; } }