2025-02-05 13:40:00
github.com
Some extra Collection classes targetting Java 8.
The main thing here at the moment is a RingBuffer implementation.
You can add the library to your project as a dependency with the following Maven coordinates:
dependency>
groupId>com.evolvedbinary.j8cugroupId>
artifactId>j8cuartifactId>
version>1.0.0version>
dependency>
Implementation of a RingBuffer (e.g. https://en.wikipedia.org/wiki/Circular_buffer) in Java 8.
This implementation supports two modes of operations for reading from the buffer:
1. Unordered (the default)
2. Ordered
The difference between Unordered and Ordered modes is that when you use Unordered mode,
it starts reading from the start of the buffer, whilst Ordered mode starts reading from the
oldest entry in the buffer. Ordered mode has FIFO (First In, First Out) like semantics.
Ordered mode is useful for when you want to keep a buffer of the most recent N objects,
and you need to read them back from oldest to newest.
The RingBuffer also provides several additional features:
- Listeners may be registered to receive events when the state of the RingBuffer changes.
- All entries may be copied out of the RingBuffer.
- The RingBuffer can be
clear
ed which removes references to all entries and resets its state, or it can just bereset
whereby any entry references are maintained but could be overwritten in future on subsequence calls toput
.
import com.evolvedbinary.j8cu.RingBuffer;
final int capacity = 3;
final RingBufferString> ringBuffer = new RingBuffer(String.class, capacity);
ringBuffer.put("a");
ringBuffer.put("b");
ringBuffer.put("c");
ringBuffer.put("d");
ringBuffer.put("e");
Then subsequent calls to get
entries from the RingBuffer would produce:
ringBuffer.get() => "d"
ringBuffer.get() => "e"
ringBuffer.get() => "c"
ringBuffer.get() => null
import com.evolvedbinary.j8cu.RingBuffer;
final int capacity = 3;
final boolean orderedReads = true;
final RingBufferString> ringBuffer = new RingBuffer(String.class, capacity, orderedReads);
ringBuffer.put("a");
ringBuffer.put("b");
ringBuffer.put("c");
ringBuffer.put("d");
ringBuffer.put("e");
Then subsequent calls to get
entries from the RingBuffer would produce:
ringBuffer.get() => "c"
ringBuffer.get() => "d"
ringBuffer.get() => "e"
ringBuffer.get() => null
It is also possible to add and remove listeners to a RingBuffer. One reason this can be useful would be if you would
like to get and/or be notified the next n entries within some sort of window (e.g. time frame or event space). For example:
import com.evolvedbinary.j8cu.RingBuffer;
import org.jspecify.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
final int capacity = 7;
final boolean orderedReads = true;
final RingBufferString> ringBuffer = new RingBuffer(String.class, capacity, orderedReads);
// capture the entries added to the RingBuffer in the next 2 seconds
final int windowSeconds = 2;
final TimeWindowListener timeWindowListener = new TimeWindowListener(windowSeconds);
ringBuffer.addListener(timeWindowListener);
// put entries for the next 2 * 1.5 seconds
final long end = System.currentTimeMillis() + (windowSeconds * 1_500);
int i = 0;
while (System.currentTimeMillis() end) {
final int increment = i++ % 24;
ringBuffer.put("" + (char)('a' + increment));
Thread.sleep(250); // slow down this is just a demo!
}
// print out what was captured by the listener
final ListString> captured = timeWindowListener.getCaptured();
System.out.println("Added: " + captured.size());
System.out.println("Captured: " + captured);
/**
* Simple example listener implementation that captures all `put` entries for a window measured in seconds
*/
private static class TimeWindowListener implements RingBuffer.ListenerString> {
private final int window; // seconds
private final long start;
private final ListString> captured = new ArrayList();
public TimeWindowListener(final int window) {
this.window = window;
this.start = System.currentTimeMillis();
}
@Override
public void retrieved(final @Nullable String entry) {
}
@Override
public void stored(final String entry) {
final long diff = System.currentTimeMillis() - start;
if (diff long) window) * 1_000) {
captured.add(entry);
}
}
public ListString> getCaptured() {
return new ArrayList(captured);
}
}
Keep your files stored safely and securely with the SanDisk 2TB Extreme Portable SSD. With over 69,505 ratings and an impressive 4.6 out of 5 stars, this product has been purchased over 8K+ times in the past month. At only $129.99, this Amazon’s Choice product is a must-have for secure file storage.
Help keep private content private with the included password protection featuring 256-bit AES hardware encryption. Order now for just $129.99 on Amazon!
Help Power Techcratic’s Future – Scan To Support
If Techcratic’s content and insights have helped you, consider giving back by supporting the platform with crypto. Every contribution makes a difference, whether it’s for high-quality content, server maintenance, or future updates. Techcratic is constantly evolving, and your support helps drive that progress.
As a solo operator who wears all the hats, creating content, managing the tech, and running the site, your support allows me to stay focused on delivering valuable resources. Your support keeps everything running smoothly and enables me to continue creating the content you love. I’m deeply grateful for your support, it truly means the world to me! Thank you!
BITCOIN bc1qlszw7elx2qahjwvaryh0tkgg8y68enw30gpvge Scan the QR code with your crypto wallet app |
DOGECOIN D64GwvvYQxFXYyan3oQCrmWfidf6T3JpBA Scan the QR code with your crypto wallet app |
ETHEREUM 0xe9BC980DF3d985730dA827996B43E4A62CCBAA7a Scan the QR code with your crypto wallet app |
Please read the Privacy and Security Disclaimer on how Techcratic handles your support.
Disclaimer: As an Amazon Associate, Techcratic may earn from qualifying purchases.