Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04f628fcc1 | ||
|
|
5fa26bfbf3 | ||
|
|
4d3eaaf604 | ||
|
|
33ab7c48bf | ||
|
|
1f4784c75e | ||
|
|
ae5a4ea818 | ||
|
|
5d66f7b453 | ||
|
|
12af656150 | ||
|
|
603ff3df0f | ||
|
|
b712981718 | ||
|
|
863d1a1027 | ||
|
|
6287da8efe | ||
|
|
c27e852ccb | ||
|
|
0157765628 | ||
|
|
8689037ceb | ||
|
|
03a8914986 |
@@ -1,5 +1,10 @@
|
||||
# Changelog of versions
|
||||
|
||||
### Version 0.6.1
|
||||
- Fixed: FIFO queue crashing when the last index is before the first index when peek is called.
|
||||
- Fixed: FIFO queue only clears the array if it was in use.
|
||||
- Added: Sorted Method for the stream replacing functions.
|
||||
|
||||
### Version 0.6.0
|
||||
- Added: addOrGet for sets.
|
||||
- Added: Async API which allows to easily execute Iterables/Collections offthread without the complexity.
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||

|
||||
|
||||
[](https://jitpack.io/#Speiger/Primitive-Collections)
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||

|
||||
# Primitive-Collections
|
||||
This is a Simple Primitive Collections Library aimed to outperform Java's Collection Library and FastUtil.
|
||||
Both in Performance and Quality of Life Features.
|
||||
|
||||
This is a Simple Primitive Collections Library i started as a hobby Project.
|
||||
It is based on Java's Collection Library and FastUtil.
|
||||
But its focus is a different one.
|
||||
## Benchmarks
|
||||
Benchmarks can be found here: [[Charts]](https://github.com/Speiger/Primitive-Collections-Benchmarks/blob/master/BENCHMARKS-CHARTS.md), [[Tables]](https://github.com/Speiger/Primitive-Collections-Benchmarks/blob/master/BENCHMARKS.md)
|
||||
|
||||
## Special Features
|
||||
[Here](features.md) you find a set of features added to Primitive Collections.
|
||||
These are designed to improve performance or to provide Quality of Life.
|
||||
|
||||
## Main Features:
|
||||
- ArrayLists / LinkedLists / CopyOnWriteLists
|
||||
@@ -15,80 +22,30 @@ But its focus is a different one.
|
||||
- ConcurrentHashMaps
|
||||
- Priority Queues
|
||||
- Streams & Functional Queries
|
||||
- SplitIterators
|
||||
- Iterators
|
||||
- Split/Iterators
|
||||
- Pairs
|
||||
- Unary/Functions
|
||||
- Suppliers
|
||||
- Bi/Consumers
|
||||
- AsyncBuilders
|
||||
|
||||
## Current Level of Stability
|
||||
Since this is a relatively new Library, stability was not perfect and some areas are not perfect yet.
|
||||
Thanks to [ben-manes](https://github.com/ben-manes) we now have Roughly 160k unit test covering Maps/Sets/Lists.
|
||||
These tests cover Javas Collection API completely and ensuring a Stable implementation.
|
||||
These freshly added tests allowed me to squash thousands of issues according to Googles Test Library (Guava-Tests).
|
||||
These will be expanded on as time goes on.
|
||||
|
||||
### Benchmarks
|
||||
Benchmarks can be found here: [Click Me](https://github.com/Speiger/Primitive-Collections-Benchmarks/tree/master)
|
||||
|
||||
## Specialized Functions
|
||||
New Specialized functions that were added to increase performance or reduce allocations or Quality Of life.
|
||||
To highlight things that may be wanted.
|
||||
- Iterable:
|
||||
- map/flatMap/arrayFlatMap: A Light weight version of Stream.map().
|
||||
- findFirst: Allows to find the first element of a Predicated Iterable.
|
||||
- filter: Allows to filter unwanted elements for wrapped Iterable
|
||||
- matchAny/matchNone/matchAll: Allows to find elements in a collection.
|
||||
- count: counts all valid elements in a collection.
|
||||
- forEach: Allows to input a second element into a forEach move allowing for more flexibility for Method References
|
||||
- reduce/limit/peek/distinct: Light Versions of the Stream variant, to reduce Stream usage.
|
||||
- pour: a function that allows to collect all elements within the Collection
|
||||
- Collection:
|
||||
- addAll: addAll array version
|
||||
- containsAny: Allows to test if another collection contains an of the elements of the tested collection.
|
||||
- primitiveStream: Provides access to the closest Java Stream Type.
|
||||
- copy: shallowCopies the collection, used instead of clone because this is better to use.
|
||||
(subCollections not supported for obvious reasons)
|
||||
- toArray: the ToArray function from Java9 and newer that uses a Functional interface and can use a method reference
|
||||
- List:
|
||||
- add/get/removeElements (From FastUtil): Allows to add/get/remove an Array into/from a list. Just with less overhead
|
||||
- extractElements: Allows to remove a Range of elements from the List and get what was removed.
|
||||
- Unstable Sort(From FastUtil): Uses a faster but not stable sort (Quick-Sort as example) to sort the list.
|
||||
- addIfAbsent/Present: adds a element only if absent/present in the list
|
||||
- swapRemove: deletes a desired element and inserts the last element in its place instead of leftshifting elements.
|
||||
- SortedSet:
|
||||
- addAndMoveToFirst/Last (From FastUtil but moved to Interface): Allows to add a element to the first/last position of a sorted set.
|
||||
- moveToFirst/Last: Moves the desired element at the first/last position of the SortedSet.
|
||||
- pollFirst/Last: Allows to poll the first/last element of the set.
|
||||
- Map:
|
||||
- putAll: putAll but in Array form.
|
||||
- putAllIfAbsent: Puts only the elements that are absent.
|
||||
- addTo (Only Primitives Values) (From FastUtil but moved to Interface): allows to add to the value of a given key. If not present it will be added. (Accumulator)
|
||||
- subFrom (Only Primitive Values): allows to subtract from the value of a given key. If value reached getDefaultReturnValue() element will be removed.
|
||||
- addToAll: Same as addTo but bulkVersion.
|
||||
- removeOrDefault: removes a Element and if not present returns the default value instead of the present value.
|
||||
- mergeAll: BulkVersion of Merge function.
|
||||
- supplyIfAbsent: A Supplier based computeIfAbsent
|
||||
- Sorted Map:
|
||||
- addAndMoveToFirst/Last (From FastUtil but moved to Interface): Allows to add a element to the first/last position of a sorted Map.
|
||||
- moveToFirst/Last: Moves the desired element at the first/last position of the Map.
|
||||
- getAndMoveToFirst/Last: gets the element and moves it to the first/last position. Replicating a Optional LinkedHashMap feature.
|
||||
- pollFirst/LastKey: Allows to poll the first/last element.
|
||||
- first/LastValue: Allows to get the first/last value from the Map.
|
||||
|
||||
|
||||
# Notes about Versions
|
||||
Any 0.x.0 version (Minor) can be reason for massive changes including API.
|
||||
To ensure that problems can be dealt with even if it is breaking the current API.
|
||||
Any breaking changes will be Documented (once 1.0 is released)
|
||||
|
||||
Also to save space every 0.0.x (Patch) that is 2 Minor Versions behind will be removed.
|
||||
So if 0.5.0 is released every 0.3.x patch will be deleted, except for the last patch for that minor version.
|
||||
|
||||
# How to install
|
||||
Using Gradle:
|
||||
Using Jitpack Gradle
|
||||
```gradle
|
||||
repositories {
|
||||
maven {
|
||||
url = "https://jitpack.io"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
implementation 'com.github.Speiger:Primitive-Collections:0.6.1'
|
||||
}
|
||||
```
|
||||
Using Custom Gradle:
|
||||
```gradle
|
||||
repositories {
|
||||
maven {
|
||||
@@ -96,13 +53,17 @@ repositories {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
compile 'de.speiger:Primitive-Collections:0.6.0'
|
||||
implementation 'de.speiger:Primitive-Collections:0.6.1'
|
||||
}
|
||||
```
|
||||
Direct:
|
||||
|
||||
<details>
|
||||
<summary>Direct: </summary>
|
||||
<p>
|
||||
|
||||
| Version | Jar | Sources | Java Doc |
|
||||
|--------- |------------------------------------------------------------------------------------------------------------------------------ |-------------------------------------------------------------------------------------------------------------------------------------- |-------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 0.6.1 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.1/Primitive-Collections-0.6.1.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.1/Primitive-Collections-0.6.1-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.1/Primitive-Collections-0.6.1-javadoc.jar) |
|
||||
| 0.6.0 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.0/Primitive-Collections-0.6.0.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.0/Primitive-Collections-0.6.0-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.0/Primitive-Collections-0.6.0-javadoc.jar) |
|
||||
| 0.5.3 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.3/Primitive-Collections-0.5.3.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.3/Primitive-Collections-0.5.3-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.3/Primitive-Collections-0.5.3-javadoc.jar) |
|
||||
| 0.5.2 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.2/Primitive-Collections-0.5.2.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.2/Primitive-Collections-0.5.2-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.2/Primitive-Collections-0.5.2-javadoc.jar) |
|
||||
@@ -116,6 +77,9 @@ Direct:
|
||||
| 0.4.0 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.0/Primitive-Collections-0.4.0.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.0/Primitive-Collections-0.4.0-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.0/Primitive-Collections-0.4.0-javadoc.jar) |
|
||||
| 0.3.6 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.3.6/Primitive-Collections-0.3.6.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.3.6/Primitive-Collections-0.3.6-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.3.6/Primitive-Collections-0.3.6-javadoc.jar) |
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
# Contributing
|
||||
If you want to contribute.
|
||||
This project is created using gradle and java and my Template Library only. Nothing extra.
|
||||
@@ -137,6 +101,3 @@ The SourceCode can be generated via:
|
||||
to build the jar:
|
||||
/gradlew.bat build
|
||||
do not combine the commands because they can not be executed at the same time.
|
||||
|
||||
## Current Down Sides (Random order)
|
||||
- Documentation is only present at the lowest level for most cases and needs a typo fixing.
|
||||
|
||||
+4
-1
@@ -18,7 +18,7 @@ repositories {
|
||||
}
|
||||
|
||||
archivesBaseName = 'Primitive Collections'
|
||||
version = '0.6.0';
|
||||
version = '0.6.1';
|
||||
|
||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaVersion.current();
|
||||
|
||||
@@ -47,6 +47,7 @@ dependencies {
|
||||
builderImplementation 'de.speiger:Simple-Code-Generator:1.0.7'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'com.google.guava:guava-testlib:31.0.1-jre'
|
||||
|
||||
}
|
||||
|
||||
task generateSource(type: JavaExec) {
|
||||
@@ -82,6 +83,8 @@ task srcJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
compileJava.dependsOn generateGithubSource
|
||||
|
||||
javadoc.failOnError = false
|
||||
javadoc.options.memberLevel = JavadocMemberLevel.PUBLIC
|
||||
javadoc.options.quiet()
|
||||
|
||||
+402
@@ -0,0 +1,402 @@
|
||||
## Quality Of Life Features
|
||||
New Specialized functions/classes that were added to increase performance and/or reduce allocations and/or for Quality of life.
|
||||
|
||||
|
||||
# Functions
|
||||
|
||||
Functions that increase performance or are quality of life in their nature.
|
||||
|
||||
<details>
|
||||
<summary>Iterable</summary>
|
||||
<p>
|
||||
|
||||
## Functional Functions
|
||||
|
||||
Java adds themselves a lot of functional functions like,
|
||||
- Stream:
|
||||
- Map/FlatMap
|
||||
- Filter/Distinct/Limit/Sorted
|
||||
- Count/FindFirst/Collect
|
||||
- Peek/ForEach/Reduce
|
||||
- anyMatch/allMatch/NoneMatch
|
||||
|
||||
that allows to process a collection in a functional way.
|
||||
But these require streams which have a lot of Overhead in their nature.
|
||||
|
||||
Luckly Primitive Collections adds replacement functions that provide the same functionality but with minimal overhead.
|
||||
Here are some examples:
|
||||
```java
|
||||
public ObjectIterable<Path> toPath(ObjectIterable<String> iterable) {
|
||||
return iterable.map(Paths::get).filter(Files::exist);
|
||||
}
|
||||
|
||||
public Iterable<Path> toPath(Iterable<String> iterable) {
|
||||
return ObjectIterables.map(iterable, Paths::get).filter(Files::exist);
|
||||
}
|
||||
|
||||
public int sum(IntIterable iterable) {
|
||||
return iterable.reduce(Integer::sum);
|
||||
}
|
||||
```
|
||||
|
||||
## AsyncAPI</summary>
|
||||
|
||||
The AsyncAPI is a Feature that simplifies the processing of Collections on a separate thread.
|
||||
It uses the same concept as Javas Stream API but uses the light weight Functions from Primitive Collections to achieve the same thing.
|
||||
Unlike Javas StreamAPI the AsyncAPI is always singleThreaded and more like Javas CompletableFuture, which you can await or let run Asynchronous.
|
||||
|
||||
The Goal is it to simplify the processing of Collections asynchronous.
|
||||
Especially on tasks which don't have to be finished instantly but can be processed on the side.
|
||||
|
||||
Here is a example of how the API works.
|
||||
```java
|
||||
public void processFiles(ObjectCollection<String> potentialFiles) {
|
||||
potentialFiles.asAsync()
|
||||
.map(Paths::get).filter(Files::exists) //Modifies the collection (Optional)
|
||||
.forEach(Files::delete) //Creates the action (Required)
|
||||
.callback(T -> {}} //Callback on completion, still offthread (Optional)
|
||||
.execute() //Starts the task. (Required)
|
||||
}
|
||||
```
|
||||
</p>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Collection</summary>
|
||||
<p>
|
||||
|
||||
These are functions specific to the Collections interface, stuff that everyone wished it was present to be in the first place.
|
||||
|
||||
## AddAll (Array)
|
||||
Adding Elements to a Collection usually requires either a for loop or a Arrays.wrap().
|
||||
This isn't an issue with Primitive Collections.
|
||||
```java
|
||||
public void addMonths(ObjectCollection<String> months) {
|
||||
months.addAll("January", "February", "March", "April", "May", "June", "July", "August", "September, "October", November", "December");
|
||||
}
|
||||
|
||||
public void addElements(ObjectCollection<String> result, String[] elements) {
|
||||
result.addAll(elements, 0, 5); //elements, offset, length
|
||||
}
|
||||
```
|
||||
|
||||
## containsAny
|
||||
Everyone hates comparing if 2 collections have part of each other included.
|
||||
The solution usually requires for loops and keeping track if things were found or not.
|
||||
And every Java Developer had this issue at least once and wished for a clean solution.
|
||||
```java
|
||||
public boolean hasMonths(ObjectCollection<Month> target, Collection<Month> toFind) {
|
||||
return target.containsAny(toFind);
|
||||
}
|
||||
```
|
||||
|
||||
## Copy
|
||||
Collections get copied every now and then. There is only 2 ways that this happens.
|
||||
Javas Clone API or using Constructor that supports collections.
|
||||
Javas Clone API is kinda in a Zombie state, where it is supported or not. Its not really clear if you should use it or not.
|
||||
The Clone CloneNotSupportedException isn't helping either, causing more janky code.
|
||||
While a Constructor can only support so much and testing for every case isn't really viable.
|
||||
|
||||
So the decision was made to straight out not support clone and instead add a copy function which doesn't use a checked exception.
|
||||
It works exactly like the clone function. In a sense where it creates a shallow copy. (SubCollections do not work for obvious reasons)
|
||||
```java
|
||||
public IntCollection copy(IntCollection original) {
|
||||
return original.copy();
|
||||
}
|
||||
```
|
||||
|
||||
## Primitive Streams
|
||||
Since Javas Stream API is still really useful, even at its shortcomings, Primitive Collections provides easy access to it.
|
||||
Generic Streams and the closest Primitive Stream will be provided. So a FloatCollection goes to a DoubleStream.
|
||||
```java
|
||||
public IntStream createStream(IntCollection source) {
|
||||
return source.primitiveStream();
|
||||
}
|
||||
```
|
||||
|
||||
## RemoveAll/RetainAll with listener
|
||||
Ever wanted use removeAll or retainAll and wanted to know what elements actually got deleted?
|
||||
The usual solution is to create a copy and then apply it to the original and cross reference them.
|
||||
Which leads to really messy code and just hasn't a clean solution.
|
||||
Luckly Primitive Collections got you covered.
|
||||
```java
|
||||
public void removeInvalidFiles(ObjectCollections<Path> files, ObjectCollection<Path> toRemove) {
|
||||
files.removeAll(toRemove, T -> System.out.println(T));
|
||||
}
|
||||
|
||||
public void removeInvalidFiles(ObjectCollections<Path> files, ObjectCollection<Path> toKeep) {
|
||||
files.retainFiles(toKeep, T -> System.out.println(T));
|
||||
}
|
||||
```
|
||||
|
||||
## ToArray
|
||||
Primitive Collections supports primitive/generic toArray functions for its Primitive Collections.
|
||||
On top of that the Object side gets a Java9 function ported back to java8, which uses a functional Interface to create the backing array.
|
||||
```java
|
||||
public Integer[] toArray(IntCollection c) {
|
||||
return c.toArray(new Integer[c.size]);
|
||||
}
|
||||
|
||||
public int[] toArray(IntCollection c) {
|
||||
return c.toIntArray();
|
||||
}
|
||||
|
||||
public String[] toArray(ObjectCollection<String> c) {
|
||||
return c.toArray(String::new);
|
||||
}
|
||||
```
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>List</summary>
|
||||
<p>
|
||||
|
||||
These functions are List specific functions, a couple of these are from FastUtil.
|
||||
|
||||
## add/get/remove/extractElements
|
||||
These functions really useful helper functions. 3 of which are copied from FastUtil. (extract is from Primitive Collections)
|
||||
They are basically array forms of addAll, getAll, removeRange and removeAndGetRange. This is the simplest way to describe it.
|
||||
|
||||
Here some example:
|
||||
```java
|
||||
public void addAll(DoubleList list) {
|
||||
list.addElements(0D, 12.2D, 3.5D, 4.2D);
|
||||
}
|
||||
|
||||
public double[] getAll(DoubleList list, int amount) {
|
||||
double[] result = new double[amount];
|
||||
list.getElements(0, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void removeRange(FloatList list) {
|
||||
list.removeElements(5, 14);
|
||||
}
|
||||
|
||||
public float[] extractRange(FloatList list) {
|
||||
return list.extractElements(5, 14); //Returns the removed elements
|
||||
}
|
||||
```
|
||||
|
||||
## addIfPresent/addIfAbsent
|
||||
These two functions are simple helper functions that check internally if a element is present or absent before adding them to the List.
|
||||
Removing the need for a contains or indexOf check every time you want to add a element.
|
||||
While it is of course better to use a set, there is cases where this is still useful.
|
||||
|
||||
```java
|
||||
public void addElements(IntList list, int... numbersToAdd) {
|
||||
for(int e : numbersToAdd) {
|
||||
list.addIfAbsent(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addExisting(ObjectList<String> list, String... textToAdd) {
|
||||
for(String s : textToAdd) {
|
||||
list.addIfPresent(s);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## SwapRemove
|
||||
Lists when removing a Element shift usually the backing array to the left based to shrink the elements.
|
||||
While that isn't computational expensive with LinkedLists, it is with ArrayLists.
|
||||
Here comes swapRemove into play, which just removes the desired elements and instead of shifting left puts the last element in its place.
|
||||
This reduces the data copying required down to 1 element instead of an array.
|
||||
|
||||
```java
|
||||
public int remove(IntList elements, int indexToRemove) {
|
||||
return elements.swapRemove(indexToRemove);
|
||||
}
|
||||
```
|
||||
|
||||
## Unstable Sort (From FastUtil)
|
||||
Unstable Sort uses a Faster but not as stable sorting algorithm to sort the Collection.
|
||||
Stable doesn't mean crashing, but more like that the result isn't exactly perfectly sorted.
|
||||
```java
|
||||
public void sort(List<Month> list, Comparator<Month> sorter) {
|
||||
list.unstableSort(sorter);
|
||||
}
|
||||
```
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Map</summary>
|
||||
<p>
|
||||
|
||||
These functions are based on the Map interface. Useful functions you really would want.
|
||||
|
||||
## addTo/subFrom
|
||||
addTo (from FastUtil) and subFrom are mathematically functions that either add or subtract from the value of a given key.
|
||||
And if the key isn't present or would result in the default value it will either add or remove the entry from the Map. Given the circumstance.
|
||||
This is a really useful function and I wish FastUtil made it accessible by default but sadly it isn't.
|
||||
To simplify the explanation:
|
||||
- addTo if no element is present puts in the desired number, otherwise it sums up the two values.
|
||||
- subFrom if a element is present subtracts from it, if the element reaches the default value it removes the element from the map. If not present it will be ignored.
|
||||
```java
|
||||
public void addTo(Object2DoubleMap<Month> map, Month key, double averageTrainsRepaired) {
|
||||
map.addTo(key, averageTrainsRepaired);
|
||||
}
|
||||
|
||||
public void subFrom(Long2IntMap map, long key, double amount) {
|
||||
map.subFrom(key, amount);
|
||||
}
|
||||
```
|
||||
|
||||
## addToAll
|
||||
Simple bulk version of the addTo function since sometimes you want to merge 2 maps for summing.
|
||||
Especially if your work is multi-threaded this can become useful.
|
||||
|
||||
```java
|
||||
public void addTo(Object2DoubleMap<Month> map, Object2DoubleMap<Month> trainsRepaired) {
|
||||
map.addToAll(trainsRepaired);
|
||||
}
|
||||
```
|
||||
|
||||
## mergeAll
|
||||
This is a simple bulk version of merge since merging 2 maps is more frequent then people might think and leads to cleaner code too.
|
||||
```java
|
||||
public void merge(Long2ByteMap result, Long2ByteMap toMerge) {
|
||||
result.mergeAll(toMerge);
|
||||
}
|
||||
```
|
||||
|
||||
## putAll (Array)
|
||||
This allows to put keys and values as arrays instead of requiring a WrapperMap to insert the elements.
|
||||
Not as useful as the Collections.addAll variant but still really useful.
|
||||
```java
|
||||
public void putAll(Int2DoubleMap map, int[] keys, double[] values) {
|
||||
map.put(keys, values, 2, 15);
|
||||
}
|
||||
```
|
||||
|
||||
## putAllIfAbsent
|
||||
putAll has this usual quirk where if a element is present it will replace the value, and sometimes this is not wanted.
|
||||
While putIfAbsent exists it has no real mass form and makes iterative solutions really uneasy to use.
|
||||
Here comes the helper function that gets rid of that problem.
|
||||
```java
|
||||
public void merge(Long2ObjectMap<String> regionFiles, Long2ObjectMap<String> toAdd) {
|
||||
regionFiles.putAllIfAbsent(toAdd);
|
||||
}
|
||||
```
|
||||
|
||||
## removeOrDefault
|
||||
getOrDefault is a really useful function that find use cases all the time.
|
||||
Sadly by default there is no variant of removeOrDefault, while it has less cases still could be used every now and then.
|
||||
This function basically tries to remove a element, if it is not present it will just return your desired default.
|
||||
```java
|
||||
public Path removeCache(Long2ObjectMap<Path> caches, long key) {
|
||||
return caches.removeOrDefault(key, Paths.get("nuclearFun"));
|
||||
}
|
||||
```
|
||||
|
||||
## supplyIfAbsent
|
||||
This one is one of my favorites. computeIfAbsent is a really useful function.
|
||||
But in 90% of the cases I use it the value is a collection.
|
||||
This becomes really annoying since methodReferences are faster/cleaner then Lambdas in my opinion.
|
||||
supplyIfAbsent is basically computeIfAbsent but without a key, perfect for the default constructor of a collection.
|
||||
This is the whole reason it exists.
|
||||
```java
|
||||
public void example(Int2ObjectMap<List<String>> map, Int2ObjectMap<String> toAdd) {
|
||||
for(Entry<String> entry : toAdd.entrySet()) {
|
||||
map.supplyIfAbsent(entry.getKey(), ObjectArrayList::new).add(entry.getValue());
|
||||
}
|
||||
}
|
||||
```
|
||||
</p>
|
||||
</details>
|
||||
|
||||
# Interfaces
|
||||
|
||||
Interfaces that provide essential or quality of life features.
|
||||
|
||||
<details>
|
||||
<summary>ITrimmable</summary>
|
||||
<p>
|
||||
|
||||
The ITrimmable is Accessor interface that allows you to access a couple helper functions to control the size of your collections.
|
||||
This was created for the constant casting requirement to implementations just to shrink collections which get annoying over time.
|
||||
|
||||
## trim
|
||||
This function basically trims down the backing implementation to use as little memory as required to store the elements in the collection.
|
||||
Optionally a desired minimum size can be provided as of how low it should go at worst.
|
||||
|
||||
## clearAndTrim
|
||||
when you want to reset a Collection completely you have 2 options. Clear it and then call trim, or recreate the collection.
|
||||
clearAndTrim solves this problem by clearing the collection and trimming it in one go, reducing overhead to achieve such a thing.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>IArray</summary>
|
||||
<p>
|
||||
|
||||
IArray is a Accessor interface that provides more access to collections by providing tools to grow your collection as needed.
|
||||
While putAll/addAll try to ensure that you have enough room for your elements, this is not really a solution for all cases.
|
||||
Sometimes you need to ensure the Collection is pre-initialized.
|
||||
IArray grants you that control.
|
||||
|
||||
There is also a type specific that provides you access to the backing array implementation of Lists for faster Iteration but that is a really specific case.
|
||||
|
||||
## ensureCapacity
|
||||
Ensures that your collection has enough storage for the elements you want to insert.
|
||||
|
||||
## elements (ITypeSpecificArray)
|
||||
Allows you access to the backing array of a List which is for people who know what they are doing.
|
||||
There is a lambda version of this function too which makes sure for synchronizedLists that you are the only one accessing the array.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>OrderedMap</summary>
|
||||
<p>
|
||||
|
||||
The OrderedMap is a real edge case interface that was born for a need.
|
||||
FastUtil added functions that were like moveToFirst which were hardcoded to the implementation.
|
||||
They didn't fit into something like a SortedMap because the Set wasn't sorted.
|
||||
So OrderedMap was born, which isn't random but ordered in a specific way that can be changed.
|
||||
|
||||
## getAndMoveToFirst/getAndMoveToLast
|
||||
Returns a desired element and removing it to the first/last spot in the Map. Moving the element that was at its spot after/before it.
|
||||
|
||||
## moveToFirst/moveToLast
|
||||
Moves the element if present to the first/last spot in the Map. Moving the element that was at its spot after/before it.
|
||||
Returns true if the element was actually moved.
|
||||
|
||||
## putAndMoveToFirst/putAndMoveToLast
|
||||
Adds the desired element and moves it to first/last spot in the Map. Moving the element that was at its spot after/before it.
|
||||
|
||||
## firstKey/lastKey (Optional poll)
|
||||
Provides access to the current first/last key of the Map.
|
||||
Optionally can be polled if desired.
|
||||
|
||||
## firstValue/lastValue
|
||||
Provides access to the current first/last value of the Map.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>OrderedSet</summary>
|
||||
<p>
|
||||
|
||||
The OrderedSet is a real edge case interface that was born for a need.
|
||||
FastUtil added functions that were like moveToFirst which were hardcoded to the implementation.
|
||||
They didn't fit into something like a SortedSet because the Set wasn't sorted.
|
||||
So OrderedSet was born, which isn't random but ordered in a specific way that can be changed.
|
||||
|
||||
## addAndMoveToFirst/addAndMoveToLast
|
||||
Adds the desired element and moves it to first/last spot in the Collection. Moving the element that was at its spot after/before it.
|
||||
|
||||
## moveToFirst/moveToLast
|
||||
Moves the element if present to the first/last spot in the Collection. Moving the element that was at its spot after/before it.
|
||||
Returns true if the element was actually moved.
|
||||
|
||||
## first/last (Optional poll)
|
||||
Provides access to the current first/last element of the set.
|
||||
Optionally can be polled if desired.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
+11
@@ -5,9 +5,11 @@ import java.util.function.Consumer;
|
||||
#if !TYPE_OBJECT
|
||||
|
||||
import speiger.src.collections.PACKAGE.functions.CONSUMER;
|
||||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||||
import speiger.src.collections.objects.collections.ObjectIterable;
|
||||
#else
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.Comparator;
|
||||
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
|
||||
@@ -156,6 +158,15 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
|
||||
return ITERABLES.limit(this, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper function to reduce the usage of Streams and allows to sort the elements
|
||||
* @param sorter that sorts the elements.
|
||||
* @return a Iterable that is sorted
|
||||
*/
|
||||
default ITERABLE KEY_GENERIC_TYPE sorted(COMPARATOR KEY_GENERIC_TYPE sorter) {
|
||||
return ITERABLES.sorted(this, sorter);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper function to reduce the usage of Streams and allows to preview elements before they are iterated through
|
||||
* @param action the action that should be applied
|
||||
|
||||
+7
-2
@@ -106,11 +106,16 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
if(first != last) {
|
||||
#if TYPE_OBJECT
|
||||
Arrays.fill(array, null);
|
||||
#endif
|
||||
first = last = 0;
|
||||
}
|
||||
else if(first != 0) {
|
||||
first = last = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(KEY_TYPE e) {
|
||||
@@ -152,9 +157,9 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
|
||||
|
||||
@Override
|
||||
public KEY_TYPE peek(int index) {
|
||||
if(first == last || index < 0 || index > size()) throw new NoSuchElementException();
|
||||
if(first == last || index < 0 || index >= size()) throw new NoSuchElementException();
|
||||
index += first;
|
||||
return index > array.length ? array[index-array.length] : array[index];
|
||||
return index >= array.length ? array[index-array.length] : array[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+13
-1
@@ -7,12 +7,13 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
|
||||
import speiger.src.collections.PACKAGE.functions.CONSUMER;
|
||||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||||
#else
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.Comparator;
|
||||
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.collections.ITERABLE;
|
||||
@@ -172,6 +173,17 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the elements inside of the Iterable.
|
||||
* This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it, and this will affect the pausing feature.
|
||||
* @param sorter that sorts the elements.
|
||||
* @return self with a sorter applied
|
||||
*/
|
||||
public ASYNC_BUILDER KEY_GENERIC_TYPE sorted(COMPARATOR KEY_GENERIC_TYPE sorter) {
|
||||
iterable = ITERABLES.sorted(iterable, sorter);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to preview elements before they are processed
|
||||
* @param action the action that should be applied
|
||||
|
||||
@@ -3,6 +3,8 @@ package speiger.src.collections.PACKAGE.utils;
|
||||
import java.util.Objects;
|
||||
#if TYPE_BOOLEAN
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
#else if TYPE_OBJECT
|
||||
import java.util.Comparator;
|
||||
#endif
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
@@ -12,8 +14,11 @@ import speiger.src.collections.PACKAGE.collections.ITERABLE;
|
||||
import speiger.src.collections.objects.collections.ObjectIterable;
|
||||
import speiger.src.collections.objects.collections.ObjectIterator;
|
||||
import speiger.src.collections.PACKAGE.functions.CONSUMER;
|
||||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
import speiger.src.collections.PACKAGE.lists.LIST;
|
||||
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
|
||||
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
|
||||
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
|
||||
#if !TYPE_BOOLEAN
|
||||
@@ -164,6 +169,30 @@ public class ITERABLES
|
||||
return new LimitedIterableBRACES(wrap(iterable), limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper function that sorts the Iterable.
|
||||
* This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it.
|
||||
* @param iterable that should be sorted
|
||||
* @param sorter that sorts the iterable. Can be null.
|
||||
* @Type(T)
|
||||
* @return a sorted iterable.
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE sorted(ITERABLE KEY_GENERIC_TYPE iterable, COMPARATOR KEY_GENERIC_TYPE sorter) {
|
||||
return new SortedIterableBRACES(iterable, sorter);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper function that sorts the Iterable from a Java Iterable
|
||||
* This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it.
|
||||
* @param iterable that should be sorted
|
||||
* @param sorter that sorts the iterable. Can be null.
|
||||
* @Type(T)
|
||||
* @return a sorted iterable.
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE sorted(Iterable<? extends CLASS_TYPE> iterable, COMPARATOR KEY_GENERIC_TYPE sorter) {
|
||||
return new SortedIterableBRACES(wrap(iterable), sorter);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper function that allows to preview the result of a Iterable.
|
||||
* @param iterable that should be peeked at
|
||||
@@ -359,6 +388,42 @@ public class ITERABLES
|
||||
#endif
|
||||
}
|
||||
|
||||
private static class SortedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
|
||||
{
|
||||
ITERABLE KEY_GENERIC_TYPE iterable;
|
||||
COMPARATOR KEY_GENERIC_TYPE sorter;
|
||||
|
||||
public SortedIterable(ITERABLE KEY_GENERIC_TYPE iterable, COMPARATOR KEY_GENERIC_TYPE sorter) {
|
||||
this.iterable = iterable;
|
||||
this.sorter = sorter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITERATOR KEY_GENERIC_TYPE iterator() {
|
||||
return ITERATORS.sorted(iterable.iterator(), sorter);
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public void forEach(CONSUMER action) {
|
||||
Objects.requireNonNull(action);
|
||||
LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
|
||||
iterable.forEach(list::add);
|
||||
list.unstableSort(sorter);
|
||||
list.forEach(action);
|
||||
}
|
||||
#else
|
||||
@Override
|
||||
public void forEach(Consumer<? super CLASS_TYPE> action) {
|
||||
Objects.requireNonNull(action);
|
||||
LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
|
||||
iterable.forEach(list::add);
|
||||
list.unstableSort(sorter);
|
||||
list.forEach(action);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static class DistinctIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
|
||||
{
|
||||
ITERABLE KEY_GENERIC_TYPE iterable;
|
||||
|
||||
@@ -3,6 +3,7 @@ package speiger.src.collections.PACKAGE.utils;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
#if TYPE_OBJECT
|
||||
import java.util.Comparator;
|
||||
import java.util.function.CONSUMER;
|
||||
#endif
|
||||
|
||||
@@ -11,6 +12,7 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
import speiger.src.collections.objects.collections.ObjectIterator;
|
||||
import speiger.src.collections.objects.utils.ObjectIterators;
|
||||
import speiger.src.collections.PACKAGE.functions.CONSUMER;
|
||||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
|
||||
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
|
||||
@@ -235,6 +237,30 @@ public class ITERATORS
|
||||
return new LimitedIteratorBRACES(wrap(iterator), limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper function that sorts the Iterator beforehand.
|
||||
* This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it.
|
||||
* @param iterator that should be sorted.
|
||||
* @param sorter the sorter of the iterator. Can be null.
|
||||
* @Type(T)
|
||||
* @return a new sorted iterator
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE sorted(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE sorter) {
|
||||
return new SortedIteratorBRACES(iterator, sorter);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper function that sorts the Iterator beforehand from a Java Iterator.
|
||||
* This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it.
|
||||
* @param iterator that should be sorted.
|
||||
* @param sorter the sorter of the iterator. Can be null.
|
||||
* @Type(T)
|
||||
* @return a new sorted iterator
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE sorted(Iterator<? extends CLASS_TYPE> iterator, COMPARATOR KEY_GENERIC_TYPE sorter) {
|
||||
return new SortedIteratorBRACES(wrap(iterator), sorter);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper function that allows to preview the result of a Iterator.
|
||||
* @param iterator that should be peeked at
|
||||
@@ -871,6 +897,35 @@ public class ITERATORS
|
||||
}
|
||||
}
|
||||
|
||||
private static class SortedIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
|
||||
{
|
||||
ITERATOR KEY_GENERIC_TYPE iterator;
|
||||
COMPARATOR KEY_GENERIC_TYPE sorter;
|
||||
LIST KEY_GENERIC_TYPE sortedElements = null;
|
||||
int index = 0;
|
||||
|
||||
public SortedIterator(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE sorter) {
|
||||
this.iterator = iterator;
|
||||
this.sorter = sorter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if(sortedElements == null) {
|
||||
boolean hasNext = iterator.hasNext();
|
||||
sortedElements = hasNext ? pour(iterator) : LISTS.empty();
|
||||
if(hasNext) sortedElements.unstableSort(sorter);
|
||||
}
|
||||
return index < sortedElements.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE NEXT() {
|
||||
if(!hasNext()) throw new IllegalStateException("End of Iterator");
|
||||
return sortedElements.GET_KEY(index++);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DistinctIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
|
||||
{
|
||||
ITERATOR KEY_GENERIC_TYPE iterator;
|
||||
|
||||
Reference in New Issue
Block a user