A type-specific linked hash set with with a fast, small-footprint
Instances of this class use a hash table to represent a set. The table is
filled up to a specified load factor, and then doubled in size to
accommodate new entries. If the table is emptied below one fourth of
the load factor, it is halved in size; however, the table is never reduced to
a size smaller than that at creation time: this approach makes it possible to
create sets with a large capacity in which insertions and deletions do not
cause immediately rehashing. Moreover, halving is not performed when deleting
entries from an iterator, as it would interfere with the iteration process.
#clear() does not modify the hash table size. Rather, a
#trim() lets you control the size of
the table; this is particularly useful if you reuse instances of this class.
Iterators generated by this set will enumerate elements in the same order in
which they have been added to the set (addition of elements already present
in the set does not change the iteration order). Note that this order has
nothing in common with the natural order of the keys. The order is kept by
means of a doubly linked list, represented via an array of longs
parallel to the table.
This class implements the interface of a sorted set, so to allow easy access
of the iteration order: for instance, you can get the first element in
iteration order with
first() without having to create an iterator;
however, this class partially violates the
java.util.SortedSetcontract because all subset methods throw an exception and
#comparator() returns always
Additional methods, such as
addAndMoveToFirst(), make it easy to use
instances of this class as a cache (e.g., with LRU policy).
The iterators provided by this class are type-specific
java.util.ListIterator, and can be started at any
element which is in the set (if the provided element is not in the
NoSuchElementException exception will be thrown). If, however,
the provided element is not the first or last element in the set, the first
access to the list index will require linear time, as in the worst case the
entire set must be scanned in iteration order to retrieve the positional
index of the starting element. If you use just the methods of a type-specific
it.unimi.dsi.fastutil.BidirectionalIterator, however, all operations
will be performed in constant time.