Copying a part of the segment into another segment (2)
Let’s consider the srcSegment (1, 2, 3, 4, -1, -1, -1, 52, 22, 33, -1, -1, -1, -1, -1, 4) and the dstSegment (0, 0, 0, 0, 0, 0, 0, 0, 10, 44, 2, 6, 55, 65, 7, 89) from the previous sections. We want to copy the last 8 elements from srcSegment as the first 8 elements from dstSegment (22, 33, -1, -1, -1, -1, -1, 4, 10, 44, 2, 6, 55, 65, 7, 89). We know that this can be done via copy(MemorySegment srcSegment, long srcOffset, MemorySegment dstSegment, long dstOffset, long bytes) as follows:
MemorySegment.copy(srcSegment, 32, dstSegment, 0, 32);
Alternatively, we can use copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset, MemorySegment dstSegment, ValueLayout dstElementLayout, long dstOffset, long elementCount) as in the following figure:

Figure 7.23 – Copying a part of a segment into another segment (2)
So, we specify the source segment as srcSegment, the source layout as JAVA_INT, the source offset as 32 (skip the first 8 elements), the destination segment as dstSegment, the destination layout as JAVA_INT, the destination offset as 0, and the number of elements to be copied as 8:
MemorySegment.copy(srcSegment, ValueLayout.JAVA_INT,
32, dstSegment, ValueLayout.JAVA_INT, 0, 8);
Feel free to test this method with different value layouts. Next, let’s talk about slicing.
Slicing a segment
Next, let’s suppose that we want to slice the segment containing (1, 2, 3, 4, -1, -1, -1, 52, 22, 33, -1, -1, -1, -1, -1, 4) into three separate IntVector instances the values that are not -1 without using the copy() methods. So, v1 should contain [1, 2, 3, 4], v2 should contain [52, 22, 33, 0], and v3 should contain [4, 0, 0, 0]. Since an int needs 4 bytes, and we have a maximum of 4 int values we go for SPECIES_128 (4 int values x 4 bytes = 16 bytes x 8 bits = 128 bits):
VectorSpecies<Integer> VS128 = IntVector.SPECIES_128;
Next, we need to slice the memory segment in order to eliminate the values of -1. This can be accomplished via the asSlice(long offset) and asSlice(long offset, long newSize) methods. The first argument represents the starting offset. The second argument represents the size of the new memory segment. The following figure helps us to clear this up:

Figure 7.24 – Slicing a memory segment
The first memory segment starts at offset 0 and ends at offset 16, so it contains 4 int values of 4 bytes (asSlice(0, 16)). The second memory segment starts at offset 28 and ends at offset 40, so it contains 3 int values of 4 bytes (asSlice(28, 12)). Finally, the third memory segment starts at offset 60 and ends at the end of the segment, so it contains a single int value of 4 bytes (asSlice(60) or asSlice(60, 4)). The resulting code is listed here:
IntVector v1, v2, v3;
try (Arena arena = Arena.openConfined()) {
MemorySegment srcSegment = arena.allocateArray(
ValueLayout.JAVA_INT, 1, 2, 3, 4, -1, -1, -1, 52, 22, 33,
-1, -1, -1, -1, -1, 4);
v1 = IntVector.fromMemorySegment(VS128,
srcSegment.asSlice(0, 16), 0, ByteOrder.nativeOrder());
v2 = IntVector.fromMemorySegment(VS128,
srcSegment.asSlice(28, 12), 0L, ByteOrder.nativeOrder(),
VS128.indexInRange(0, 3));
v3 = IntVector.fromMemorySegment(VS128,
srcSegment.asSlice(60), 0, ByteOrder.nativeOrder(),
VS128.indexInRange(0, 1));
}
Done! Of course, we can slice a memory segment in regular Java arrays as well. Here you go:
int[] jv1, jv2, jv3;
try (Arena arena = Arena.openConfined()) {
MemorySegment srcSegment = arena.allocateArray(
ValueLayout.JAVA_INT, 1, 2, 3, 4, -1, -1, -1, 52, 22, 33,
-1, -1, -1, -1, -1, 4);
jv1 = srcSegment
.asSlice(0, 16).toArray(ValueLayout.JAVA_INT);
jv2 = srcSegment
.asSlice(28, 12).toArray(ValueLayout.JAVA_INT);
jv3 = srcSegment
.asSlice(60).toArray(ValueLayout.JAVA_INT);
}
The toArray() method returns a Java regular array (here, int[]) from the sliced memory segment.
Using asOverlappingSlice()
The asOverlappingSlice(MemorySegment other) method returns a slice of this segment that overlaps the given segment as an Optional<MemorySegment>. Consider the following segment (arena is an instance of Arena):
MemorySegment segment = arena.allocateArray(
ValueLayout.JAVA_INT, new int[]{1, 2, 3, 4, 6, 8, 4, 5, 3});
And, we slice it at offset 12, so at value 4:
MemorySegment subsegment = segment.asSlice(12);
Finally, we call asOverlappingSlice() to see where the overlapping occurs:
int[] subarray = segment.asOverlappingSlice(subsegment)
.orElse(MemorySegment.NULL).toArray(ValueLayout.JAVA_INT);
The resulted array is [4, 6, 8, 4, 5, 3].
Using segmentOffset()
The segmentOffset(MemorySegment other) returns the offset of the given segment (other) relative to this segment. Consider the following segment (arena is an instance of Arena):
MemorySegment segment = arena.allocateArray(
ValueLayout.JAVA_INT, new int[]{1, 2, 3, 4, 6, 8, 4, 5, 3});
And, we slice it at offset 16, so at value 6:
MemorySegment subsegment = segment.asSlice(16);
Next, we call segmentOffset() to find out at what offset in segment we have subsegment:
// 16
long offset = segment.segmentOffset(subsegment);
// 6
segment.get(ValueLayout.JAVA_INT, offset)
You can practice all these examples in the bundled code. Challenge yourself to explore further MemorySegment.mismatch().