public void removeFromFirstWhen(final Predicate<T> predicate) {
        Segment<T> firstSeg = getFirst();
        while (true) {
            if (firstSeg == null) {
                this.firstOffset = this.size = 0;
                return;
            }
            int removed = firstSeg.removeFromFirstWhen(predicate);
            if (removed == 0) {
                break;
            }
            this.size -= removed;
            this.firstOffset = firstSeg.offset;
            if (firstSeg.isEmpty()) {
                RecycleUtil.recycle(this.segments.pollFirst());
                firstSeg = getFirst();
                this.firstOffset = 0;
            }
        }
    }
@Test
    public void testRemoveFromFirstWhen() {
        fillList();
        this.list.removeFromFirstWhen(x -> x < 200);
        assertEquals(800, this.list.size());
        assertEquals(200, (int) this.list.get(0));

        for (int i = 0; i < 800; i++) {
            assertEquals(200 + i, (int) this.list.get(i));
        }

        this.list.removeFromFirstWhen(x -> x < 500);
        assertEquals(500, this.list.size());
        for (int i = 0; i < 500; i++) {
            assertEquals(500 + i, (int) this.list.get(i));
        }

        this.list.removeFromFirstWhen(x -> x < 1000);
        assertTrue(this.list.isEmpty());
        assertEquals(0, this.list.segmentSize());

        fillList();
        assertFilledList();
    }