1 /* 2 * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. 3 */ 4 5 package org.openjdk.bench.valhalla.sandbox.corelibs.corelibs; 6 7 import java.util.ConcurrentModificationException; 8 import java.util.NoSuchElementException; 9 10 /** 11 * An inline cursor is a reference to an existing or non-existent element 12 * of a collection. 13 * <p> 14 * Cursor values are immutable, the reference to an element 15 * does not change but the state of the collection can change 16 * so the element is no longer accessible. 17 * Calling {@link #get()} throws a {@link ConcurrentModificationException}. 18 * Iterating through a Collection proceeds by creating new Cursor 19 * from the Collection or advancing to the next or retreating to previous elements. 20 * Advancing past the end of the Collection or retreating before the beginning 21 * results in Cursor values that are non-existent. 22 * A Cursor for an empty Collection does not refer to an element and 23 * throws {@link NoSuchElementException}. 24 * Modifications to the Collection invalidate every Cursor that was created 25 * before the modification. 26 * The typical traversal pattern is: 27 * <pre>{@code 28 * Collection<T> c = ...; 29 * for (var cursor = c.cursor(); cursor.exists(); cursor = cursor.advance()) { 30 * var el = cursor.get(); 31 * } 32 * } 33 * </pre> 34 * <p> 35 * Cursors can be used to {@link #remove()} remove an element from the collection. 36 * Removing an element modifies the collection making that cursor invalid. 37 * The cursor returned from the {@link #remove()} method is a placeholder 38 * for the position, the element occupied, between the next and previous elements. 39 * It can be moved to the next or previous element to continue the iteration. 40 * <p> 41 * The typical traversal and remove pattern follows; when an element is 42 * removed, the cursor returned from the remove is used to continue the iteration: 43 * <pre>{@code 44 * Collection<T> c = ...; 45 * for (var cursor = c.cursor(); cursor.exists(); cursor = cursor.advance()) { 46 * var el = cursor.get(); 47 * if (el.equals(...)) { 48 * cursor = cursor.remove(); 49 * } 50 * } 51 * } 52 * </pre> 53 * <p> 54 * @param <T> the type of the element. 55 */ 56 public interface InlineCursor<T> { 57 /** 58 * Return true if the Cursor refers to an element. 59 * 60 * If the collection has been modified since the Cursor was created 61 * the element can not be known to exist. 62 * This method does not throw {@link ConcurrentModificationException} 63 * if the collection has been modified but returns false. 64 * 65 * @return true if this Cursor refers to an element in the collection and 66 * the collection has not been modified since the cursor was created; 67 * false otherwise 68 */ 69 boolean exists(); 70 71 /** 72 * Return a Cursor for the next element after the current element. 73 * If there is no element following this element the returned 74 * Cursor will be non-existent. To wit: {@code Cursor.exists() == false}. 75 * 76 * @return return a cursor for the next element after this element 77 * @throws ConcurrentModificationException if the collection 78 * has been modified since this Cursor was created 79 */ 80 InlineCursor<T> advance(); 81 82 /** 83 * Return the current element referred to by the Cursor. 84 * 85 * The behavior must be consistent with {@link #exists()} 86 * as long as the collection has not been modified. 87 * 88 * @return return the element in the collection if the collection 89 * has not been modified since the cursor was created 90 * @throws NoSuchElementException if the referenced element does not exist 91 * or no longer exists 92 * @throws ConcurrentModificationException if the collection 93 * has been modified since this Cursor was created 94 */ 95 T get(); 96 }