{"id":30612633,"url":"https://github.com/evolvedbinary/j8cu","last_synced_at":"2026-03-27T02:36:44.155Z","repository":{"id":275119922,"uuid":"925133454","full_name":"evolvedbinary/j8cu","owner":"evolvedbinary","description":"Java 8 Collection Utilities","archived":false,"fork":false,"pushed_at":"2025-09-26T11:11:42.000Z","size":98,"stargazers_count":9,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-09T06:52:19.407Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/evolvedbinary.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-31T09:45:31.000Z","updated_at":"2025-09-26T11:11:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"bd89ba2e-980d-4856-b8b0-8e7258bed5a8","html_url":"https://github.com/evolvedbinary/j8cu","commit_stats":null,"previous_names":["evolvedbinary/j8cu"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/evolvedbinary/j8cu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolvedbinary%2Fj8cu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolvedbinary%2Fj8cu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolvedbinary%2Fj8cu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolvedbinary%2Fj8cu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evolvedbinary","download_url":"https://codeload.github.com/evolvedbinary/j8cu/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evolvedbinary%2Fj8cu/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31010791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T02:33:22.146Z","status":"ssl_error","status_checked_at":"2026-03-27T02:33:21.763Z","response_time":164,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-30T05:34:44.999Z","updated_at":"2026-03-27T02:36:44.136Z","avatar_url":"https://github.com/evolvedbinary.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Java 8 Collection Utilities\n\n[![CircleCI](https://dl.circleci.com/status-badge/img/gh/evolvedbinary/j8cu/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/evolvedbinary/j8cu/tree/main)\n[![Coverage Status](https://coveralls.io/repos/github/evolvedbinary/j8cu/badge.svg?branch=main)](https://coveralls.io/github/evolvedbinary/j8cu?branch=main)\n[![Java 8](https://img.shields.io/badge/java-8-blue.svg)](https://adoptopenjdk.net/)\n[![License](https://img.shields.io/badge/license-BSD%203-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.evolvedbinary.j8cu/j8cu/badge.svg)](https://search.maven.org/search?q=g:com.evolvedbinary.j8xu)\n\nSome extra Collection classes targetting Java 8.\n\nThe main things here at the moment are:\n\n1. A [RingBuffer](src/main/java/com/evolvedbinary/j8cu/buffer/ring/RingBuffer.java) implementation.\n2. A variety of [Linked List](src/main/java/com/evolvedbinary/j8cu/list/linked/) implementations.\n\n## Maven Dependency\nYou can add the library to your project as a dependency with the following Maven coordinates:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.evolvedbinary.j8cu\u003c/groupId\u003e\n    \u003cartifactId\u003ej8cu\u003c/artifactId\u003e\n    \u003cversion\u003e2.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Ring Buffer\nImplementation of a [RingBuffer](src/main/java/com/evolvedbinary/j8cu/buffer/ring/RingBuffer.java) (e.g. https://en.wikipedia.org/wiki/Circular_buffer) in Java 8.\nThis implementation supports two modes of operations for reading from the buffer:\n    \n    1. Unordered (the default)\n    2. Ordered\n\nThe difference between Unordered and Ordered modes is that when you use Unordered mode,\nit starts reading from the start of the buffer, whilst Ordered mode starts reading from the \noldest entry in the buffer. Ordered mode has FIFO (First In, First Out) like semantics.\n\nOrdered mode is useful for when you want to keep a buffer of the most recent N objects,\nand you need to read them back from oldest to newest.\n\nThe RingBuffer also provides several additional features:\n* Listeners may be registered to receive events when the state of the RingBuffer changes.\n* All entries may be copied out of the RingBuffer.\n* The RingBuffer can be `clear`ed which removes references to all entries and resets its state, or it can just be `reset` whereby any entry references are maintained but could be overwritten in future on subsequence calls to `put`.\n\n### Unordered Ring Buffer Example\n\n```java\nimport com.evolvedbinary.j8cu.buffer.ring.RingBuffer;\n\nfinal int capacity = 3;\nfinal RingBuffer\u003cString\u003e ringBuffer = new RingBuffer\u003c\u003e(String.class, capacity);\n\nringBuffer.put(\"a\");\nringBuffer.put(\"b\");\nringBuffer.put(\"c\");\nringBuffer.put(\"d\");\nringBuffer.put(\"e\");\n```\n\nThen subsequent calls to `get` entries from the RingBuffer would produce:\n```\nringBuffer.get() =\u003e \"d\"\nringBuffer.get() =\u003e \"e\"\nringBuffer.get() =\u003e \"c\"\nringBuffer.get() =\u003e null\n```\n\n### Ordered Ring Buffer Example\n\n```java\nimport com.evolvedbinary.j8cu.buffer.ring.RingBuffer;\n\nfinal int capacity = 3;\nfinal boolean orderedReads = true;\nfinal RingBuffer\u003cString\u003e ringBuffer = new RingBuffer\u003c\u003e(String.class, capacity, orderedReads);\n\nringBuffer.put(\"a\");\nringBuffer.put(\"b\");\nringBuffer.put(\"c\");\nringBuffer.put(\"d\");\nringBuffer.put(\"e\");\n```\n\nThen subsequent calls to `get` entries from the RingBuffer would produce:\n```\nringBuffer.get() =\u003e \"c\"\nringBuffer.get() =\u003e \"d\"\nringBuffer.get() =\u003e \"e\"\nringBuffer.get() =\u003e null\n```\n\n### Listening to RingBuffer Events\n\nIt is also possible to add and remove listeners to a RingBuffer. One reason this can be useful would be if you would\nlike to get and/or be notified the next *n* entries within some sort of window (e.g. time frame or event space). For example:\n\n```java\nimport com.evolvedbinary.j8cu.buffer.ring.RingBuffer;\nimport org.jspecify.annotations.Nullable;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\nfinal int capacity = 7;\nfinal boolean orderedReads = true;\nfinal RingBuffer\u003cString\u003e ringBuffer = new RingBuffer\u003c\u003e(String.class, capacity, orderedReads);\n\n// capture the entries added to the RingBuffer in the next 2 seconds\nfinal int windowSeconds = 2;\nfinal TimeWindowListener timeWindowListener = new TimeWindowListener(windowSeconds);\nringBuffer.addListener(timeWindowListener);\n\n// put entries for the next 2 * 1.5 seconds\nfinal long end = System.currentTimeMillis() + (windowSeconds * 1_500);\nint i = 0;\nwhile (System.currentTimeMillis() \u003c end) {\n    final int increment = i++ % 24;\n    ringBuffer.put(\"\" + (char)('a' + increment));\n    Thread.sleep(250); // slow down this is just a demo!\n}\n\n// print out what was captured by the listener\nfinal List\u003cString\u003e captured = timeWindowListener.getCaptured();\nSystem.out.println(\"Added: \" + captured.size());\nSystem.out.println(\"Captured: \" + captured);\n\n\n/**\n * Simple example listener implementation that captures all `put` entries for a window measured in seconds\n */\nprivate static class TimeWindowListener implements RingBuffer.Listener\u003cString\u003e {\n    private final int window;  // seconds\n    private final long start;\n    private final List\u003cString\u003e captured = new ArrayList\u003c\u003e();\n\n    public TimeWindowListener(final int window) {\n        this.window = window;\n        this.start = System.currentTimeMillis();\n    }\n\n    @Override\n    public void retrieved(final @Nullable String entry) {\n    }\n\n    @Override\n    public void stored(final String entry) {\n        final long diff = System.currentTimeMillis() - start;\n        if (diff \u003c ((long) window) * 1_000) {\n            captured.add(entry);\n        }\n    }\n\n    public List\u003cString\u003e getCaptured() {\n        return new ArrayList\u003c\u003e(captured);\n    }\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevolvedbinary%2Fj8cu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevolvedbinary%2Fj8cu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevolvedbinary%2Fj8cu/lists"}