public void removeFromLastWhen(final Predicate<T> predicate) {
        Segment<T> lastSeg = getLast();
        while (true) {
            if (lastSeg == null) {
                this.firstOffset = this.size = 0;
                return;
            }
            int removed = lastSeg.removeFromLastWhen(predicate);
            if (removed == 0) {
                break;
            }
            this.size -= removed;
            if (lastSeg.isEmpty()) {
                RecycleUtil.recycle(this.segments.pollLast());
                lastSeg = getLast();
            }
        }
    }
@Test
    public void testRemoveFromLastWhen() {
        fillList();

        // remove elements is greater or equal to 150.
        this.list.removeFromLastWhen(x -> x >= 150);
        assertEquals(150, this.list.size());
        assertFalse(this.list.isEmpty());
        for (int i = 0; i < 150; i++) {
            assertEquals(i, (int) this.list.get(i));
        }
        try {
            this.list.get(151);
            fail();
        } catch (IndexOutOfBoundsException e) {

        }
        assertEquals(150 / SegmentList.SEGMENT_SIZE + 1, this.list.segmentSize());

        // remove  elements is greater or equal to 32.
        this.list.removeFromLastWhen(x -> x >= 32);
        assertEquals(32, this.list.size());
        assertFalse(this.list.isEmpty());
        for (int i = 0; i < 32; i++) {
            assertEquals(i, (int) this.list.get(i));
        }
        try {
            this.list.get(32);
            fail();
        } catch (IndexOutOfBoundsException e) {

        }
        assertEquals(1, this.list.segmentSize());

        // Add elements again.
        fillList();
        assertEquals(1032, this.list.size());
        for (int i = 0; i < 1032; i++) {
            if (i < 32) {
                assertEquals(i, (int) this.list.get(i));
            } else {
                assertEquals(i - 32, (int) this.list.get(i));
            }
        }
    }