{"id":37432036,"url":"https://github.com/kschuetz/collection-views","last_synced_at":"2026-01-16T06:36:01.497Z","repository":{"id":57745431,"uuid":"181782752","full_name":"kschuetz/collection-views","owner":"kschuetz","description":"Low overhead, protected views over Java collections","archived":false,"fork":false,"pushed_at":"2022-10-03T04:24:08.000Z","size":1184,"stargazers_count":3,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-09T14:42:36.771Z","etag":null,"topics":["collections","functional-programming","immutable","java","lambda","non-empty","set","vector"],"latest_commit_sha":null,"homepage":"https://kschuetz.github.io/collection-views/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kschuetz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-16T23:34:09.000Z","updated_at":"2022-10-30T22:43:42.000Z","dependencies_parsed_at":"2022-08-30T14:51:18.535Z","dependency_job_id":null,"html_url":"https://github.com/kschuetz/collection-views","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/kschuetz/collection-views","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kschuetz%2Fcollection-views","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kschuetz%2Fcollection-views/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kschuetz%2Fcollection-views/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kschuetz%2Fcollection-views/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kschuetz","download_url":"https://codeload.github.com/kschuetz/collection-views/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kschuetz%2Fcollection-views/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28477882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: 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":["collections","functional-programming","immutable","java","lambda","non-empty","set","vector"],"created_at":"2026-01-16T06:36:01.258Z","updated_at":"2026-01-16T06:36:01.464Z","avatar_url":"https://github.com/kschuetz.png","language":"Java","readme":"# collection-views\n\n[![collection-views](https://img.shields.io/maven-central/v/software.kes/collection-views.svg)](http://search.maven.org/#search%7Cga%7C1%7Csoftware.kes.collection-views)\n[![Javadoc](https://javadoc-badge.appspot.com/software.kes/collection-views.svg?label=javadoc)](https://kschuetz.github.io/collection-views/javadoc/)\n[![CircleCI](https://circleci.com/gh/kschuetz/collection-views.svg?style=svg)](https://circleci.com/gh/kschuetz/collection-views)\n[![Maintainability](https://api.codeclimate.com/v1/badges/43ac4c983644c1bc7f5d/maintainability)](https://codeclimate.com/github/kschuetz/collection-views/maintainability)\n\n# [lambda](https://github.com/palatable/lambda) version compatibility\n\nThe current version of *collection-views* has been certified to be compatible with the following lambda versions:\n\n- 5.3.0\n- 5.2.0\n- 5.1.0\n- 5.0.0\n- 4.0.0\n\n#### Table of Contents\n\n- [What is it?](#what-is-it)\n- [What is it not?](#what-is-it-not)\n- [Why?](#why)\n- [Design principles](#design-principles)\n- [Installation](#installation)\n- [Type of collection views](#types)\n   - [`Vector\u003cA\u003e`](#vector)\n   - [`NonEmptyVector\u003cA\u003e`](#non-empty-vector)\n   - [`ImmutableVector\u003cA\u003e`](#immutable-vector)\n   - [`ImmutableNonEmptyVector\u003cA\u003e`](#immutable-non-empty-vector)\n   - [`Set\u003cA\u003e`](#set)\n   - [`NonEmptySet\u003cA\u003e`](#non-empty-set)\n   - [`ImmutableSet\u003cA\u003e`](#immutable-set)\n   - [`ImmutableNonEmptySet\u003cA\u003e`](#immutable-non-empty-set)\n - [Examples](#examples)\n   - [`Vector`](#vector-examples)\n   - [`Set`](#set-examples)\n - [Non-goals and trade-offs](#non-goals-and-trade-offs)\n - [Custom views](#custom-views)\n - [Notes](#notes)\n - [License](#license)   \n       \n\n# \u003ca name=\"what-is-it\"\u003eWhat is it?\u003c/a\u003e\n\n*collection-views* is a Java library that facilitates creating protected views over collections and arrays with as little overhead as possible.  It provides the interfaces `Vector\u003cA\u003e` and `Set\u003cA\u003e`, and some variations of these that provide additional guarantees. \n\nIt builds on [enhanced-iterables](https://github.com/kschuetz/enhanced-iterables) and is intended to be used in conjunction with [lambda](https://github.com/palatable/lambda).\n\nFor more details, check out the [javadoc](https://kschuetz.github.io/collection-views/javadoc/).\n\n# \u003ca name=\"what-is-it-not\"\u003eWhat is it not?\u003c/a\u003e\n\n*collection-views* is not a persistent data structures library.  Collections are wrapped as is;  no methods are provided for updating or adding to collections.  \n\nIt differs from [Guava Immutable Collections](https://github.com/google/guava/wiki/ImmutableCollectionsExplained) in that it acts as a shield over existing collections rather than being collections themselves.\n\n# \u003ca name=\"why\"\u003eWhy?\u003c/a\u003e \n\nSometimes you might want all of the following:\n\n- To provide (or require) read-access to the essential operations of a collection (e.g., 'get by index' for arrays or lists, or 'contains' for sets).\n- Protection from mutation to the collection without making defensive copies.\n- To retain the performance and locality of reference characteristics of the collection you are employing.\n\nThe goal of *collection-views* is to provide this functionality with as little overhead as possible.\n\n#### Why not just use `Collections.unmodifiableXXX` or Guava?\n\nWhile *collection-views* has essentially the same purpose as `Collections.unmodifiableXXX` or Guava, here are a few reasons *collection-views* is different.\n\n- *collection-views* is designed to be used with [lambda](https://github.com/palatable/lambda).  It takes advantage of lambda's types (such as `Maybe`), and should be comfortable to those already using lambda.  \n\n- *collection-views* gives you control over when to make copies. `Collections.unmodifiableXXX` will never make a copy, so you don't have a strong guarantee of immutability.  Guava, on the other hand, always initially makes a copy, and that may not be always what you want.  \n\n- *collection-views* provides the following features currently not available in either:\n    - `NonEmpty` types\n    - Transformations such as `fmap`, `take`, `drop`, `slice`\n\n#### Why not just use lambda's `map`, `take`, `drop`, etc?\n\nWhile these functions are useful and will work perfectly well on a collection view, they currently operate on `Iterable`s and return `Iterable`s as a result.  *collection-views* provides equivalents that will yield a more specific type at compile-time.  For example, `ImmutableNonEmptyVector.fmap` will always yield an `ImmutableNonEmptyVector`, and `ImmutableVector.take` will always yield an `ImmutableVector`.\n\n# \u003ca name=\"design-principles\"\u003eDesign principles\u003c/a\u003e\n\nThe design of *collection-views* is guided by the following principles and goals:\n\n## Only the essentials\n\nOnly the essential read-only operations of underlying collections should be exposed.  The consumer of a `Vector` will only be able to iterate its elements, check its size, or read an element by index.  The consumer of a `Set` will only be able to iterate its elements, check its size, or test for membership.  It is not a goal of this library to provide add or update operations.\n\n## Immutable to bearer\n\nA collection view should be able to be shared safely without making a defensive copy.  There should be no way for the bearer of a collection view to mutate the collection or gain access to a reference to the underlying collection.\n\n## Correct by construction\n\nIt should be impossible to construct an instance of an interface that does not uphold its guarantees.  For example, there is no way to create `NonEmptyVector` that contains no elements.  Therefore, you can be assured at compile-time that if you require a `NonEmptyVector`, there will be no need to check at run-time if it is non-empty.\n\n## Doesn't make copies\n\nMethods should never make a copy of an underlying collection unless explicitly asked to, or if it is necessary to uphold the guarantees of its interface.  For example, there is no reason `fmap`, `take`, or `slice` on a `Vector` should need to make any copies of the collection to uphold the random access guarantee on a `Vector`.   \n\nIn contrast, if a `Vector` is to be constructed from an `Iterable` that is not known to have a random access guarantee, then in that case a copy will be made so `Vector` can fulfill this guarantee. \n\n## Opt-in to guarantees\n\nIf you simply prefer to work with `Vector`s or `Set`s and not think about non-emptiness or immutability, you should be able to do so.  For example, since `NonEmptyVector\u003cA\u003e`, `ImmutableVector\u003cA\u003e`, and `ImmutableNonEmptyVector\u003cA\u003e` are all subtypes of `Vector\u003cA\u003e`, you can use them anywhere a `Vector\u003cA\u003e` is called for.\n\n## Provide transformations if they don't violate other principles\n\nAlthough updating and adding to collections is not supported, some transformations can be performed without violating other design principles (e.g. don't make copies).  Those that can be done so with low overhead should be provided.\n\nExamples include `fmap`, `take`, `drop`, `slice`, and `reverse` on `Vector`s.  Each of these transforms a view of a collection without making copies, or violating any guarantees.\n\nThe views yielded by these transformation are new, independent views, and do not affect the original. \n\n## Easy to construct on the fly\n\nFor convenience, collection views should be easy to create on the fly without the need for a pre-existing collection.  Views constructed this way should be first-class and have the same capabilities of all other views.  \n\n# \u003ca name=\"installation\"\u003eInstallation\u003c/a\u003e\n\nTo install, add the dependency to the latest version to your `pom.xml` (Maven) or `build.gradle` (Gradle).\n\nFollow this link to get the dependency info for your preferred build tool:\n[![collection-views](https://img.shields.io/maven-central/v/software.kes/collection-views.svg)](http://search.maven.org/#search%7Cga%7C1%7Csoftware.kes.collection-views)\n\n# \u003ca name=\"types\"\u003eTypes of collection views\u003c/a\u003e\n\n| Interface | Immutable to bearer | Guaranteed safe from mutation anywhere | Guaranteed non-empty |\n|---|---|---|---|\n| `Vector\u003cA\u003e` | yes | no | no |\n| `NonEmptyVector\u003cA\u003e` | yes | no | yes |\n| `ImmutableVector\u003cA\u003e` | yes | yes | no |\n| `ImmutableNonEmptyVector\u003cA\u003e` | yes | yes | yes |\n| `Set\u003cA\u003e` | yes | no | no |\n| `NonEmptySet\u003cA\u003e` | yes | no | yes |\n| `ImmutableSet\u003cA\u003e` | yes | yes | no |\n| `ImmutableNonEmptySet\u003cA\u003e` | yes | yes | yes |\n\n## \u003ca name=\"vector\"\u003e`Vector\u003cA\u003e`\u003c/a\u003e\n\nA `Vector` is a finite, ordered view of a collection, with O(1)[*](#o1-note) random access to its elements.  It inherits all methods from `FiniteIterable\u003cA\u003e` in [enhanced-iterables](https://github.com/kschuetz/enhanced-iterables), and will return a new `Vector` for many of these methods.   \n\nThe bearer of a `Vector` has the following capabilities:\n\n- Random access to any element in the `Vector` using the `get` method.\n- Get the size of the `Vector` in O(1)[*](#o1-note) using the `size` method.\n- Safely iterate the `Vector` or use it anywhere an `Iterable` is called for.  A `Vector` is always finite.\n- Share the `Vector` with others safely.\n- Make slices of the `Vector` using the `take`, `drop` or `slice` methods.  These slices are `Vector`s themselves, and can also be shared with others safely.\n- Map to a new `Vector` of the same size but a different type using `fmap`.\n\nThe bearer of a `Vector` cannot:\n\n- Mutate the contents of the underlying collection or array. \n- Gain access to the reference of the underlying collection or array.\n\n### \u003ca name=\"creating-vectors\"\u003eCreating `Vector`s\u003c/a\u003e\n\nSeveral static methods are available for creating `Vector`s, with various levels of guarantees:\n\n| Method | Returns | Makes a copy | Caveats |\n|---|---|---|---|\n| `Vector.empty` | `ImmutableVector\u003cA\u003e` | N/A |  |  \n| `Vector.of` | `ImmutableNonEmptyVector\u003cA\u003e` | N/A |  |  \n| `Vector.wrap` | `Vector\u003cA\u003e` | no |  |  \n| `Vector.copyFrom` | `ImmutableVector\u003cA\u003e` | yes| may not terminate if input is infinite | \n| `Vector.copySliceFrom` |`ImmutableVector\u003cA\u003e` | yes |  |\n| `Vector.fill` | `ImmutableVector\u003cA\u003e` | N/A | |\n| `Vector.lazyFill` | `ImmutableVector\u003cA\u003e` | N/A | |\n| `NonEmptyVector.maybeWrap` |`Maybe\u003cNonEmptyVector\u003cA\u003e\u003e` | no |  |\n| `NonEmptyVector.wrapOrThrow` |`NonEmptyVector\u003cA\u003e` | no | may throw exceptions |\n| `NonEmptyVector.maybeCopyFrom` |`Maybe\u003cImmutableNonEmptyVector\u003cA\u003e\u003e` | yes | may not terminate if input is infinite |\n| `NonEmptyVector.copyFromOrThrow` |`ImmutableNonEmptyVector\u003cA\u003e` | yes | may throw exceptions |\n| `NonEmptyVector.fill` | `ImmutableNonEmptyVector\u003cA\u003e` | N/A | |\n| `NonEmptyVector.lazyFill` | `ImmutableNonEmptyVector\u003cA\u003e` | N/A | |\n\n#### \u003ca name=\"vector-wrapping\"\u003eWrapping an existing collection\u003c/a\u003e\n\nA `Vector` can be created by wrapping an existing collection or array using one of the `Vector.wrap` static methods. \n\n`Vector.wrap`:\n\n- Does not make a copy of the underlying collection.\n- Will never alter the underlying collection in any way.\n- Will maintain a reference to the collection you wrap.\n\nThe underlying collection is protected against mutation from anyone you share the `Vector` with. \nHowever, be aware that anyone else who has a reference to the underlying collection is still able to mutate it.  \nTherefore, it is highly recommended that you do not mutate the collection or share the underlying collection with anyone else who might mutate it.\nIf you prefer to avoid this, you can construct an `ImmutableVector` using `copyFrom` instead.\n\n#### \u003ca name=\"vector-copy-from\"\u003eCopying from an `Iterable\u003cA\u003e`\u003c/a\u003e\n\nA `Vector` can be created by copying from an `Iterable` or array using the `copyFrom` or `copySliceFrom` methods.\n\n`Vector.copyFrom`:\n\n- Makes a copy of the input if necessary\u003csuper\u003e*\u003c/super\u003e.\n- Will not alter the input in any way.\n- Will not maintain a reference to the input.\n\nThe copying of the input is a one-time cost, but in return you get an `ImmutableVector` that is guaranteed safe from mutation.\n\n\u003csuper\u003e*\u003c/super\u003e \u003csmall\u003eif the input is an `ImmutableVector`, no copying will be performed.\u003c/small\u003e\n\n#### \u003ca name=\"vector-of\"\u003eBuilding `Vector`s directly\u003c/a\u003e\n\nCalling `Vector.of` with one or more elements will return a new `ImmutableNonEmptyVector`. \n\n`Vector.fill` and `Vector.lazyFill` also create `ImmutableVector`s directly.\n\n#### \u003ca name=\"vector-builders\"\u003eBuilding using a `VectorBuilder`\u003c/a\u003e\n\nThe `Vector.builder` static method will return a new `VectorBuilder`, which can be used to construct new `ImmutableVector`s.\n\n#### \u003ca name=\"vector-empty\"\u003eCreating an empty `Vector`\u003c/a\u003e\n\nThe `Vector.empty` static method will return an `ImmutableVector\u003cA\u003e` that is empty.\n\n## \u003ca name=\"non-empty-vector\"\u003e`NonEmptyVector\u003cA\u003e`\u003c/a\u003e\n\nA `NonEmptyVector\u003cA\u003e` is a `Vector\u003cA\u003e` that is known at compile-time to contain at least one element.  It is not possible to construct a `NonEmptyVector` that is empty.  Since it is also a `Vector\u003cA\u003e`, it can be used anywhere a `Vector\u003cA\u003e` is called for.\n`NonEmptyVector\u003cA\u003e` is a subtype of `NonEmptyIterable\u003cA\u003e`, which provides a `head` method that unconditionally yields the first element.\n\n### \u003ca name=\"creating-non-empty-vectors\"\u003eCreating a `NonEmptyVector`\u003c/a\u003e\n\n#### \u003ca name=\"non-empty-vector-wrapping\"\u003eWrapping an existing collection\u003c/a\u003e\n\n`NonEmptyVector.maybeWrap` takes an array or a `java.util.List` and returns a `Maybe\u003cNonEmptyVector\u003cA\u003e\u003e`.  If the provided collection is not empty, a `NonEmptyVector\u003cA\u003e` will be created and returned in a `Maybe.just`, otherwise `Maybe.nothing` will be returned.\n\nAlternatively, if you know for sure that the collection you are passing is not empty, then you can call `NonEmptyVector.wrapOrThrow`.  This will either return the `NonEmptyVector` directly, or throw an `IllegalArgumentException` if the provided collection is empty.\n\n`NonEmptyVector.maybeWrap` and `NonEmptyVector.wrapOrThrow` behave similarly to `Vector.wrap` in that a copy of the underlying collection is never made.\n\n#### \u003ca name=\"non-empty-vector-converting\"\u003eConverting an existing `Vector`\u003c/a\u003e\n\nA `Vector` has the methods `toNonEmpty` and `toNonEmptyOrThrow` that will attempt to convert the `Vector` to a `NonEmptyVector` at run-time.  They will do so without making copies of any underlying collections.\n\n#### \u003ca name=\"non-empty-vector-of\"\u003eBuilding `NonEmptyVector`s directly\u003c/a\u003e\n\n`Vector.of` always returns a `ImmutableNonEmptyVector`, so all `Vector`s constructed this way are compatible with `NonEmptyVector`.\n\n`NonEmptyVector.fill` and `NonEmptyVector.lazyFill` are variations of `Vector.fill` and `Vector.lazyFill` that yield `ImmutableNonEmptyVector`s.\n\n## \u003ca name=\"immutable-vector\"\u003e`ImmutableVector\u003cA\u003e`\u003c/a\u003e\n\nAn `ImmutableVector\u003cA\u003e` is a `Vector\u003cA\u003e` with the additional guarantee that it is 100% safe from mutation.  In other words, no one else holds any references to its underlying collection.\n\n## \u003ca name=\"immutable-non-empty-vector\"\u003e`ImmutableNonEmptyVector\u003cA\u003e`\u003c/a\u003e\n\nAn `ImmutableNonEmptyVector\u003cA\u003e` is a `Vector\u003cA\u003e` that also has all the guarantees of `NonEmptyVector\u003cA\u003e` and `ImmutableVector\u003cA\u003e`.  An `ImmutableNonEmptyVector\u003cA\u003e` can be used anywhere a `Vector\u003cA\u003e` is called for. \n\n## Transformations available on `Vectors`\n\nWhile all methods of `EnhancedIterable` are available on all `Vectors`, some of them will also return `Vector`s instead of `Iterable`s.  The following transformations are available on all `Vector`s.  All return a new `Vector` with as specific a type as possible, and don't make copies of the underlying collection:\n\n- `fmap`\n- `reverse`\n- `take`\n- `drop`\n- `slice`\n- `takeRight`\n- `dropRight`\n- `zipWithIndex`\n\nThe following transformations are also possible on `ImmutableVector`s: \n\n- `takeWhile`\n- `dropWhile`\n\n## \u003ca name=\"set\"\u003e`Set\u003cA\u003e`\u003c/a\u003e\n\nThe bearer of a `Set` has the following capabilities:\n\n- Get the size of the `Set` in O(1) using the `size` method.\n- Test for membership in the `Set` using the `contains`method.\n- Safely iterate the `Set` or use it anywhere an `Iterable` is called for.  A `Set` is always finite.\n- Share the `Set` with others safely.\n\nThe bearer of a `Set` cannot:\n\n- Mutate the contents of the underlying collection. \n- Gain access to the reference of the underlying collection.\n\n### \u003ca name=\"creating-sets\"\u003eCreating `Set`s\u003c/a\u003e\n\nSeveral static methods are available for creating `Set`s, with various levels of guarantees:\n\n| Method | Returns | Makes a copy | Caveats |\n|---|---|---|---|\n| `Set.empty` | `ImmutableSet\u003cA\u003e` | N/A |  |  \n| `Set.of` | `ImmutableNonEmptySet\u003cA\u003e` | N/A |  |  \n| `Set.wrap` | `Set\u003cA\u003e` | no |  |  \n| `Set.copyFrom` | `ImmutableSet\u003cA\u003e` | yes| may not terminate if input is infinite | \n| `NonEmptySet.maybeWrap` |`Maybe\u003cNonEmptySet\u003cA\u003e\u003e` | no |  |\n| `NonEmptySet.wrapOrThrow` |`NonEmptySet\u003cA\u003e` | no | may throw exceptions |\n| `NonEmptySet.maybeCopyFrom` |`Maybe\u003cImmutableNonEmptySet\u003cA\u003e\u003e` | yes | may not terminate if input is infinite |\n| `NonEmptySet.copyFromOrThrow` |`ImmutableNonEmptySet\u003cA\u003e` | yes | may throw exceptions |\n\n#### \u003ca name=\"set-wrapping\"\u003eWrapping an existing `java.util.Set`\u003c/a\u003e\n\nA `Set` can be created by wrapping an existing `java.util.Set` using the `Set.wrap` static methods. \n\n`Set.wrap`:\n\n- Does not make a copy of the underlying collection.\n- Will not alter the underlying collection in any way.\n- Will maintain a reference to the collection you wrap.\n\nThe underlying collection is protected against mutation from anyone you share the `Set` with.  However, note that anyone who has a reference to the underlying collection is still able to mutate it.  Therefore, it is highly recommended that you do not mutate the collection or share the underlying collection with anyone else who might mutate it.\nIf you prefer to avoid this, you can construct an `ImmutableSet` using `copyFrom` instead.\n\n#### \u003ca name=\"set-copy-from\"\u003eCopying from an `Iterable\u003cA\u003e`\u003c/a\u003e\n\nA `Set` can be constructed from an `Iterable` or array using the `copyFrom` or `copySliceFrom` methods.\n\n`Set.copyFrom`:\n\n- Makes a copy of the input if necessary\u003csuper\u003e*\u003c/super\u003e.\n- Will not alter the input in any way.\n- Will not maintain a reference to the input.\n\nThe copying of the input is a one-time cost, but in return you get an `ImmutableSet` that is guaranteed safe from mutation.\n\n\u003csuper\u003e*\u003c/super\u003e \u003csmall\u003eif the input is an `ImmutableSet`, no copying will be performed.\u003c/small\u003e\n\n#### \u003ca name=\"set-of\"\u003eBuilding `Set`s directly\u003c/a\u003e\n\nCalling `Set.of` with one or more elements will return a new `ImmutableNonEmptySet`. \n\n#### \u003ca name=\"set-empty\"\u003eCreating an empty `Set`\u003c/a\u003e\n\nThe `Set.empty` static method will return an `ImmutableSet\u003cA\u003e` that is empty.\n\n## \u003ca name=\"non-empty-set\"\u003e`NonEmptySet\u003cA\u003e`\u003c/a\u003e\n\nA `NonEmptySet\u003cA\u003e` is a `Set\u003cA\u003e` that is known at compile-time to contain at least one element.  It is not possible to construct a `NonEmptySet` that is empty.  Since it is also a `Set\u003cA\u003e`, it can be used anywhere a `Set\u003cA\u003e` is called for.\n`NonEmptySet\u003cA\u003e` is a subtype of `NonEmptyIterable\u003cA\u003e`, which provides a `head` method that unconditionally yields an element.\n\n### \u003ca name=\"creating-non-empty-vectors\"\u003eCreating a `NonEmptySet`\u003c/a\u003e\n\n#### \u003ca name=\"non-empty-vector-wrapping\"\u003eWrapping an existing collection\u003c/a\u003e\n\n`NonEmptyVector.maybeWrap` takes an a `java.util.Set` and returns a `Maybe\u003cNonEmptySet\u003cA\u003e\u003e`.  If the provided collection is not empty, a `NonEmptySet\u003cA\u003e` will be created and returned in a `Maybe.just`, otherwise `Maybe.nothing` will be returned.\n\nAlternatively, if you know for sure that the set you are passing is not empty, then you can call `NonEmptySet.wrapOrThrow`.  This will either return the `NonEmptySet` directly, or throw an `IllegalArgumentException` if the provided collection is empty.\n\n`NonEmptySet.maybeWrap` and `NonEmptySet.wrapOrThrow` behave similarly to `Set.wrap` in that a copy of the underlying collection is never made.\n\n#### \u003ca name=\"non-empty-vector-converting\"\u003eConverting an existing `Set`\u003c/a\u003e\n\nA `Set` has the methods `toNonEmpty` and `toNonEmptyOrThrow` that will attempt to convert the `Set` to a `NonEmptySet` at run-time.  They will do so without making copies of any underlying collections.\n\n#### \u003ca name=\"non-empty-vector-of\"\u003eBuilding `NonEmptyVector`s directly\u003c/a\u003e\n\n`Set.of` always returns a `ImmutableNonEmptySet`, so all `Set`s constructed this way are compatible with `NonEmptySet`.\n\n## \u003ca name=\"immutable-set\"\u003e`ImmutableSet\u003cA\u003e`\u003c/a\u003e\n\nAn `ImmutableSet\u003cA\u003e` is a `Set\u003cA\u003e` with the additional guarantee that it is 100% safe from mutation.  In other words, no one else holds any references to its underlying collection.\n\n## \u003ca name=\"immutable-non-empty-set\"\u003e`ImmutableNonEmptySet\u003cA\u003e`\u003c/a\u003e\n\nAn `ImmutableNonEmptySet\u003cA\u003e` is a `Set\u003cA\u003e` that also has all the guarantees of `NonEmptySet\u003cA\u003e` and `ImmutableSet\u003cA\u003e`.  An `ImmutableNonEmptySet\u003cA\u003e` can be used anywhere a `Set\u003cA\u003e` is called for. \n\n# \u003ca name=\"examples\"\u003eExamples\u003c/a\u003e\n\n## \u003ca name=\"vector-examples\"\u003e`Vector` examples\u003c/a\u003e\n\n### Basics\n\n`Vector`s can wrap arrays or `java.util.List`s. The following wraps an `Integer` array in a `Vector`.  No copy of the array is made:\n\n```Java\nInteger[] arr = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\nVector\u003cInteger\u003e vector1 = Vector.wrap(arr);\n```\n\nYou can also wrap an instance of `java.util.List\u003cA\u003e`, but for this\nexample we will wrap an array.\n\n```Java\nSystem.out.println(\"vector1 = \" + vector1);\n    // *** vector1 = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n```\n\nYou can get the size of the `Vector` in O(1) using the `size` method:\n\n```Java\nSystem.out.println(\"vector1.size() = \" + vector1.size());\n    // *** vector1.size() = 10\n```\n\nYou can safely get an element at any index in O(1) using the `get` method:\n\n```Java\nSystem.out.println(\"vector1.get(0) = \" + vector1.get(0));\n    // *** vector1.get(0) = Just 1\n\nSystem.out.println(\"vector1.get(9) = \" + vector1.get(9));\n    // *** vector1.get(9) = Just 10\n\nSystem.out.println(\"vector1.get(100) = \" + vector1.get(100));\n    // *** vector1.get(100) = Nothing\n```\n\nNote that `get` returns a `Maybe\u003cA\u003e`.  If you pass `get` an invalid index, it will return `Maybe.nothing`:\n\n```Java\nSystem.out.println(\"vector1.get(100) = \" + vector1.get(100));\n    // *** vector1.get(100) = Nothing\n```\n\n`get` is also guaranteed to never return `null`.  If the underlying collection contains a `null` at the index requested, `get` will return `Maybe.nothing`.\n\nIf you want to avoid the overhead of wrapping the result in a `Maybe`, you can use the `unsafeGet` method...\n\n```Java\nSystem.out.println(\"vector1.unsafeGet(5) = \" + vector1.unsafeGet(5));\n// *** vector1.unsafeGet(5) = 6\n\n```\n\n...but be aware, `unsafeGet` will throw an `IndexOutOfBoundsException` if you provide it an invalid index:\n```Java\nSystem.out.println(\"vector1.unsafeGet(1000) = \"  + vector1.unsafeGet(1000));\n// *** throws IndexOutOfBoundsException\n```\n\n`unsafeGet` may return `null` if that is what the underlying collection contains.\n\n### Slices\n\nYou can create slices of another `Vector` using `take`, `drop`, or `slice`.  The results of these methods are also `Vector`s, and none of them make copies of the original underlying collection.\n\n```Java\nVector\u003cInteger\u003e vector2 = vector1.take(5);\nSystem.out.println(\"vector2 = \" + vector2);\n    // *** vector2 = Vector(1, 2, 3, 4, 5)\n\nVector\u003cInteger\u003e vector3 = vector1.drop(2);\nSystem.out.println(\"vector3 = \" + vector3);\n    // *** vector3 = Vector(3, 4, 5, 6, 7, 8, 9, 10)\n\nVector\u003cInteger\u003e vector4 = vector1.slice(3, 7);\nSystem.out.println(\"vector4 = \" + vector4);\n    // *** vector4 = Vector(4, 5, 6, 7)\n```\n\n### Mapping\n\nYou can map to a new `Vector` using `fmap`.  This returns a new `Vector` and leaves the original `Vector` unaffected.\n`fmap` never makes copies, and is stack-safe.\n\n```Java\nVector\u003cInteger\u003e vector5 = vector1.fmap(n -\u003e n * 100);\n\nSystem.out.println(\"vector5 = \" + vector5);\n    // *** vector5 = Vector(100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)\n\nVector\u003cString\u003e vector6 = vector5.fmap(n -\u003e \"a\" + n + \"z\");\n\nSystem.out.println(\"vector6 = \" + vector6);\n    // *** vector6 = Vector(a100z, a200z, a300z, a400z, a500z, a600z, a700z, a800z, a900z, a1000z)\n```\n### No copies are made\n\nThe following is to prove that none of the above methods made a copy of the underlying array.   (Don't do this!)\n```Java\narr[3] = 1000;\n\nSystem.out.println(\"vector1 = \" + vector1);\n    // *** vector1 = Vector(1, 2, 3, 1000, 5, 6, 7, 8, 9, 10)\n\nSystem.out.println(\"vector2 = \" + vector2);\n    // *** vector2 = Vector(1, 2, 3, 1000, 5)\n\nSystem.out.println(\"vector3 = \" + vector3);\n    // *** vector3 = Vector(3, 1000, 5, 6, 7, 8, 9, 10)\n\nSystem.out.println(\"vector4 = \" + vector4);\n    // *** vector4 = Vector(1000, 5, 6, 7)\n\nSystem.out.println(\"vector5 = \" + vector5);\n    // *** vector5 = Vector(100, 200, 300, 100000, 500, 600, 700, 800, 900, 1000)\n\nSystem.out.println(\"vector6 = \" + vector6);\n    // *** vector6 = Vector(a100z, a200z, a300z, a100000z, a500z, a600z, a700z, a800z, a900z, a1000z)\n```\nAgain, mutation is discouraged;  the above was just to prove that no copy was made.\nWe will switch it back:\n```Java\narr[3] = 4;\n```\n### `ImmutableVector\u003cA\u003e`\nIf you want to be sure you are complete protected from mutation, you can upgrade to an `ImmutableVector`:\n\n```Java\nImmutableVector\u003cInteger\u003e vector7 = vector1.toImmutable();\n\nSystem.out.println(\"vector7 = \" + vector7);\n    // *** vector7 = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n```\nNote that `toImmutable` may make a copy of the underlying collection, but only if it is necessary.  Calling `toImmutable` on a `Vector` that is already immutable is a no-op.\n\nNow we will show that `ImmutableVector`s are safe from mutation:\n\n```Java\n arr[3] = 1000;\n\n// vector1 was affected:\nSystem.out.println(\"vector1 = \" + vector1);\n    // *** vector1 = Vector(1, 2, 3, 1000, 5, 6, 7, 8, 9, 10)\n\n// vector7 was not:\nSystem.out.println(\"vector7 = \" + vector7);\n    // *** vector7 = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n\n```\nAn `ImmutableVector\u003cA\u003e` can be used anywhere a `Vector\u003cA\u003e` is called for, but it has the additional compile-time guarantee that it is protected against mutation anywhere (at the cost of a one-time copy).\n        \nThe methods `tail`, `take`, `slice`, `drop` and `fmap` on an `ImmutableVector` all yield `ImmutableVector`s for free:\n\n```Java\nImmutableVector\u003cInteger\u003e vector8 = vector7.tail();\nImmutableVector\u003cInteger\u003e vector9 = vector7.take(5);\nImmutableVector\u003cInteger\u003e vector10 = vector7.drop(2);\nImmutableVector\u003cInteger\u003e vector11 = vector7.slice(3, 7);\nImmutableVector\u003cInteger\u003e vector12 = vector7.fmap(n -\u003e n * 100);\n```\n### Creating `ImmutableVector`s directly\nYou can construct  an `ImmutableVector` directly using `Vector.of`:\n```Java\nImmutableVector\u003cString\u003e vector13 = Vector.of(\"foo\", \"bar\", \"baz\");\n\nSystem.out.println(\"vector13 = \" + vector13);\n    // *** vector13 = Vector(foo, bar, baz)\n```\n### `NonEmptyVector\u003cA\u003e`\n`Vector.of` actually returns an instance of `ImmutableNonEmptyVector\u003cA\u003e`, which can be used where any `Vector\u003cA\u003e`, `ImmutableVector\u003cA\u003e`, or `NonEmptyVector\u003cA\u003e` is called for.\n\n```Java\n ImmutableNonEmptyVector\u003cString\u003e vector14 = Vector.of(\"foo\", \"bar\", \"baz\");\n```\n`NonEmpty` is another guarantee you can provide or require at compile-time.  `NonEmpty` provides a `head` method that is guaranteed to yield an element: \n```Java\nSystem.out.println(\"vector14.head() = \" + vector14.head());\n    // *** vector14.head() = foo\n```\nAll `NonEmptyVector\u003cA\u003e`s can be used anywhere a `Vector\u003cA\u003e` is called for, so it is a concept you can opt-in to caring about.  All the following are legal:\n```Java\nVector\u003cString\u003e vector15 = vector14;\nImmutableVector\u003cString\u003e vector16 = vector14;\nNonEmptyVector\u003cString\u003e vector17 = vector14;\n```\nHowever, if you _require_ a `NonEmptyVector`, you need to provide one at compile-time.\n```Java\nVector\u003cString\u003e vector18 = Vector.empty();\n\n// The following line won't compile!\nNonEmptyVector\u003cString\u003e vector19 = vector18;\n```\nNor will the following compile, since `Vector\u003cString\u003e` has not been proven non-empty at compile-time:\n```Java\nVector\u003cString\u003e vector20 = Vector.wrap(asList(\"foo\", \"bar\", \"baz\"));\n\n// The following line won't compile!\nNonEmptyVector\u003cString\u003e vector21 = vector20;\n```\nIf you want to upgrade to a `NonEmptyVector` at run-time, use the `toNonEmpty` or `toNonEmptyOrThrow` methods on a `Vector`.\n```Java\nMaybe\u003cNonEmptyVector\u003cString\u003e\u003e vector22 = vector21.toNonEmpty();\n\nSystem.out.println(\"vector22 = \" + vector22);\n    // *** vector22 = Just Vector(foo, bar, baz)\n\nMaybe\u003cNonEmptyVector\u003cString\u003e\u003e vector23 = vector21.toNonEmpty();\n\nSystem.out.println(\"vector23 = \" + vector23);\n    // *** vector23 = Nothing\n```\n\n## \u003ca name=\"set-examples\"\u003e`Set` examples\u003c/a\u003e\n\nTODO\n\n# \u003ca name=\"non-goals-and-trade-offs\"\u003eNon-goals and trade-offs\u003c/a\u003e\n\nThe following are either explicitly non-goals, or trade-offs made in the design of this library:\n\n## Adding or updating elements\n\nTo support updating, or even adding of elements would require sacrificing other guarantees.  Therefore these are not supported.  \n\nEven something as simple as adding an element to the end of a `Vector` is not supported, as this would either require making a copy, sacrificing O(1) random access, or compromising locality of reference.\n\n## Protection from `null`s\n\n*collection-views* does not offer full `null` protection like [Guava Immutable Collections](https://github.com/google/guava/wiki/ImmutableCollectionsExplained), which doesn't allow construction of a collection that contains any `null`s.\n\nThough not recommended, you are able to construct `Vector`s and `Set`s that contain `null` elements.  \n\nTo prevent construction of, say, a `Vector` that contains no `null`s would require examining every element of the collection you are trying to wrap.  This goes beyond what can be deemed \"low overhead\".\n\n`Vector` *does* however have a `get` method which guarantees to never return `null`, so there is _some_ level of `null` protection.  \n\n## `java.util.Collection`\n\nIt is non-goal to make *collection-views* compatible with `java.util.Collection`.  If you need to convert to a `java.util.Collection`, you can easily accomplish this with [lambda](https://palatable.github.io/lambda/)'s `toCollection` function. \n\n# \u003ca name=\"custom-views\"\u003eCustom views\u003c/a\u003e\n\nSince `Vector` and `Set` are interfaces, you can create your own custom implementations by subtyping them.\n  \nBy design, no concrete classes in this library are exposed for direct instantiation or extension.  However, some useful methods have been made available in `VectorHelpers` and `SetHelpers` to which you can delegate to handle some of the administrivia (e.g., `equals`, `toString`) in your custom implementation.\n\n# \u003ca name=\"notes\"\u003eNotes\u003c/a\u003e\n\n#### \u003ca name=\"o1-note\"\u003eO(1)\u003c/a\u003e\n\nThroughout this library, the claim of O(1) means that the number of elements in a collection has no bearing on performance.  However, the number of transformations applied to a view (such as mapping and slicing), will.  Technically, the complexity is O(k) where *k* is the number of transformations applied.  \n\n# \u003ca name=\"license\"\u003eLicense\u003c/a\u003e\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fkschuetz%2Fcollection-views.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fkschuetz%2Fcollection-views?ref=badge_shield)\n\n*collection-views* is distributed under [The MIT License](http://choosealicense.com/licenses/mit/).\n\nThe MIT License (MIT)\n\nCopyright © 2019 Kevin Schuetz\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkschuetz%2Fcollection-views","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkschuetz%2Fcollection-views","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkschuetz%2Fcollection-views/lists"}