Buffer details

A Buffer consists of data and four indexes to access and manipulate this data efficiently: mark, position, limit and capacity. There are methods to set and reset these indexes and to query their value.

capacity( )

Returns the buffers capacity

clear( )

Clears the buffer, sets the position to zero, and limit to capacity. You call this method to overwrite an existing buffer.

flip( )

Sets limit to position and position to zero. This method is used to prepare the buffer for a read after data has been written into it.

limit( )

Returns the value of limit.

limit(int lim)

Sets the value of limit.

mark( )

Sets mark at position.

position( )

Returns the value of position.

position(int pos)

Sets the value of position.

remaining( )

Returns (limit - position).

hasRemaining( )

Returns true if there are any elements between position and limit.

Methods that insert and extract data from the buffer update these indexes to reflect the changes.

This example uses a very simple algorithm (swapping adjacent characters) to scramble and unscramble characters in a CharBuffer:

Although you could produce a CharBuffer directly by calling wrap( ) with a char array, an underlying ByteBuffer is allocated instead, and a CharBuffer is produced as a view on the ByteBuffer. This emphasizes that fact that the goal is always to manipulate a ByteBuffer, since that is what interacts with a channel.

Heres what the buffer looks like after the put( ):

The position points to the first element in the buffer, and the capacity and limit point to the last element.

In symmetricScramble( ), the while loop iterates until position is equivalent to limit. The position of the buffer changes when a relative get( ) or put( ) function is called on it. You can also call absolute get( ) and put( ) methods that include an index argument, which is the location where the get( ) or put( ) takes place. These methods do not modify the value of the buffers position.

When the control enters the while loop, the value of mark is set using mark( ) call. The state of the buffer then:

The two relative get( ) calls save the value of the first two characters in variables c1 and c2. After these two calls, the buffer looks like this:

To perform the swap, we need to write c2 at position = 0 and c1 at position = 1. We can either use the absolute put method to achieve this, or set the value of position to mark, which is what reset( ) does:

The two put( ) methods write c2 and then c1:

During the next iteration of the loop, mark is set to the current value of position:

The process continues until the entire buffer is traversed. At the end of the while loop, position is at the end of the buffer. If you print the buffer, only the characters between the position and limit are printed. Thus, if you want to show the entire contents of the buffer you must set position to the start of the buffer using rewind( ). Here is the state of buffer after the rewind( ) call (the value of mark becomes undefined):

When the function symmetricScramble( ) is called again, the CharBuffer undergoes the same process and is restored to its original state.