Author SHA1 Message Date
Speiger 2a97d017b7 1.0.0 release for now 2026-05-15 01:42:51 +02:00
Speiger 374b027120 Fixed the last unit tests 2026-05-15 00:04:54 +02:00
Speiger 21ccbee3b2 Disabled Google Tests that we don't have to deal. 2026-05-14 21:32:16 +02:00
Speiger 58a9eb38b4 Loads of additions.
-Added: Indirect Sorters.
-Added: ReferenceMaps
-Fixed: A bunch of smaller bugs found due to tests
2026-05-14 19:21:38 +02:00
Speiger 2f1525ab57 Fixes and new updates.
- Added: Collectors to lists/queues/sets
- Fixed: Bugs in linked hash sets.
- Fixed: Bugs in unit tests.
2026-05-14 02:51:38 +02:00
Speiger 9f46091282 Added Tests for Ordered Maps and more work on completing the
implementation
2026-05-12 13:37:22 +02:00
Speiger 3d39d5526d Breaking update
- Added: Optionals for the missing JDK ones.
- Removed: Default values for Reduce and FindFirst. Using Optionals
instead.
2026-05-11 18:00:00 +02:00
Speiger c6f656ee66 Switched to yearly activity 2026-05-11 00:36:08 +02:00
Speiger f0139d1a22 Fixed Badge Generator 2026-05-11 00:34:48 +02:00
Speiger 58e20bb513 Fixed Enums 2026-05-11 00:10:44 +02:00
Speiger 502f22cea3 Removed java 25 support. Gradlew isn't supporting this yet. 2026-05-10 22:11:18 +02:00
Speiger 90e3b7110a Updated Actions 2026-05-10 22:09:21 +02:00
Speiger a26106cc89 Fixed a bunch of Iterator code and implemented Reverse Map/Set Tests 2026-05-10 22:00:55 +02:00
Speiger d002f0094f Updated Build Matrix to incude newer java versions and remove obsolete
ones
2026-05-09 05:25:26 +02:00
Speiger 042460a338 Started Adding support for JDK21 SequencedCollections.
Implementation is mostly finished. Just need to iron out bugs.
But at this point i want to push activity.
2026-05-09 05:22:35 +02:00
85 changed files with 7430 additions and 1005 deletions
+1 -7
View File
@@ -6,12 +6,6 @@
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
@@ -38,7 +32,7 @@
<attribute name="gradle_used_by_scope" value="builder"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
+4 -4
View File
@@ -11,20 +11,20 @@ jobs:
strategy:
fail-fast: false
matrix:
jdk: [8, 11, 16, 17, 18, 19, 20]
jdk: [8, 11, 17, 20, 21]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v3
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: ${{ matrix.jdk }}
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1
uses: gradle/actions/wrapper-validation@v6
- name: Make gradlew executable
run: chmod +x ./gradlew
+3 -3
View File
@@ -9,12 +9,12 @@ jobs:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK 11
uses: actions/setup-java@v3
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 11
@@ -54,7 +54,7 @@ jobs:
esac
- name: Create Test Badge
uses: emibcn/badge-action@v1.2.4
uses: emibcn/badge-action@v2
with:
label: Tests
status: '${{ fromJSON( steps.test-results.outputs.json ).conclusion }}, Passed: ${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.tests_succ }}, Skipped: ${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.tests_skip }}, Failed: ${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.tests_fail }}'
+2 -2
View File
@@ -8,11 +8,11 @@ jobs:
name: Code Quality Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 11
uses: actions/setup-java@v3
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 11
@@ -9,12 +9,12 @@ jobs:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up JDK 11
uses: actions/setup-java@v3
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 11
+14 -13
View File
@@ -2,21 +2,22 @@
<projectDescription>
<name>Primitive-Collections</name>
<comment></comment>
<projects/>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<linkedResources/>
<filteredResources/>
</projectDescription>
+3 -3
View File
@@ -2,11 +2,11 @@
[![Latest Release](https://jitpack.io/v/Speiger/Primitive-Collections.svg)](https://jitpack.io/#Speiger/Primitive-Collections)
![Maven Central Version](https://img.shields.io/maven-central/v/io.github.speiger/Primitive-Collections)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
![GitHub commit activity](https://img.shields.io/github/commit-activity/m/Speiger/Primitive-Collections)
![GitHub commit activity](https://img.shields.io/github/commit-activity/y/Speiger/Primitive-Collections)
![Unit Tests](https://github.com/Speiger/Primitive-Collections/actions/workflows/build_tests_action.yml/badge.svg)
![Coverage](https://gist.githubusercontent.com/Speiger/280257cd19cbe1dda3789bebd4ff65cf/raw/405abd1d2f6c19ac70f20b8b1772176f42d5c5d3/jacoco.svg)
![Coverage](https://gist.githubusercontent.com/Speiger/280257cd19cbe1dda3789bebd4ff65cf/raw/jacoco.svg)
[![codecov](https://codecov.io/gh/Speiger/Primitive-Collections/branch/debug/graph/badge.svg?token=WSTSNJM0EN)](https://codecov.io/gh/Speiger/Primitive-Collections)
![Tests Done](https://gist.githubusercontent.com/Speiger/280257cd19cbe1dda3789bebd4ff65cf/raw/405abd1d2f6c19ac70f20b8b1772176f42d5c5d3/tests.svg)
![Tests Done](https://gist.githubusercontent.com/Speiger/280257cd19cbe1dda3789bebd4ff65cf/raw/tests.svg)
# 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.
+50 -49
View File
@@ -1,7 +1,7 @@
plugins {
id 'java-library'
id "jacoco"
// id "com.vanniktech.maven.publish" version "0.28.0"
id "com.vanniktech.maven.publish" version "0.28.0"
}
tasks.withType(JavaCompile) {
@@ -36,6 +36,7 @@ javadoc {
options.tags = [ "implSpec", "note" ]
}
eclipse {
classpath {
downloadJavadoc = true
@@ -47,6 +48,7 @@ sourceSets {
builder
}
configurations {
builderCompile.extendsFrom compile
}
@@ -55,7 +57,7 @@ dependencies {
builderImplementation 'com.google.code.gson:gson:2.10'
builderImplementation 'de.speiger:Simple-Code-Generator:1.3.0'
testImplementation 'junit:junit:4.12'
testImplementation 'com.google.guava:guava-testlib:31.0.1-jre'
testImplementation 'com.google.guava:guava-testlib:33.6.0-jre'
}
@@ -330,50 +332,49 @@ tasks.withType(PublishToMavenLocal) {
//Maven central Start
//Disabling due to java8 incompat, only needed to manually publishing anyways
//signing.useGpgCmd()
//
//import com.vanniktech.maven.publish.SonatypeHost
//import com.vanniktech.maven.publish.JavaLibrary
//import com.vanniktech.maven.publish.JavadocJar
//
//mavenPublishing {
// configure(new JavaLibrary(new JavadocJar.None(), true))
//}
//
//mavenPublishing {
// publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
//
// signAllPublications()
// pom {
// name = 'Primitive Collections'
// description = 'A Primitive Collection library that reduces memory usage and improves performance'
// url = 'https://github.com/Speiger/Primitive-Collections'
// version = project.version
// group = 'io.github.speiger'
// licenses {
// license {
// name = 'The Apache License, Version 2.0'
// url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
// }
// }
//
// developers {
// developer {
// id = 'speiger'
// name = 'Speiger'
// }
// }
//
// scm {
// connection = 'scm:git:git://github.com/Speiger/Primitive-Collections.git'
// developerConnection = 'scm:git:ssh://github.com:Speiger/Primitive-Collections.git'
// url = 'https://github.com/Speiger/Primitive-Collections'
// }
//
// issueManagement {
// system = 'github'
// url = 'https://github.com/Speiger/Primitive-Collections/issues'
// }
// }
//}
//
signing.useGpgCmd()
import com.vanniktech.maven.publish.SonatypeHost
import com.vanniktech.maven.publish.JavaLibrary
import com.vanniktech.maven.publish.JavadocJar
mavenPublishing {
configure(new JavaLibrary(new JavadocJar.None(), true))
}
mavenPublishing {
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
signAllPublications()
pom {
name = 'Primitive Collections'
description = 'A Primitive Collection library that reduces memory usage and improves performance'
url = 'https://github.com/Speiger/Primitive-Collections'
version = project.version
group = 'io.github.speiger'
licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id = 'speiger'
name = 'Speiger'
}
}
scm {
connection = 'scm:git:git://github.com/Speiger/Primitive-Collections.git'
developerConnection = 'scm:git:ssh://github.com:Speiger/Primitive-Collections.git'
url = 'https://github.com/Speiger/Primitive-Collections'
}
issueManagement {
system = 'github'
url = 'https://github.com/Speiger/Primitive-Collections/issues'
}
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
org.gradle.jvmargs=-Xmx3G
maxMemory = 1024m
maxMemory = 2048m
testThreads = 4
RELEASE_VERSION = 0.9.0
RELEASE_VERSION = 1.0.0
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+1 -1
View File
@@ -1,5 +1,5 @@
jdk:
- openjdk9
- openjdk21
install:
- chmod +x ./gradlew
- ./gradlew build publishToMavenLocal
@@ -41,7 +41,7 @@ public class CollectionModule extends BaseModule
protected void loadBlockades() {
if(!MODULE.isEnabled()) {
addBlockedFiles("Iterable", "Iterables", "Iterator", "Iterators", "BidirectionalIterator", "ListIterator");
addBlockedFiles("Arrays", "Collection", "AbstractCollection", "Collections", "Stack");
addBlockedFiles("Arrays", "Collection", "OrderedCollection", "AbstractCollection", "Collections", "Stack");
}
if(!SPLIT_ITERATORS.isEnabled()) addBlockedFiles("Splititerator", "Splititerators");
if(!IARRAY.isEnabled()) addBlockedFiles("IArray");
@@ -91,6 +91,7 @@ public class CollectionModule extends BaseModule
{
//Abstract Classes
addAbstractMapper("ABSTRACT_COLLECTION", "Abstract%sCollection");
addAbstractMapper("REVERSED_ORDERED_COLLECTION", "Reverse%sOrderedCollection");
//Helper Classes
addClassMapper("ARRAYS", "Arrays");
@@ -101,6 +102,7 @@ public class CollectionModule extends BaseModule
//Interfaces
addClassMapper("COLLECTION", "Collection");
addClassMapper("ORDERED_COLLECTION", "OrderedCollection");
addClassMapper("ITERABLE", "Iterable");
addClassMapper("SPLIT_ITERATOR", "Splititerator");
addClassMapper("LIST_ITERATOR", "ListIterator");
@@ -34,7 +34,8 @@ public class FunctionModule extends BaseModule
protected void loadBlockades()
{
if(keyType.isObject()) addBlockedFiles("Consumer", "Comparator");
if(!MODULE.isEnabled()) addBlockedFiles("Consumer", "BiConsumer", "Comparator", "Supplier", "Function", "UnaryOperator");
if(!MODULE.isEnabled()) addBlockedFiles("Consumer", "BiConsumer", "Comparator", "Supplier", "Optional", "Function", "UnaryOperator");
if(!keyType.needsCustomJDKType()) addBlockedFiles("Optional");
}
@Override
@@ -60,6 +61,7 @@ public class FunctionModule extends BaseModule
}
else addBiRequirement("Function");
addRemapper("BiConsumer", "%sConsumer");
addRemapper("Optional", "Optional%s");
}
@Override
@@ -94,6 +96,8 @@ public class FunctionModule extends BaseModule
addFunctionMappers("PREDICATE", "%sPredicate");
addClassMapper("SUPPLIER", "Supplier");
addSimpleMapper("OPTIONAL", keyType.isObject() ? "Optional" : String.format("Optional%s", keyType.getFileType()));
addSimpleMapper("VALUE_OPTIONAL", valueType.isObject() ? "Optional" : String.format("Optional%s", valueType.getFileType()));
addAbstractMapper("SINGLE_UNARY_OPERATOR", "%1$s%1$sUnaryOperator");
addBiClassMapper("UNARY_OPERATOR", "UnaryOperator", "");
if(keyType.isObject())
@@ -60,6 +60,8 @@ public class JavaModule extends BaseModule
addSimpleMapper("APPLY_KEY_VALUE", keyType.isObject() ? "apply" : "applyAs"+keyType.getNonFileType());
addSimpleMapper("APPLY_VALUE", valueType.isObject() ? "apply" : "applyAs"+valueType.getNonFileType());
addSimpleMapper("APPLY_CAST", "applyAs"+keyType.getCustomJDKType().getNonFileType());
addSimpleMapper("GET_OPTIONAL", keyType.isObject() ? "ofNullable" : "of");
addSimpleMapper("GET_OPTIONAL_VALUE", valueType.isObject() ? "ofNullable" : "of");
//Shared by Maps and Pairs so moved to java.
addFunctionMappers("ENTRY_KEY", "get%sKey");
@@ -196,6 +198,7 @@ public class JavaModule extends BaseModule
addComment("@Type", "@param <%s> the keyType of elements maintained by this Collection");
addValueComment("@ValueArrayType", "@param <%s> the keyType of array that the operation should be applied");
addValueComment("@ValueType", "@param <%s> the keyType of elements maintained by this Collection");
addSimpleMapper("@Java21", getVersion() >= 21 ? "@Override" : "");
addAnnontion("@PrimitiveOverride", "@Override");
addSimpleMapper("@PrimitiveDoc", "");
addAnnontion("@Primitive", "@Deprecated");
@@ -36,6 +36,10 @@ public class MapModule extends BaseModule
public static final FunctionDependency ENUM_MAP = MODULE.createDependency("EnumMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_ENUM_MAP = MODULE.createDependency("LinkedEnumMap").addEntryDependency(ENUM_MAP).addEntryDependency(ORDERED_MAP);
public static final FunctionDependency REF_MAP = MODULE.createDependency("ReferenceHashMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_REF_MAP = MODULE.createDependency("LinkedReferenceMap").addEntryDependency(REF_MAP).addEntryDependency(ORDERED_MAP);
public static final FunctionDependency CONCURRENT_MAP = MODULE.createDependency("ConcurrentMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency AVL_TREE_MAP = MODULE.createDependency("AVLTreeMap").addEntryDependency(SORTED_MAP).addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency RB_TREE_MAP = MODULE.createDependency("RBTreeMap").addEntryDependency(SORTED_MAP).addEntryDependency(IMPLEMENTATION);
@@ -51,7 +55,7 @@ public class MapModule extends BaseModule
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) {
List<IDependency> dependencies = new ArrayList<>(Arrays.asList(MODULE, ORDERED_MAP, SORTED_MAP, IMPLEMENTATION, WRAPPERS, ARRAY_MAP, IMMUTABLE_MAP, HASH_MAP, LINKED_MAP, CUSTOM_MAP, LINKED_CUSTOM_MAP, CONCURRENT_MAP, AVL_TREE_MAP, RB_TREE_MAP));
if(keyType == ClassType.OBJECT) dependencies.addAll(Arrays.asList(ENUM_MAP, LINKED_ENUM_MAP));
if(keyType == ClassType.OBJECT) dependencies.addAll(Arrays.asList(ENUM_MAP, LINKED_ENUM_MAP, REF_MAP, LINKED_REF_MAP));
return dependencies;
}
@@ -70,6 +74,10 @@ public class MapModule extends BaseModule
if(AVL_TREE_MAP.isEnabled()) addFlag("AVL_TREE_MAP_FEATURE");
if(RB_TREE_MAP.isEnabled()) addFlag("RB_TREE_MAP_FEATURE");
if(REF_MAP.isEnabled()) addFlag("REF_MAP_FEATURE");
if(LINKED_REF_MAP.isEnabled()) addFlag("LINKED_REF_MAP_FEATURE");
if(CONCURRENT_MAP.isEnabled()) addFlag("CONCURRENT_MAP_FEATURE");
if(IMMUTABLE_MAP.isEnabled()) addFlag("IMMUTABLE_MAP_FEATURE");
if(HASH_MAP.isEnabled()) addFlag("MAP_FEATURE");
@@ -85,6 +93,8 @@ public class MapModule extends BaseModule
if(!IMMUTABLE_MAP.isEnabled()) addBlockedFiles("ImmutableOpenHashMap");
if(!CONCURRENT_MAP.isEnabled()) addBlockedFiles("ConcurrentMap", "ConcurrentOpenHashMap");
if(!ORDERED_MAP.isEnabled()) addBlockedFiles("OrderedMap");
if(!REF_MAP.isEnabled()) addBlockedFiles("ReferenceHashMap");
if(!LINKED_REF_MAP.isEnabled()) addBlockedFiles("LinkedReferenceHashMap");
if(!HASH_MAP.isEnabled()) addBlockedFiles("OpenHashMap");
if(!LINKED_MAP.isEnabled()) addBlockedFiles("LinkedOpenHashMap");
if(!CUSTOM_MAP.isEnabled()) addBlockedFiles("OpenCustomHashMap");
@@ -127,6 +137,8 @@ public class MapModule extends BaseModule
addBiRequirement("AbstractMap");
addEnumRequirement("EnumMap");
addEnumRequirement("LinkedEnumMap");
addEnumRequirement("ReferenceHashMap");
addEnumRequirement("LinkedReferenceHashMap");
addBiRequirement("ConcurrentOpenHashMap");
addBiRequirement("ImmutableOpenHashMap");
addBiRequirement("OpenHashMap");
@@ -141,6 +153,8 @@ public class MapModule extends BaseModule
addRemapper("AbstractMap", "Abstract%sMap");
addRemapper("EnumMap", "Enum2%sMap");
addRemapper("LinkedEnumMap", "LinkedEnum2%sMap");
addRemapper("ReferenceHashMap", "Reference2%sHashMap");
addRemapper("LinkedReferenceHashMap", "Reference2%sLinkedHashMap");
addRemapper("ImmutableOpenHashMap", "Immutable%sOpenHashMap");
//Test Classes
@@ -198,6 +212,7 @@ public class MapModule extends BaseModule
addBiRequirement("SortedMapNavigationTester");
addBiRequirement("OrderedMapNavigationTester");
addBiRequirement("OrderedMapMoveTester");
addBiRequirement("OrderedMapPutTester");
addBiRequirement("MapConstructorTester");
addRemapper("TestMapGenerator", "Test%sMapGenerator");
@@ -248,11 +263,14 @@ public class MapModule extends BaseModule
addBiClassMapper("RB_TREE_MAP", "RBTreeMap", "2");
addFunctionValueMappers("LINKED_ENUM_MAP", valueType.isObject() ? "LinkedEnum2ObjectMap" : "LinkedEnum2%sMap");
addFunctionValueMappers("ENUM_MAP", valueType.isObject() ? "Enum2ObjectMap" : "Enum2%sMap");
addFunctionValueMappers("REF_MAP", valueType.isObject() ? "Reference2ObjectHashMap" : "Reference2%sHashMap");
addFunctionValueMappers("LINKED_REF_MAP", valueType.isObject() ? "Reference2ObjectLinkedHashMap" : "Reference2%sLinkedHashMap");
addBiClassMapper("HASH_MAP", "OpenHashMap", "2");
addBiClassMapper("ARRAY_MAP", "ArrayMap", "2");
//Abstract Classes
addAbstractBiMapper("ABSTRACT_MAP", "Abstract%sMap", "2");
addAbstractBiMapper("REVERSED_ORDERED_MAP", "Reversed%sOrderedMap", "2");
//Helper Classes
addBiClassMapper("MAPS", "Maps", "2");
@@ -148,6 +148,7 @@ public class SetModule extends BaseModule
//Abstract Classes
addAbstractMapper("ABSTRACT_SET", "Abstract%sSet");
addAbstractMapper("REVERSED_ORDERED_SET", "Reversed%sOrderedSet");
//Helper Classes
addClassMapper("SETS", "Sets");
@@ -1,12 +1,18 @@
package speiger.src.collections.PACKAGE.collections;
import java.util.Collection;
#if ORDERED_MAP_FEATURE
import java.util.function.Supplier;
#endif
import java.util.Objects;
import java.util.AbstractCollection;
#if TYPE_OBJECT
import java.util.function.Consumer;
#endif
#if ORDERED_MAP_FEATURE
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.utils.ITERATORS;
@@ -262,5 +268,79 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
if (a.length > size()) a[size()] = EMPTY_KEY_VALUE;
return a;
}
#endif
#if ORDERED_MAP_FEATURE
public static class REVERSED_ORDERED_COLLECTION KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements ORDERED_COLLECTION KEY_GENERIC_TYPE {
ORDERED_COLLECTION KEY_GENERIC_TYPE collection;
Supplier<ITERATOR KEY_GENERIC_TYPE> reverseIterator;
public REVERSED_ORDERED_COLLECTION(ORDERED_COLLECTION KEY_GENERIC_TYPE collection, Supplier<ITERATOR KEY_GENERIC_TYPE> reverseIterator) {
this.collection = collection;
this.reverseIterator = reverseIterator;
}
@Override
public boolean add(KEY_TYPE o) { return collection.add(o); }
@Override
public ORDERED_COLLECTION KEY_GENERIC_TYPE reversed() { return collection; }
@Override
public void addFirst(KEY_TYPE e) { collection.addLast(e); }
@Override
public void addLast(KEY_TYPE e) { collection.addFirst(e); }
@Override
#if !TYPE_OBJECT
public boolean contains(KEY_TYPE e) { return collection.contains(e); }
#else
public boolean contains(Object e) { return collection.contains(e); }
#endif
@Override
#if !TYPE_OBJECT
public boolean REMOVE_KEY(KEY_TYPE e) { return collection.REMOVE_KEY(e); }
#else
public boolean remove(Object e) { return collection.remove(e); }
#endif
@Override
public void clear() { collection.clear(); }
@Override
public KEY_TYPE GET_FIRST_KEY() { return collection.GET_LAST_KEY(); }
@Override
public KEY_TYPE REMOVE_FIRST_KEY() { return collection.REMOVE_LAST_KEY(); }
@Override
public KEY_TYPE GET_LAST_KEY() { return collection.GET_FIRST_KEY(); }
@Override
public KEY_TYPE REMOVE_LAST_KEY() { return collection.REMOVE_FIRST_KEY(); }
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() { return reverseIterator.get(); }
@Override
public int size() { return collection.size(); }
}
public static class ReverseBiIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE {
LIST_ITERATOR KEY_GENERIC_TYPE it;
public ReverseBiIterator(LIST_ITERATOR KEY_GENERIC_TYPE it) {
this.it = it;
}
@Override
public KEY_TYPE NEXT() { return it.PREVIOUS(); }
@Override
public boolean hasNext() { return it.hasPrevious(); }
@Override
public boolean hasPrevious() { return it.hasNext(); }
@Override
public KEY_TYPE PREVIOUS() { return it.NEXT(); }
@Override
public void remove() { it.remove(); }
@Override
public int nextIndex() { return it.previousIndex(); }
@Override
public int previousIndex() { return it.nextIndex(); }
@Override
public void set(KEY_TYPE e) { it.set(e); }
@Override
public void add(KEY_TYPE e) { it.add(e); }
}
#endif
}
@@ -5,6 +5,9 @@ import java.util.function.Consumer;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
#if JDK_TYPE
import java.util.OPTIONAL;
#endif
#if !TYPE_OBJECT
@@ -30,6 +33,9 @@ import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERABLE;
#endif
#enditerate
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
@@ -408,13 +414,13 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
* @param filter that should be applied
* @return the found value or the null equivalent variant.
*/
default KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
default OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
KEY_TYPE entry = iter.NEXT();
if(filter.test(entry)) return entry;
if(filter.test(entry)) return OPTIONAL.GET_OPTIONAL(entry);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
#if !TYPE_OBJECT
@@ -459,7 +465,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
* @param operator the operation that should be applied
* @return the reduction result, returns null value if nothing was found
*/
default KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
default OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -471,7 +477,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
}
state = operator.APPLY_VALUE(state, iter.NEXT());
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
/**
@@ -0,0 +1,83 @@
package speiger.src.collections.PACKAGE.collections;
#if JAVA_VERSION>=21
import java.util.SequencedCollection;
public interface ORDERED_COLLECTION KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, SequencedCollection<CLASS_TYPE> {
#else
public interface ORDERED_COLLECTION KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE {
#endif
@Java21
ORDERED_COLLECTION KEY_GENERIC_TYPE reversed();
/**
* A method to add an element to the start of a collection
* @param e that should be added at the start.
*/
public void addFirst(KEY_TYPE e);
/**
* A method to add an element to the end of a collection
* @param e that should be added at the end.
*/
public void addLast(KEY_TYPE e);
/**
* A method to get the first element in the collection
* @return first element in the collection
*/
public KEY_TYPE GET_FIRST_KEY();
/**
* A method to get and remove the first element in the collection
* @return first element in the collection
*/
public KEY_TYPE REMOVE_FIRST_KEY();
/**
* A method to get the last element in the collection
* @return last element in the collection
*/
public KEY_TYPE GET_LAST_KEY();
/**
* A method to get and remove the last element in the collection
* @return last element in the collection
*/
public KEY_TYPE REMOVE_LAST_KEY();
#if JAVA_VERSION>=21 && !TYPE_OBJECT
@Override
@Deprecated
default void addFirst(CLASS_TYPE e) {
addFirst(OBJ_TO_KEY(e));
}
@Override
@Deprecated
default void addLast(CLASS_TYPE e) {
addLast(OBJ_TO_KEY(e));
}
@Override
@Deprecated
default CLASS_TYPE getFirst() {
return KEY_TO_OBJ(GET_FIRST_KEY());
}
@Override
@Deprecated
default CLASS_TYPE getLast() {
return KEY_TO_OBJ(GET_LAST_KEY());
}
@Override
@Deprecated
default CLASS_TYPE removeFirst() {
return KEY_TO_OBJ(REMOVE_FIRST_KEY());
}
@Override
@Deprecated
default CLASS_TYPE removeLast() {
return KEY_TO_OBJ(REMOVE_LAST_KEY());
}
#endif
}
@@ -0,0 +1,89 @@
package speiger.src.collections.PACKAGE.functions;
import java.util.NoSuchElementException;
import java.util.function.Supplier;
public final class OPTIONAL KEY_GENERIC_TYPE {
private static final OPTIONAL NO_GENERIC_TYPE EMPTY = new OPTIONALBRACES();
private final boolean isPresent;
private final KEY_TYPE value;
private OPTIONAL() {
this.isPresent = false;
this.value = EMPTY_VALUE;
}
private OPTIONAL(KEY_TYPE value) {
this.isPresent = true;
this.value = value;
}
public static OPTIONAL KEY_GENERIC_TYPE empty() {
return EMPTY;
}
public static OPTIONAL KEY_GENERIC_TYPE of(KEY_TYPE value) {
return new OPTIONALBRACES(value);
}
public KEY_TYPE SUPPLY_GET() {
if(!isPresent) throw new NoSuchElementException("No value present");
return value;
}
public boolean isPresent() {
return isPresent;
}
public boolean isEmpty() {
return !isPresent;
}
public void ifPresent(CONSUMER KEY_GENERIC_TYPE consumer) {
if(isPresent) consumer.accept(value);
}
public void ifPresentOrElse(CONSUMER KEY_GENERIC_TYPE action, Runnable emptyAction) {
if (isPresent) action.accept(value);
else emptyAction.run();
}
public KEY_TYPE orElse(KEY_TYPE other) {
return isPresent ? value : other;
}
public KEY_TYPE orElseGet(SUPPLIER KEY_GENERIC_TYPE other) {
return isPresent ? value : other.SUPPLY_GET();
}
public KEY_TYPE orElseThrow() {
if (!isPresent) throw new NoSuchElementException("No value present");
return value;
}
public <X extends Throwable> KEY_TYPE orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if(isPresent) return value;
else throw exceptionSupplier.get();
}
@Override
public boolean equals(Object obj) {
if(obj == this) return true;
if(obj instanceof OPTIONAL) {
OPTIONAL KEY_GENERIC_TYPE other = (OPTIONAL KEY_GENERIC_TYPE)obj;
return (isPresent && other.isPresent ? KEY_EQUALS(value, other.value) : isPresent == other.isPresent);
}
return false;
}
@Override
public int hashCode() {
return isPresent ? KEY_TO_HASH(value) : 0;
}
@Override
public String toString() {
return isPresent ? "OPTIONAL["+value+"]" : "OPTIONAL.empty";
}
}
@@ -7,6 +7,16 @@ import java.util.Comparator;
import java.util.Collection;
import java.util.Iterator;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#endif
#if TYPE_OBJECT
#if IARRAY_FEATURE || TYPE_OBJECT
import java.util.function.Consumer;
@@ -33,6 +43,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.STACK;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -219,6 +232,42 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return list;
}
#endif
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a ArrayList
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, ObjectArrayList<T>, ObjectArrayList<T>> toList() {
return Collector.of(ObjectArrayList::new, ObjectArrayList::add, ObjectArrayList::merge);
}
/**
* Collects a Stream to a ArrayList
* @Type(T)
* @return a list with the contents of the Stream
*/
public static <T> ARRAY_LIST KEY_GENERIC_TYPE toList(Stream<T> stream) {
return stream.collect(ObjectArrayList::new, ObjectArrayList::add, ObjectArrayList::merge);
}
private ObjectArrayList<T> merge(ObjectArrayList<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a ArrayList
* @return a list with the contents of the Stream
*/
public static ARRAY_LIST toList(JAVA_STREAM stream) {
return stream.collect(ARRAY_LIST::new, ARRAY_LIST::add, ARRAY_LIST::addAll);
}
#endif
#endif
/**
* Appends the specified element to the end of this list.
@@ -682,12 +731,12 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(data[i])) return data[i];
if(filter.test(data[i])) return OPTIONAL.GET_OPTIONAL(data[i]);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
#if !TYPE_OBJECT
@@ -714,7 +763,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -726,7 +775,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
}
state = operator.APPLY_VALUE(state, data[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
@@ -8,6 +8,15 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#endif
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -33,6 +42,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.STACK;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -166,7 +178,42 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
}
#endif
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a CopyOnWriteArrayList
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, CopyOnWriteObjectArrayList<T>, CopyOnWriteObjectArrayList<T>> toList() {
return Collector.of(CopyOnWriteObjectArrayList::new, CopyOnWriteObjectArrayList::add, CopyOnWriteObjectArrayList::merge);
}
/**
* Collects a Stream to a CopyOnWriteArrayList
* @Type(T)
* @return a list with the contents of the Stream
*/
public static <T> CopyOnWriteObjectArrayList KEY_GENERIC_TYPE toList(Stream<T> stream) {
return stream.collect(CopyOnWriteObjectArrayList::new, CopyOnWriteObjectArrayList::add, CopyOnWriteObjectArrayList::merge);
}
private CopyOnWriteObjectArrayList<T> merge(CopyOnWriteObjectArrayList<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a CopyOnWriteArrayList
* @return a list with the contents of the Stream
*/
public static COPY_ON_WRITE_LIST toList(JAVA_STREAM stream) {
return stream.collect(COPY_ON_WRITE_LIST::new, COPY_ON_WRITE_LIST::add, COPY_ON_WRITE_LIST::addAll);
}
#endif
#endif
private void setArray(KEY_TYPE[] data) {
this.data = data;
}
@@ -535,7 +582,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
* @return if the element was found.
*/
@Override
@Deprecated
@Primitive
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@@ -546,7 +593,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
* @return the index of the element if found. (if not found then -1)
*/
@Override
@Deprecated
@Primitive
public int indexOf(Object o) {
KEY_TYPE[] data = this.data;
#if TYPE_OBJECT
@@ -570,7 +617,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
* @return the last index of the element if found. (if not found then -1)
*/
@Override
@Deprecated
@Primitive
public int lastIndexOf(Object o) {
KEY_TYPE[] data = this.data;
#if TYPE_OBJECT
@@ -810,13 +857,13 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
KEY_TYPE[] data = this.data;
for(int i = 0,m=data.length;i<m;i++) {
if(filter.test(data[i])) return data[i];
if(filter.test(data[i])) return OPTIONAL.GET_OPTIONAL(data[i]);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
#if !TYPE_OBJECT
@@ -845,7 +892,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE[] data = this.data;
KEY_TYPE state = EMPTY_VALUE;
@@ -858,7 +905,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
}
state = operator.APPLY_VALUE(state, data[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
@@ -3,10 +3,26 @@ package speiger.src.collections.PACKAGE.lists;
import java.util.Arrays;
#if TYPE_OBJECT
import java.util.Comparator;
#else if !TYPE_BOOLEAN
import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport;
#endif
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if PRIMITIVES
import java.util.function.Supplier;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
import speiger.src.collections.PACKAGE.utils.COLLECTIONS;
#endif
#endif
#if TYPE_OBJECT
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -20,6 +36,7 @@ import java.util.function.PREDICATE;
#if !JDK_FUNCTION
import java.util.function.JAVA_PREDICATE;
#endif
import java.util.function.JAVA_UNARY_OPERATOR;
#endif
@@ -27,6 +44,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
@@ -36,10 +56,6 @@ import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#if PRIMITIVES && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport;
#endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
@@ -120,6 +136,42 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
data = Arrays.copyOfRange(a, offset, offset+length);
}
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a ImmutableList
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, COLLECTION<T>, ImmutableObjectList<T>> toList() {
return Collector.of(COLLECTIONS::wrapper, COLLECTION::add, ImmutableObjectList::merge, E -> new IMMUTABLE_LIST<>(E.toArray((T[])new Object[E.size()])));
}
/**
* Collects a Stream to a ImmutableList
* @Type(T)
* @return a list with the contents of the Stream
*/
public static <T> ImmutableObjectList KEY_GENERIC_TYPE toList(Stream<T> stream) {
return stream.collect(toList());
}
private static <T> COLLECTION<T> merge(COLLECTION<T> a, COLLECTION<T> b) {
a.addAll(b);
return a;
}
#else
/**
* Collects a Stream to a ImmutableList
* @return a list with the contents of the Stream
*/
public static IMMUTABLE_LIST toList(JAVA_STREAM stream) {
return new IMMUTABLE_LIST(stream.collect((Supplier<COLLECTION>)COLLECTIONS::wrapper, COLLECTION::add, COLLECTION::addAll).TO_ARRAY());
}
#endif
#endif
@Override
public boolean add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
@@ -335,12 +387,12 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=data.length;i<m;i++) {
if(filter.test(data[i])) return data[i];
if(filter.test(data[i])) return OPTIONAL.GET_OPTIONAL(data[i]);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
#if !TYPE_OBJECT
@@ -367,7 +419,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -379,7 +431,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
}
state = operator.APPLY_VALUE(state, data[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
@@ -4,7 +4,6 @@ package speiger.src.collections.PACKAGE.lists;
#if DEQUEUE_FEATURE
import java.util.Comparator;
#endif
import java.util.function.BiFunction;
#else if PRIMITIVES
import java.nio.JAVA_BUFFER;
@@ -12,6 +11,15 @@ import java.nio.JAVA_BUFFER;
import java.util.Collection;
import java.util.Iterator;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#endif
import java.util.NoSuchElementException;
#if SPLIT_ITERATOR_FEATURE
import java.util.Spliterator;
@@ -34,6 +42,9 @@ import java.util.function.JAVA_PREDICATE;
#endif
import java.util.function.JAVA_UNARY_OPERATOR;
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
@@ -155,6 +166,42 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
for(int i = offset,m=offset+length;i<m;add(a[i++]));
}
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a LinkedList
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, ObjectLinkedList<T>, ObjectLinkedList<T>> toList() {
return Collector.of(ObjectLinkedList::new, ObjectLinkedList::add, ObjectLinkedList::merge);
}
/**
* Collects a Stream to a LinkedList
* @Type(T)
* @return a list with the contents of the Stream
*/
public static <T> ObjectLinkedList KEY_GENERIC_TYPE toList(Stream<T> stream) {
return stream.collect(ObjectLinkedList::new, ObjectLinkedList::add, ObjectLinkedList::merge);
}
private ObjectLinkedList<T> merge(ObjectLinkedList<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a LinkedList
* @return a list with the contents of the Stream
*/
public static LINKED_LIST toList(JAVA_STREAM stream) {
return stream.collect(LINKED_LIST::new, LINKED_LIST::add, LINKED_LIST::addAll);
}
#endif
#endif
@Override
public boolean add(KEY_TYPE e) {
add(size(), e);
@@ -493,12 +540,12 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(filter.test(entry.value)) return entry.value;
if(filter.test(entry.value)) return OPTIONAL.GET_OPTIONAL(entry.value);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
#if !TYPE_OBJECT
@@ -525,7 +572,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -537,7 +584,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
}
state = operator.APPLY_VALUE(state, entry.value);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
@@ -15,6 +15,7 @@ import java.util.function.UnaryOperator;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ORDERED_COLLECTION;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#endif
@@ -40,7 +41,7 @@ import speiger.src.collections.utils.SanityChecks;
* A Type Specific List interface that reduces boxing/unboxing and adds a couple extra quality of life features
* @Type(T)
*/
public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List<CLASS_TYPE>
public interface LIST KEY_GENERIC_TYPE extends ORDERED_COLLECTION KEY_GENERIC_TYPE, List<CLASS_TYPE>
{
#if !TYPE_OBJECT
/**
@@ -105,6 +106,24 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
*/
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c);
/**
* A method to add an element to the start of a list
* @param e that should be added at the start.
*/
@Override
public default void addFirst(KEY_TYPE e) {
add(0, e);
}
/**
* A method to add an element to the end of a list
* @param e that should be added at the end.
*/
@Override
public default void addLast(KEY_TYPE e) {
add(e);
}
/**
* Helper method that returns the first element of a List.
* This function was introduced due to how annoying it is to get/remove the last element of a list.
@@ -508,9 +527,56 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
@Override
@Deprecated
public default boolean add(CLASS_TYPE e) {
return COLLECTION.super.add(e);
return ORDERED_COLLECTION.super.add(e);
}
#if JAVA_VERSION>=21
#if !TYPE_OBJECT
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default void addFirst(CLASS_TYPE e) {
addFirst(OBJ_TO_KEY(e));
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default void addLast(CLASS_TYPE e) {
addLast(OBJ_TO_KEY(e));
}
#endif
@Override
@Deprecated
default CLASS_TYPE getFirst() {
return KEY_TO_OBJ(GET_FIRST_KEY());
}
@Override
@Deprecated
default CLASS_TYPE getLast() {
return KEY_TO_OBJ(GET_LAST_KEY());
}
@Override
@Deprecated
default CLASS_TYPE removeFirst() {
return KEY_TO_OBJ(REMOVE_FIRST_KEY());
}
@Override
@Deprecated
default CLASS_TYPE removeLast() {
return KEY_TO_OBJ(REMOVE_LAST_KEY());
}
#endif
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
@@ -558,7 +624,7 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
@Override
@Deprecated
public default boolean contains(Object o) {
return COLLECTION.super.contains(o);
return ORDERED_COLLECTION.super.contains(o);
}
/** {@inheritDoc}
@@ -568,7 +634,7 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
@Override
@Deprecated
public default boolean remove(Object o) {
return COLLECTION.super.remove(o);
return ORDERED_COLLECTION.super.remove(o);
}
/** {@inheritDoc}
@@ -14,6 +14,15 @@ import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
#if ORDERED_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectOrderedSet;
#endif
#endif
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET;
#if MAPS_FEATURE
@@ -42,7 +51,7 @@ import speiger.src.collections.utils.SanityChecks;
*/
public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CLASS_TYPE, CLASS_VALUE_TYPE> implements MAP KEY_VALUE_GENERIC_TYPE
{
protected VALUE_TYPE defaultReturnValue = EMPTY_VALUE;
protected VALUE_TYPE defaultReturnValue = INVALID_VALUE;
@Override
public VALUE_TYPE getDefaultReturnValue() {
@@ -119,7 +128,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
public void putAll(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, int offset, int size) {
SanityChecks.checkArrayCapacity(keys.length, offset, size);
SanityChecks.checkArrayCapacity(values.length, offset, size);
for(int i = 0;i<size;i++) put(keys[i], values[i]);
for(int i = 0;i<size;i++) put(OBJ_TO_KEY(keys[i]), OBJ_TO_VALUE(values[i]));
}
#endif
@@ -543,6 +552,132 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
return hash;
}
public static class REVERSED_ORDERED_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements ORDERED_MAP KEY_VALUE_GENERIC_TYPE {
ORDERED_MAP KEY_VALUE_GENERIC_TYPE map;
public REVERSED_ORDERED_MAP(ORDERED_MAP KEY_VALUE_GENERIC_TYPE map) {
this.map = map;
}
@Override
public ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE setDefaultReturnValue(VALUE_TYPE v) {
map.setDefaultReturnValue(v);
return this;
}
@Override
public VALUE_TYPE getDefaultReturnValue() { return map.getDefaultReturnValue(); }
@Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) { return map.put(key, value); }
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) { return map.putIfAbsent(key, value); }
#if VALUE_PRIMITIVES
@Override
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) { return map.addTo(key, value); }
@Override
public VALUE_TYPE subFrom(KEY_TYPE key, VALUE_TYPE value) { return map.subFrom(key, value); }
#endif
@Override
public VALUE_TYPE REMOVE_VALUE(KEY_TYPE key) { return map.REMOVE_VALUE(key); }
#if !TYPE_OBJECT || !VALUE_OBJECT
@Override
public boolean remove(KEY_TYPE key, VALUE_TYPE value) { return map.remove(key, value); }
#endif
@Override
public VALUE_TYPE REMOVE_VALUEOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return map.REMOVE_VALUEOrDefault(key, defaultValue); }
@Override
#if TYPE_OBJECT
public boolean containsKey(Object key) { return map.containsKey(key); }
#else
public boolean containsKey(KEY_TYPE key) { return map.containsKey(key); }
#endif
@Override
#if VALUE_OBJECT
public boolean containsValue(Object value) { return map.containsValue(value); }
#else
public boolean containsValue(VALUE_TYPE value) { return map.containsValue(value); }
#endif
@Override
public boolean replace(KEY_TYPE key, VALUE_TYPE oldValue, VALUE_TYPE newValue) { return map.replace(key, oldValue, newValue); }
@Override
public VALUE_TYPE replace(KEY_TYPE key, VALUE_TYPE value) { return map.replace(key, value); }
@Override
public void REPLACE_VALUES(MAP KEY_VALUE_GENERIC_TYPE m) { map.REPLACE_VALUES(m); }
@Override
public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { map.REPLACE_VALUES(mappingFunction); }
@Override
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { return map.COMPUTE(key, mappingFunction); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { return map.COMPUTE_IF_ABSENT(key, mappingFunction); }
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { return map.SUPPLY_IF_ABSENT(key, valueProvider); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { return map.COMPUTE_IF_PRESENT(key, mappingFunction); }
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { return map.COMPUTENonDefault(key, mappingFunction); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { return map.COMPUTE_IF_ABSENTNonDefault(key, mappingFunction); }
@Override
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { return map.SUPPLY_IF_ABSENTNonDefault(key, valueProvider); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { return map.COMPUTE_IF_PRESENTNonDefault(key, mappingFunction); }
#endif
@Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { return map.MERGE(key, value, mappingFunction); }
#if !TYPE_OBJECT || !VALUE_OBJECT
@Override
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return map.getOrDefault(key, defaultValue); }
#endif
@Override
public VALUE_TYPE GET_VALUE(KEY_TYPE key) { return map.GET_VALUE(key); }
@Override
public VALUE_TYPE putAndMoveToFirst(KEY_TYPE key, VALUE_TYPE value) { return map.putAndMoveToLast(key, value); }
@Override
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { return map.putAndMoveToFirst(key, value); }
@Override
public VALUE_TYPE putFirst(KEY_TYPE key, VALUE_TYPE value) { return map.putLast(key, value); }
@Override
public VALUE_TYPE putLast(KEY_TYPE key, VALUE_TYPE value) { return map.putFirst(key, value); }
@Override
public boolean moveToFirst(KEY_TYPE key) { return map.moveToLast(key); }
@Override
public boolean moveToLast(KEY_TYPE key) { return map.moveToFirst(key); }
@Override
public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) { return map.getAndMoveToLast(key); }
@Override
public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) { return map.getAndMoveToFirst(key); }
@Override
public KEY_TYPE FIRST_ENTRY_KEY() { return map.LAST_ENTRY_KEY(); }
@Override
public KEY_TYPE POLL_FIRST_ENTRY_KEY() { return map.POLL_LAST_ENTRY_KEY(); }
@Override
public KEY_TYPE LAST_ENTRY_KEY() { return map.FIRST_ENTRY_KEY(); }
@Override
public KEY_TYPE POLL_LAST_ENTRY_KEY() { return map.POLL_FIRST_ENTRY_KEY(); }
@Override
public VALUE_TYPE FIRST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE LAST_ENTRY_VALUE() { return map.FIRST_ENTRY_VALUE(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { return map.lastEntry(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() { return map.firstEntry(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() { return map.pollLastEntry(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() { return map.pollFirstEntry(); }
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { return new AbstractObjectSet.ReversedObjectOrderedSet<>(map.ENTRY_SET()); }
@Override
public ORDERED_SET KEY_GENERIC_TYPE keySet() { return new ABSTRACT_SET.REVERSED_ORDERED_SETBRACES(map.keySet()); }
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() { return map.values().reversed(); }
@Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE reversed() { return map; }
}
/**
* A Simple Type Specific Entry class to reduce boxing/unboxing
* @Type(T)
@@ -4,15 +4,18 @@ import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.locks.StampedLock;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.BiFunction;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
#if !TYPE_OBJECT
@@ -40,9 +43,12 @@ import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if!VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.CONCURRENT_MAP;
@@ -78,6 +84,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
#if VALUE_OBJECT
@@ -839,7 +846,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -863,11 +870,11 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp);
}
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
MapEntry entry = new MapEntry();
for(int i = 0,m=segments.length;i<m;i++) {
@@ -877,7 +884,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try {
while(index != -1) {
entry.set(index, i);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
index = (int)seg.links[index];
}
}
@@ -885,7 +892,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp);
}
}
return null;
return Optional.empty();
}
@Override
@@ -1186,7 +1193,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1210,11 +1217,11 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp);
}
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
@@ -1222,7 +1229,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try {
int index = seg.firstIndex;
while(index != -1){
if(filter.test(seg.keys[index])) return seg.keys[index];
if(filter.test(seg.keys[index])) return OPTIONAL.GET_OPTIONAL(seg.keys[index]);
index = (int)seg.links[index];
}
}
@@ -1230,7 +1237,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp);
}
}
return EMPTY_KEY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1454,7 +1461,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1478,20 +1485,20 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp);
}
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE;
if(size() <= 0) return VALUE_OPTIONAL.empty();
for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock();
try {
int index = seg.firstIndex;
while(index != -1){
if(filter.test(seg.values[index])) return seg.values[index];
if(filter.test(seg.values[index])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(seg.values[index]);
index = (int)seg.links[index];
}
}
@@ -1499,7 +1506,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp);
}
}
return EMPTY_VALUE;
return VALUE_OPTIONAL.empty();
}
@Override
@@ -4,14 +4,17 @@ import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -27,6 +30,7 @@ import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#if !TYPE_INT || !SAME_TYPE
@@ -40,7 +44,7 @@ import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
#if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
@@ -59,6 +63,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
#if !TYPE_OBJECT
@@ -233,13 +238,13 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value;
moveToFirstIndex(nullIndex);
moveToFirstIndex(nullIndex, false);
return lastValue;
}
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex);
moveToFirstIndex(nullIndex, true);
}
else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
@@ -247,7 +252,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(strategy.equals(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos];
values[pos] = value;
moveToFirstIndex(pos);
moveToFirstIndex(pos, false);
return lastValue;
}
pos = ++pos & mask;
@@ -255,7 +260,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
moveToFirstIndex(pos);
moveToFirstIndex(pos, true);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
@@ -267,13 +272,13 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value;
moveToLastIndex(nullIndex);
moveToLastIndex(nullIndex, false);
return lastValue;
}
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
moveToLastIndex(nullIndex);
moveToLastIndex(nullIndex, true);
}
else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
@@ -281,7 +286,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(strategy.equals(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos];
values[pos] = value;
moveToLastIndex(pos);
moveToLastIndex(pos, false);
return lastValue;
}
pos = ++pos & mask;
@@ -289,7 +294,55 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
moveToLastIndex(pos);
moveToLastIndex(pos, true);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE putFirst(KEY_TYPE key, VALUE_TYPE value) {
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) return values[nullIndex];
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex, true);
}
else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) return values[pos];
pos = ++pos & mask;
}
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
moveToFirstIndex(pos, true);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE putLast(KEY_TYPE key, VALUE_TYPE value) {
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) return values[nullIndex];
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
moveToLastIndex(nullIndex, true);
}
else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) return values[pos];
pos = ++pos & mask;
}
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
moveToLastIndex(pos, true);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
@@ -300,7 +353,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(isEmpty() || strategy.equals(FIRST_ENTRY_KEY(), key)) return false;
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
moveToFirstIndex(nullIndex, false);
return true;
}
}
@@ -308,7 +361,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) {
moveToFirstIndex(pos);
moveToFirstIndex(pos, false);
return true;
}
pos = ++pos & mask;
@@ -322,7 +375,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(isEmpty() || strategy.equals(LAST_ENTRY_KEY(), key)) return false;
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToLastIndex(nullIndex);
moveToLastIndex(nullIndex, false);
return true;
}
}
@@ -330,7 +383,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) {
moveToLastIndex(pos);
moveToLastIndex(pos, false);
return true;
}
pos = ++pos & mask;
@@ -343,7 +396,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) {
int index = findIndex(key);
if(index < 0) return getDefaultReturnValue();
moveToFirstIndex(index);
moveToFirstIndex(index, false);
return values[index];
}
@@ -351,7 +404,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) {
int index = findIndex(key);
if(index < 0) return getDefaultReturnValue();
moveToLastIndex(index);
moveToLastIndex(index, false);
return values[index];
}
@@ -430,6 +483,52 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
return values[lastIndex];
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[firstIndex], values[firstIndex]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[lastIndex], values[lastIndex]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() {
if(size == 0) throw new NoSuchElementException();
int pos = firstIndex;
onNodeRemoved(pos);
BasicEntry KEY_VALUE_GENERIC_TYPE result = new BasicEntryKV_BRACES(keys[pos], values[pos]);
size--;
if(strategy.equals(result.ENTRY_KEY(), EMPTY_KEY_VALUE)) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() {
if(size == 0) throw new NoSuchElementException();
int pos = lastIndex;
onNodeRemoved(pos);
BasicEntry KEY_VALUE_GENERIC_TYPE result = new BasicEntryKV_BRACES(keys[pos], values[pos]);
size--;
if(strategy.equals(result.ENTRY_KEY(), EMPTY_KEY_VALUE)) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet();
@@ -443,9 +542,9 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values();
return valuesC;
return (VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE)valuesC;
}
@Override
@@ -481,8 +580,8 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
containsNull = false;
}
protected void moveToFirstIndex(int startPos) {
if(size == 1 || firstIndex == startPos) return;
protected void moveToFirstIndex(int startPos, boolean adding) {
if(size == (adding ? 0 : 1) || firstIndex == startPos) return;
if(lastIndex == startPos) {
lastIndex = (int)(links[startPos] >>> 32);
links[lastIndex] |= 0xFFFFFFFFL;
@@ -499,8 +598,8 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
firstIndex = startPos;
}
protected void moveToLastIndex(int startPos) {
if(size == 1 || lastIndex == startPos) return;
protected void moveToLastIndex(int startPos, boolean adding) {
if(size == (adding ? 0 : 1) || lastIndex == startPos) return;
if(firstIndex == startPos) {
firstIndex = (int)links[startPos];
links[lastIndex] |= 0xFFFFFFFF00000000L;
@@ -614,6 +713,10 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
private class MapEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> implements ORDERED_MAP.FastOrderedSet KEY_VALUE_GENERIC_TYPE {
@Override
public void addFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
@@ -630,24 +733,24 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getFirst() {
return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getLast() {
return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeFirst() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY();
return entry;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeLast() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY();
return entry;
@@ -655,7 +758,12 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
return new EntryIterator(true);
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new EntryIterator(false);
}
@Override
@@ -665,7 +773,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator();
return new FastEntryIterator(true);
}
@Override
@@ -774,7 +882,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -789,21 +897,21 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
state = operator.apply(state, new ValueMapEntry(index));
index = (int)links[index];
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
MapEntry entry = new MapEntry();
int index = firstIndex;
while(index != -1) {
entry.set(index);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
index = (int)links[index];
}
return null;
return Optional.empty();
}
@Override
@@ -900,10 +1008,13 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public boolean add(KEY_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -919,7 +1030,12 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new KeyIterator();
return new KeyIterator(true);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new KeyIterator(false);
}
@Override
@@ -941,22 +1057,22 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
@Override
public KEY_TYPE FIRST_KEY() {
public KEY_TYPE GET_FIRST_KEY() {
return FIRST_ENTRY_KEY();
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
public KEY_TYPE REMOVE_FIRST_KEY() {
return POLL_FIRST_ENTRY_KEY();
}
@Override
public KEY_TYPE LAST_KEY() {
public KEY_TYPE GET_LAST_KEY() {
return LAST_ENTRY_KEY();
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
public KEY_TYPE REMOVE_LAST_KEY() {
return POLL_LAST_ENTRY_KEY();
}
@@ -1056,7 +1172,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1071,19 +1187,19 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
state = operator.APPLY_KEY_VALUE(state, keys[index]);
index = (int)links[index];
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE;
if(size() <= 0) return OPTIONAL.empty();
int index = firstIndex;
while(index != -1){
if(filter.test(keys[index])) return keys[index];
if(filter.test(keys[index])) return OPTIONAL.GET_OPTIONAL(keys[index]);
index = (int)links[index];
}
return EMPTY_KEY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1100,39 +1216,47 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
}
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE implements VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE {
#if VALUE_OBJECT
@Override
@Deprecated
public boolean contains(Object e) {
return containsValue(e);
}
public boolean contains(Object e) { return containsValue(e); }
#else
@Override
public boolean contains(VALUE_TYPE e) {
return containsValue(e);
}
public boolean contains(VALUE_TYPE e) { return containsValue(e); }
#endif
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
@Override
public int size() {
return LINKED_CUSTOM_HASH_MAP.this.size();
}
public int size() { return LINKED_CUSTOM_HASH_MAP.this.size(); }
@Override
public void clear() {
LINKED_CUSTOM_HASH_MAP.this.clear();
public void clear() { LINKED_CUSTOM_HASH_MAP.this.clear(); }
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); }
private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new ValueIterator(false);
}
@Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void addLast(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE VALUE_GET_FIRST_KEY() { return FIRST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_FIRST_KEY() {
VALUE_TYPE result = FIRST_ENTRY_VALUE();
POLL_FIRST_ENTRY_KEY();
return result;
}
@Override
public VALUE_TYPE VALUE_GET_LAST_KEY() { return LAST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_LAST_KEY() {
VALUE_TYPE result = LAST_ENTRY_VALUE();
POLL_LAST_ENTRY_KEY();
return result;
}
@Override
@@ -1231,7 +1355,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1246,19 +1370,19 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
state = operator.APPLY_VALUE(state, values[index]);
index = (int)links[index];
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE;
if(size() <= 0) return VALUE_OPTIONAL.empty();
int index = firstIndex;
while(index != -1){
if(filter.test(values[index])) return values[index];
if(filter.test(values[index])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[index]);
index = (int)links[index];
}
return EMPTY_VALUE;
return VALUE_OPTIONAL.empty();
}
@Override
@@ -1278,7 +1402,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry();
public FastEntryIterator() {}
public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(KEY_TYPE from) {
super(from);
}
@@ -1305,7 +1429,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry;
public EntryIterator() {}
public EntryIterator(boolean start) { super(start); }
public EntryIterator(KEY_TYPE from) {
super(from);
}
@@ -1335,7 +1459,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {}
public KeyIterator(boolean start) { super(start); }
public KeyIterator(KEY_TYPE from) {
super(from);
}
@@ -1357,7 +1481,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {}
public ValueIterator(boolean start) { super(start); }
@Override
public VALUE_TYPE VALUE_PREVIOUS() {
@@ -1378,16 +1502,20 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
private class MapIterator {
boolean forward;
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
MapIterator() {
next = firstIndex;
MapIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
}
MapIterator(KEY_TYPE from) {
this.forward = true;
if(strategy.equals(from, EMPTY_KEY_VALUE)) {
if(containsNull) {
next = (int) links[nullIndex];
@@ -1415,11 +1543,11 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
}
public boolean hasNext() {
return next != -1;
return (forward ? next : previous) != -1;
}
public boolean hasPrevious() {
return previous != -1;
return (forward ? previous : next) != -1;
}
public int nextIndex() {
@@ -1479,20 +1607,30 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
current = previous;
previous = (int)(links[current] >> 32);
next = current;
if(forward) moveBackwards();
else moveForwards();
if(index >= 0) index--;
return current;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
if(forward) moveForwards();
else moveBackwards();
if(index >= 0) index++;
return current;
}
private void moveBackwards() {
current = previous;
previous = (int)(links[current] >> 32);
next = current;
}
private void moveForwards() {
current = next;
next = (int)(links[current]);
previous = current;
if(index >= 0) index++;
return current;
}
private void ensureIndexKnown() {
@@ -5,14 +5,17 @@ import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
#if !TYPE_OBJECT
@@ -37,9 +40,12 @@ import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if !VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
#if !TYPE_OBJECT
@@ -75,6 +81,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
import speiger.src.collections.objects.collections.ObjectIterator;
@@ -1090,7 +1097,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -1107,25 +1114,25 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
}
state = operator.apply(state, new ValueMapEntry(i));
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
MapEntry entry = new MapEntry();
if(containsNull) {
entry.set(nullIndex);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
}
for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) {
entry.set(i);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
}
}
return null;
return Optional.empty();
}
@Override
@@ -1331,7 +1338,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1348,18 +1355,18 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
}
state = operator.APPLY_KEY_VALUE(state, keys[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE;
if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex];
if(size() <= 0) return OPTIONAL.empty();
if(containsNull && filter.test(keys[nullIndex])) return OPTIONAL.GET_OPTIONAL(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return keys[i];
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return OPTIONAL.GET_OPTIONAL(keys[i]);
}
return EMPTY_KEY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1497,7 +1504,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1514,18 +1521,18 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
}
state = operator.APPLY_VALUE(state, values[i]);
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE;
if(containsNull && filter.test(values[nullIndex])) return values[nullIndex];
if(size() <= 0) return VALUE_OPTIONAL.empty();
if(containsNull && filter.test(values[nullIndex])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(values[i])) return values[i];
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(values[i])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[i]);
}
return EMPTY_VALUE;
return VALUE_OPTIONAL.empty();
}
@Override
@@ -4,14 +4,17 @@ import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -27,6 +30,7 @@ import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#if !TYPE_INT || !SAME_TYPE
@@ -39,7 +43,7 @@ import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
#if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
@@ -58,6 +62,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
#if !TYPE_OBJECT
@@ -210,13 +215,13 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value;
moveToFirstIndex(nullIndex);
moveToFirstIndex(nullIndex, false);
return lastValue;
}
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex);
moveToFirstIndex(nullIndex, true);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
@@ -224,7 +229,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(KEY_EQUALS(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos];
values[pos] = value;
moveToFirstIndex(pos);
moveToFirstIndex(pos, false);
return lastValue;
}
pos = ++pos & mask;
@@ -232,7 +237,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
moveToFirstIndex(pos);
moveToFirstIndex(pos, true);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
@@ -244,13 +249,13 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value;
moveToLastIndex(nullIndex);
moveToLastIndex(nullIndex, false);
return lastValue;
}
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
moveToLastIndex(nullIndex);
moveToLastIndex(nullIndex, true);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
@@ -258,7 +263,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(KEY_EQUALS(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos];
values[pos] = value;
moveToLastIndex(pos);
moveToLastIndex(pos, false);
return lastValue;
}
pos = ++pos & mask;
@@ -266,7 +271,55 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
moveToLastIndex(pos);
moveToLastIndex(pos, true);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE putFirst(KEY_TYPE key, VALUE_TYPE value) {
if(KEY_EQUALS_NULL(key)) {
if(containsNull) return values[nullIndex];
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex, true);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], key)) return values[pos];
pos = ++pos & mask;
}
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
moveToFirstIndex(pos, true);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE putLast(KEY_TYPE key, VALUE_TYPE value) {
if(KEY_EQUALS_NULL(key)) {
if(containsNull) return values[nullIndex];
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
moveToLastIndex(nullIndex, true);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], key)) return values[pos];
pos = ++pos & mask;
}
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
moveToLastIndex(pos, true);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
@@ -277,7 +330,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(isEmpty() || KEY_EQUALS(FIRST_ENTRY_KEY(), key)) return false;
if(KEY_EQUALS_NULL(key)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
moveToFirstIndex(nullIndex, false);
return true;
}
}
@@ -285,7 +338,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], key)) {
moveToFirstIndex(pos);
moveToFirstIndex(pos, false);
return true;
}
pos = ++pos & mask;
@@ -299,7 +352,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(isEmpty() || KEY_EQUALS(LAST_ENTRY_KEY(), key)) return false;
if(KEY_EQUALS_NULL(key)) {
if(containsNull) {
moveToLastIndex(nullIndex);
moveToLastIndex(nullIndex, false);
return true;
}
}
@@ -307,7 +360,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], key)) {
moveToLastIndex(pos);
moveToLastIndex(pos, false);
return true;
}
pos = ++pos & mask;
@@ -320,7 +373,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) {
int index = findIndex(key);
if(index < 0) return getDefaultReturnValue();
moveToFirstIndex(index);
moveToFirstIndex(index, false);
return values[index];
}
@@ -328,7 +381,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) {
int index = findIndex(key);
if(index < 0) return getDefaultReturnValue();
moveToLastIndex(index);
moveToLastIndex(index, false);
return values[index];
}
@@ -434,6 +487,52 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
return values[lastIndex];
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[firstIndex], values[firstIndex]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[lastIndex], values[lastIndex]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() {
if(size == 0) throw new NoSuchElementException();
int pos = firstIndex;
onNodeRemoved(pos);
BasicEntry KEY_VALUE_GENERIC_TYPE result = new BasicEntryKV_BRACES(keys[pos], values[pos]);
size--;
if(KEY_EQUALS_NULL(result.ENTRY_KEY())) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() {
if(size == 0) throw new NoSuchElementException();
int pos = lastIndex;
onNodeRemoved(pos);
BasicEntry KEY_VALUE_GENERIC_TYPE result = new BasicEntryKV_BRACES(keys[pos], values[pos]);
size--;
if(KEY_EQUALS_NULL(result.ENTRY_KEY())) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet();
@@ -447,9 +546,9 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values();
return valuesC;
return (VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE)valuesC;
}
@Override
@@ -485,8 +584,8 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
containsNull = false;
}
protected void moveToFirstIndex(int startPos) {
if(size == 1 || firstIndex == startPos) return;
protected void moveToFirstIndex(int startPos, boolean adding) {
if(size == (adding ? 0 : 1) || firstIndex == startPos) return;
if(lastIndex == startPos) {
lastIndex = (int)(links[startPos] >>> 32);
links[lastIndex] |= 0xFFFFFFFFL;
@@ -503,8 +602,8 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
firstIndex = startPos;
}
protected void moveToLastIndex(int startPos) {
if(size == 1 || lastIndex == startPos) return;
protected void moveToLastIndex(int startPos, boolean adding) {
if(size == (adding ? 0 : 1) || lastIndex == startPos) return;
if(firstIndex == startPos) {
firstIndex = (int)links[startPos];
links[lastIndex] |= 0xFFFFFFFF00000000L;
@@ -618,6 +717,10 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
private class MapEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> implements ORDERED_MAP.FastOrderedSet KEY_VALUE_GENERIC_TYPE {
@Override
public void addFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
@@ -634,24 +737,24 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getFirst() {
return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getLast() {
return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeFirst() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY();
return entry;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeLast() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY();
return entry;
@@ -659,7 +762,12 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
return new EntryIterator(true);
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new EntryIterator(false);
}
@Override
@@ -669,7 +777,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator();
return new FastEntryIterator(true);
}
@Override
@@ -778,7 +886,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -793,21 +901,21 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
state = operator.apply(state, new ValueMapEntry(index));
index = (int)links[index];
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
MapEntry entry = new MapEntry();
int index = firstIndex;
while(index != -1) {
entry.set(index);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
index = (int)links[index];
}
return null;
return Optional.empty();
}
@Override
@@ -899,6 +1007,12 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
#endif
@Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -918,7 +1032,12 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new KeyIterator();
return new KeyIterator(true);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new KeyIterator(false);
}
@Override
@@ -940,22 +1059,22 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
@Override
public KEY_TYPE FIRST_KEY() {
public KEY_TYPE GET_FIRST_KEY() {
return FIRST_ENTRY_KEY();
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
public KEY_TYPE REMOVE_FIRST_KEY() {
return POLL_FIRST_ENTRY_KEY();
}
@Override
public KEY_TYPE LAST_KEY() {
public KEY_TYPE GET_LAST_KEY() {
return LAST_ENTRY_KEY();
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
public KEY_TYPE REMOVE_LAST_KEY() {
return POLL_LAST_ENTRY_KEY();
}
@@ -1055,7 +1174,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1070,19 +1189,19 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
state = operator.APPLY_KEY_VALUE(state, keys[index]);
index = (int)links[index];
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE;
if(size() <= 0) return OPTIONAL.empty();
int index = firstIndex;
while(index != -1){
if(filter.test(keys[index])) return keys[index];
if(filter.test(keys[index])) return OPTIONAL.GET_OPTIONAL(keys[index]);
index = (int)links[index];
}
return EMPTY_KEY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1099,41 +1218,50 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
}
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE implements VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE {
#if VALUE_OBJECT
@Override
@Deprecated
public boolean contains(Object e) {
return containsValue(e);
}
public boolean contains(Object e) { return containsValue(e); }
#else
@Override
public boolean contains(VALUE_TYPE e) {
return containsValue(e);
}
public boolean contains(VALUE_TYPE e) { return containsValue(e); }
#endif
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
@Override
public int size() {
return LINKED_HASH_MAP.this.size();
}
public int size() { return LINKED_HASH_MAP.this.size(); }
@Override
public void clear() {
LINKED_HASH_MAP.this.clear();
public void clear() { LINKED_HASH_MAP.this.clear(); }
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); }
private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new ValueIterator(false);
}
@Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void addLast(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE VALUE_GET_FIRST_KEY() { return FIRST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_FIRST_KEY() {
VALUE_TYPE result = FIRST_ENTRY_VALUE();
POLL_FIRST_ENTRY_KEY();
return result;
}
@Override
public VALUE_TYPE VALUE_GET_LAST_KEY() { return LAST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_LAST_KEY() {
VALUE_TYPE result = LAST_ENTRY_VALUE();
POLL_LAST_ENTRY_KEY();
return result;
}
@Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action);
@@ -1231,7 +1359,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1246,19 +1374,19 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
state = operator.APPLY_VALUE(state, values[index]);
index = (int)links[index];
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE;
if(size() <= 0) return VALUE_OPTIONAL.empty();
int index = firstIndex;
while(index != -1){
if(filter.test(values[index])) return values[index];
if(filter.test(values[index])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[index]);
index = (int)links[index];
}
return EMPTY_VALUE;
return VALUE_OPTIONAL.empty();
}
@Override
@@ -1278,7 +1406,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry();
public FastEntryIterator() {}
public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(KEY_TYPE from) {
super(from);
}
@@ -1305,7 +1433,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry;
public EntryIterator() {}
public EntryIterator(boolean start) { super(start); }
public EntryIterator(KEY_TYPE from) {
super(from);
}
@@ -1335,7 +1463,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {}
public KeyIterator(boolean start) { super(start); }
public KeyIterator(KEY_TYPE from) {
super(from);
}
@@ -1357,7 +1485,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {}
public ValueIterator(boolean start) { super(start); }
@Override
public VALUE_TYPE VALUE_PREVIOUS() {
@@ -1377,13 +1505,16 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
private class MapIterator {
boolean forward;
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
MapIterator() {
next = firstIndex;
MapIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
}
MapIterator(KEY_TYPE from) {
@@ -1414,11 +1545,11 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
}
public boolean hasNext() {
return next != -1;
return (forward ? next : previous) != -1;
}
public boolean hasPrevious() {
return previous != -1;
return (forward ? previous : next) != -1;
}
public int nextIndex() {
@@ -1478,20 +1609,30 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
current = previous;
previous = (int)(links[current] >> 32);
next = current;
if(forward) moveBackwards();
else moveForwards();
if(index >= 0) index--;
return current;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
if(forward) moveForwards();
else moveBackwards();
if(index >= 0) index++;
return current;
}
private void moveBackwards() {
current = previous;
previous = (int)(links[current] >> 32);
next = current;
}
private void moveForwards() {
current = next;
next = (int)(links[current]);
previous = current;
if(index >= 0) index++;
return current;
}
private void ensureIndexKnown() {
@@ -5,14 +5,17 @@ import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
#if !TYPE_OBJECT
@@ -37,9 +40,12 @@ import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if !VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
#if !TYPE_OBJECT
@@ -73,6 +79,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
import speiger.src.collections.objects.collections.ObjectIterator;
@@ -1049,7 +1056,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -1066,25 +1073,25 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
}
state = operator.apply(state, new ValueMapEntry(i));
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
MapEntry entry = new MapEntry();
if(containsNull) {
entry.set(nullIndex);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
}
for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) {
entry.set(i);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
}
}
return null;
return Optional.empty();
}
@Override
@@ -1286,7 +1293,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1303,18 +1310,18 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
}
state = operator.APPLY_KEY_VALUE(state, keys[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE;
if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex];
if(size() <= 0) return OPTIONAL.empty();
if(containsNull && filter.test(keys[nullIndex])) return OPTIONAL.GET_OPTIONAL(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return keys[i];
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return OPTIONAL.GET_OPTIONAL(keys[i]);
}
return EMPTY_KEY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1452,7 +1459,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1469,18 +1476,18 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
}
state = operator.APPLY_VALUE(state, values[i]);
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE;
if(containsNull && filter.test(values[nullIndex])) return values[nullIndex];
if(size() <= 0) return VALUE_OPTIONAL.empty();
if(containsNull && filter.test(values[nullIndex])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(values[i])) return values[i];
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(values[i])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[i]);
}
return EMPTY_VALUE;
return VALUE_OPTIONAL.empty();
}
@Override
@@ -4,14 +4,17 @@ import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
#if !TYPE_OBJECT
@@ -26,9 +29,12 @@ import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if !VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
@@ -59,13 +65,14 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
#endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER;
#if !SAME_TYPE
@@ -119,7 +126,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
/** KeySet cache */
protected transient ORDERED_SET KEY_GENERIC_TYPE keySet;
/** Values cache */
protected transient VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC;
protected transient VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE valuesC;
/** Amount of Elements stored in the HashMap */
protected int size;
@@ -320,6 +327,10 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE putFirst(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE putLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(KEY_TYPE key) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToLast(KEY_TYPE key) { throw new UnsupportedOperationException(); }
@@ -441,7 +452,24 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
public VALUE_TYPE LAST_ENTRY_VALUE() {
if(size == 0) throw new NoSuchElementException();
return values[lastIndex];
}
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[firstIndex], values[firstIndex]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[lastIndex], values[lastIndex]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() { throw new UnsupportedOperationException(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() { throw new UnsupportedOperationException(); }
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
@@ -456,7 +484,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values();
return valuesC;
}
@@ -609,6 +637,10 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
}
private class MapEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> implements ORDERED_MAP.FastOrderedSet KEY_VALUE_GENERIC_TYPE {
@Override
public void addFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
@@ -621,24 +653,29 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
public boolean moveToLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getFirst() {
return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getLast() {
return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() { throw new UnsupportedOperationException(); }
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeFirst() { throw new UnsupportedOperationException(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() { throw new UnsupportedOperationException(); }
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeLast() { throw new UnsupportedOperationException(); }
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
return new EntryIterator(true);
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new EntryIterator(false);
}
@Override
@@ -648,7 +685,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator();
return new FastEntryIterator(true);
}
@Override
@@ -757,7 +794,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -772,21 +809,21 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
state = operator.apply(state, new BasicEntryKV_BRACES(keys[index], values[index]));
index = (int)links[index];
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
int index = firstIndex;
while(index != -1) {
entry.set(keys[index], values[index]);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
index = (int)links[index];
}
return null;
return Optional.empty();
}
@Override
@@ -861,6 +898,12 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
throw new UnsupportedOperationException();
}
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -875,7 +918,12 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new KeyIterator();
return new KeyIterator(true);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new KeyIterator(false);
}
@Override
@@ -895,20 +943,20 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
public void clear() { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE FIRST_KEY() {
public KEY_TYPE GET_FIRST_KEY() {
return FIRST_ENTRY_KEY();
}
@Override
public KEY_TYPE POLL_FIRST_KEY() { throw new UnsupportedOperationException(); }
public KEY_TYPE REMOVE_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE LAST_KEY() {
public KEY_TYPE GET_LAST_KEY() {
return LAST_ENTRY_KEY();
}
@Override
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); }
public KEY_TYPE REMOVE_LAST_KEY() { throw new UnsupportedOperationException(); }
@Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
@@ -1006,7 +1054,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1021,19 +1069,19 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
state = operator.APPLY_KEY_VALUE(state, keys[index]);
index = (int)links[index];
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE;
if(size() <= 0) return OPTIONAL.empty();
int index = firstIndex;
while(index != -1){
if(filter.test(keys[index])) return keys[index];
if(filter.test(keys[index])) return OPTIONAL.GET_OPTIONAL(keys[index]);
index = (int)links[index];
}
return EMPTY_KEY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1050,39 +1098,42 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
}
}
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE implements VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE {
#if VALUE_OBJECT
@Override
@Deprecated
public boolean contains(Object e) {
return containsValue(e);
}
public boolean contains(Object e) { return containsValue(e); }
#else
@Override
public boolean contains(VALUE_TYPE e) {
return containsValue(e);
}
public boolean contains(VALUE_TYPE e) { return containsValue(e); }
#endif
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
@Override
public int size() {
return IMMUTABLE_HASH_MAP.this.size();
}
public int size() { return IMMUTABLE_HASH_MAP.this.size(); }
@Override
public void clear() { throw new UnsupportedOperationException(); }
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); }
private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new ValueIterator(false);
}
@Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void addLast(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE VALUE_GET_FIRST_KEY() { return FIRST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE VALUE_GET_LAST_KEY() { return LAST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_LAST_KEY() { throw new UnsupportedOperationException(); }
@Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
int index = firstIndex;
@@ -1179,7 +1230,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1194,19 +1245,19 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
state = operator.APPLY_VALUE(state, values[index]);
index = (int)links[index];
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE;
if(size() <= 0) return VALUE_OPTIONAL.empty();
int index = firstIndex;
while(index != -1){
if(filter.test(values[index])) return values[index];
if(filter.test(values[index])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[index]);
index = (int)links[index];
}
return EMPTY_VALUE;
return VALUE_OPTIONAL.empty();
}
@Override
@@ -1226,7 +1277,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry();
public FastEntryIterator() {}
public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(KEY_TYPE from) {
super(from);
}
@@ -1252,7 +1303,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
public EntryIterator() {}
public EntryIterator(boolean start) { super(start); }
public EntryIterator(KEY_TYPE from) {
super(from);
}
@@ -1279,7 +1330,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {}
public KeyIterator(boolean start) { super(start); }
public KeyIterator(KEY_TYPE from) {
super(from);
}
@@ -1301,7 +1352,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
}
private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {}
public ValueIterator(boolean start) { super(start); }
@Override
public VALUE_TYPE VALUE_PREVIOUS() {
@@ -1322,13 +1373,16 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
}
private class MapIterator {
boolean forward;
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
MapIterator() {
next = firstIndex;
MapIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
}
MapIterator(KEY_TYPE from) {
@@ -1359,11 +1413,11 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
}
public boolean hasNext() {
return next != -1;
return (forward ? next : previous) != -1;
}
public boolean hasPrevious() {
return previous != -1;
return (forward ? previous : next) != -1;
}
public int nextIndex() {
@@ -1380,20 +1434,30 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
current = previous;
previous = (int)(links[current] >> 32);
next = current;
if(forward) moveBackwards();
else moveForwards();
if(index >= 0) index--;
return current;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
if(forward) moveForwards();
else moveBackwards();
if(index >= 0) index++;
return current;
}
private void moveBackwards() {
current = previous;
previous = (int)(links[current] >> 32);
next = current;
}
private void moveForwards() {
current = next;
next = (int)(links[current]);
previous = current;
if(index >= 0) index++;
return current;
}
private void ensureIndexKnown() {
@@ -4,14 +4,17 @@ import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -26,9 +29,12 @@ import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if!VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
@@ -46,7 +52,7 @@ import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER;
#if !SAME_TYPE
@@ -66,6 +72,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
#if !VALUE_OBJECT
@@ -105,7 +112,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
/** KeySet cache */
protected ORDERED_SET KEY_GENERIC_TYPE keySet;
/** Values cache */
protected VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC;
protected VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE valuesC;
/** EntrySet cache */
protected FastOrderedSet KEY_VALUE_GENERIC_TYPE entrySet;
@@ -275,6 +282,27 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
return lastValue;
}
@Override
public VALUE_TYPE putFirst(KEY_TYPE key, VALUE_TYPE value) {
int index = findIndex(key);
if(index < 0) {
insertIndex(0, key, value);
size++;
return getDefaultReturnValue();
}
return values[index];
}
@Override
public VALUE_TYPE putLast(KEY_TYPE key, VALUE_TYPE value) {
int index = findIndex(key);
if(index < 0) {
insertIndex(size++, key, value);
return getDefaultReturnValue();
}
return values[index];
}
@Override
public boolean moveToFirst(KEY_TYPE key) {
int index = findIndex(key);
@@ -402,6 +430,34 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
return result;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[0], values[0]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[size-1], values[size-1]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() {
if(size == 0) throw new NoSuchElementException();
BasicEntry KEY_VALUE_GENERIC_TYPE result = new BasicEntryKV_BRACES(keys[0], values[0]);
removeIndex(0);
return result;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() {
if(size == 0) throw new NoSuchElementException();
BasicEntry KEY_VALUE_GENERIC_TYPE result = new BasicEntryKV_BRACES(keys[size-1], values[size-1]);
removeIndex(size-1);
return result;
}
@Override
public VALUE_TYPE REMOVE_VALUE(KEY_TYPE key) {
int index = findIndex(key);
@@ -461,7 +517,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values();
return valuesC;
}
@@ -812,6 +868,10 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
private class MapEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> implements ORDERED_MAP.FastOrderedSet KEY_VALUE_GENERIC_TYPE {
@Override
public void addFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
@@ -828,24 +888,24 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getFirst() {
return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getLast() {
return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeFirst() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY();
return entry;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeLast() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY();
return entry;
@@ -853,7 +913,12 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
return new EntryIterator(true);
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new EntryIterator(false);
}
@Override
@@ -863,7 +928,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator();
return new FastEntryIterator(true);
}
@Override
@@ -955,7 +1020,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -967,19 +1032,19 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
state = operator.apply(state, new ValueMapEntry(i));
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
MapEntry entry = new MapEntry();
for(int i = 0;i<size;i++) {
entry.set(i);
if(filter.test(entry)) return entry;
if(filter.test(entry)) return Optional.ofNullable(entry);
}
return null;
return Optional.empty();
}
@Override
@@ -1065,6 +1130,10 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -1073,7 +1142,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean moveToLast(KEY_TYPE o) { return ARRAY_MAP.this.moveToLast(o); }
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { return new KeyIterator(); }
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { return new KeyIterator(true); }
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() { return new KeyIterator(false); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return new KeyIterator(fromElement); }
@Override
@@ -1081,13 +1152,13 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public void clear() { ARRAY_MAP.this.clear(); }
@Override
public KEY_TYPE FIRST_KEY() { return FIRST_ENTRY_KEY(); }
public KEY_TYPE GET_FIRST_KEY() { return FIRST_ENTRY_KEY(); }
@Override
public KEY_TYPE POLL_FIRST_KEY() { return POLL_FIRST_ENTRY_KEY(); }
public KEY_TYPE REMOVE_FIRST_KEY() { return POLL_FIRST_ENTRY_KEY(); }
@Override
public KEY_TYPE LAST_KEY() { return LAST_ENTRY_KEY(); }
public KEY_TYPE GET_LAST_KEY() { return LAST_ENTRY_KEY(); }
@Override
public KEY_TYPE POLL_LAST_KEY() { return POLL_LAST_ENTRY_KEY(); }
public KEY_TYPE REMOVE_LAST_KEY() { return POLL_LAST_ENTRY_KEY(); }
@Override
public KeySet copy() { throw new UnsupportedOperationException(); }
@@ -1162,7 +1233,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1174,16 +1245,16 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
state = operator.APPLY_KEY_VALUE(state, keys[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(keys[i])) return keys[i];
if(filter.test(keys[i])) return OPTIONAL.GET_OPTIONAL(keys[i]);
}
return EMPTY_KEY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1197,40 +1268,49 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
}
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE implements VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE {
#if VALUE_OBJECT
@Override
public boolean contains(Object e) {
return containsValue(e);
}
public boolean contains(Object e) { return containsValue(e); }
#else
@Override
public boolean contains(VALUE_TYPE e) {
return containsValue(e);
}
public boolean contains(VALUE_TYPE e) { return containsValue(e); }
#endif
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
@Override
public int size() {
return ARRAY_MAP.this.size();
}
public int size() { return ARRAY_MAP.this.size(); }
@Override
public void clear() {
ARRAY_MAP.this.clear();
public void clear() { ARRAY_MAP.this.clear(); }
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); }
private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new ValueIterator(false);
}
@Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void addLast(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE VALUE_GET_FIRST_KEY() { return FIRST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_FIRST_KEY() {
VALUE_TYPE result = FIRST_ENTRY_VALUE();
POLL_FIRST_ENTRY_KEY();
return result;
}
@Override
public VALUE_TYPE VALUE_GET_LAST_KEY() { return LAST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_LAST_KEY() {
VALUE_TYPE result = LAST_ENTRY_VALUE();
POLL_LAST_ENTRY_KEY();
return result;
}
@Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action);
@@ -1294,7 +1374,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1306,16 +1386,16 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
state = operator.APPLY_VALUE(state, values[i]);
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(values[i])) return values[i];
if(filter.test(values[i])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[i]);
}
return EMPTY_VALUE;
return VALUE_OPTIONAL.empty();
}
@Override
@@ -1332,10 +1412,8 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry();
public FastEntryIterator() {}
public FastEntryIterator(KEY_TYPE from) {
index = findIndex(from);
}
public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(KEY_TYPE element) { super(element); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
@@ -1358,11 +1436,8 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = null;
public EntryIterator() {}
public EntryIterator(KEY_TYPE from) {
index = findIndex(from);
if(index == -1) throw new NoSuchElementException();
}
public EntryIterator(boolean start) { super(start); }
public EntryIterator(KEY_TYPE element) { super(element); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
@@ -1389,11 +1464,8 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {}
public KeyIterator(KEY_TYPE element) {
index = findIndex(element);
if(index == -1) throw new NoSuchElementException();
}
public KeyIterator(boolean start) { super(start); }
public KeyIterator(KEY_TYPE element) { super(element); }
@Override
public KEY_TYPE PREVIOUS() {
@@ -1413,6 +1485,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator(boolean start) { super(start); }
public ValueIterator(KEY_TYPE element) { super(element); }
@Override
public VALUE_TYPE VALUE_PREVIOUS() {
return values[previousEntry()];
@@ -1431,23 +1506,37 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
private class MapIterator {
boolean forward;
int index;
int lastReturned = -1;
MapIterator(boolean start) {
this.forward = start;
this.index = start ? 0 : size;
}
MapIterator(KEY_TYPE element) {
this.forward = true;
index = findIndex(element);
if(index == -1) throw new NoSuchElementException();
}
public boolean hasNext() {
return index < size;
return forward ? index < size : index > 0;
}
public boolean hasPrevious() {
return index > 0;
return forward ? index > 0 : index < size;
}
public int nextIndex() {
return index;
if(forward) return index;
return size - index;
}
public int previousIndex() {
return index-1;
if(forward) return index-1;
return (size - index)-1;
}
public void remove() {
@@ -1460,26 +1549,42 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
index--;
return (lastReturned = index);
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
if(forward) {
index--;
return (lastReturned = index);
}
lastReturned = index;
return index++;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
if(forward) {
lastReturned = index;
return index++;
}
index--;
return (lastReturned = index);
}
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
return forward ? moveForward(amount) : moveBackwards(amount);
}
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
return forward ? moveBackwards(amount) : moveForward(amount);
}
private int moveForward(int amount) {
int steps = Math.min(amount, size() - index);
index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps;
}
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
private int moveBackwards(int amount) {
int steps = Math.min(amount, index);
index -= steps;
if(steps > 0) lastReturned = Math.min(index, size()-1);
@@ -18,7 +18,7 @@ import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
#if !VALUE_OBJECT && !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER;
@@ -216,6 +216,28 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE putFirst(T key, VALUE_TYPE value) {
int index = key.ordinal();
if(isSet(index)) return values[index];
set(index);
values[index] = value;
onNodeAdded(index);
moveToFirstIndex(index);
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE putLast(T key, VALUE_TYPE value) {
int index = key.ordinal();
if(isSet(index)) return values[index];
set(index);
values[index] = value;
onNodeAdded(index);
moveToLastIndex(index);
return getDefaultReturnValue();
}
@Override
public boolean moveToFirst(T key) {
int index = key.ordinal();
@@ -312,6 +334,42 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
return values[lastIndex];
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[firstIndex], values[firstIndex]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() {
if(size == 0) throw new NoSuchElementException();
return new BasicEntryKV_BRACES(keys[lastIndex], values[lastIndex]);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() {
if(size == 0) throw new NoSuchElementException();
int pos = firstIndex;
firstIndex = (int)links[pos];
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
BasicEntry KEY_VALUE_GENERIC_TYPE result = new BasicEntryKV_BRACES(keys[pos], values[pos]);
size--;
values[result.ENTRY_KEY().ordinal()] = EMPTY_VALUE;
return result;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() {
if(size == 0) throw new NoSuchElementException();
int pos = lastIndex;
firstIndex = (int)links[pos];
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
BasicEntry KEY_VALUE_GENERIC_TYPE result = new BasicEntryKV_BRACES(keys[pos], values[pos]);
size--;
values[result.ENTRY_KEY().ordinal()] = EMPTY_VALUE;
return result;
}
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet();
@@ -325,9 +383,9 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values();
return valuesC;
return (VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE)valuesC;
}
@Override
@@ -415,6 +473,10 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
}
private class MapEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> implements ORDERED_MAP.FastOrderedSet KEY_VALUE_GENERIC_TYPE {
@Override
public void addFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
@@ -431,24 +493,24 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getFirst() {
return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE getLast() {
return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeFirst() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY();
return entry;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() {
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeLast() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY();
return entry;
@@ -456,7 +518,12 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
return new EntryIterator(true);
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() {
return new EntryIterator(false);
}
@Override
@@ -466,7 +533,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator();
return new FastEntryIterator(true);
}
@Override
@@ -574,7 +641,10 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
public boolean add(T o) {
throw new UnsupportedOperationException();
}
@Override
public void addFirst(T o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(T o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(T o) { throw new UnsupportedOperationException(); }
@@ -593,7 +663,12 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new KeyIterator();
return new KeyIterator(true);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new KeyIterator(false);
}
@Override
@@ -614,22 +689,22 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
}
@Override
public T FIRST_KEY() {
public T GET_FIRST_KEY() {
return FIRST_ENTRY_KEY();
}
@Override
public T POLL_FIRST_KEY() {
public T REMOVE_FIRST_KEY() {
return POLL_FIRST_ENTRY_KEY();
}
@Override
public T LAST_KEY() {
public T GET_LAST_KEY() {
return LAST_ENTRY_KEY();
}
@Override
public T POLL_LAST_KEY() {
public T REMOVE_LAST_KEY() {
return POLL_LAST_ENTRY_KEY();
}
@@ -656,41 +731,50 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
#endif
}
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE implements VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE {
#if VALUE_OBJECT
@Override
@Deprecated
public boolean contains(Object e) {
return containsValue(e);
}
public boolean contains(Object e) { return containsValue(e); }
#else
@Override
public boolean contains(VALUE_TYPE e) {
return containsValue(e);
}
public boolean contains(VALUE_TYPE e) { return containsValue(e); }
#endif
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
@Override
public int size() {
return LINKED_ENUM_MAP.this.size();
}
public int size() { return LINKED_ENUM_MAP.this.size(); }
@Override
public void clear() {
LINKED_ENUM_MAP.this.clear();
public void clear() { LINKED_ENUM_MAP.this.clear(); }
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE reversed() { return new VALUE_ABSTRACT_COLLECTION.VALUE_REVERSED_ORDERED_COLLECTIONVALUE_BRACES(this, this::reverseIterator); }
private VALUE_ITERATOR VALUE_GENERIC_TYPE reverseIterator() {
return new ValueIterator(false);
}
@Override
public void addFirst(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void addLast(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE VALUE_GET_FIRST_KEY() { return FIRST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_FIRST_KEY() {
VALUE_TYPE result = FIRST_ENTRY_VALUE();
POLL_FIRST_ENTRY_KEY();
return result;
}
@Override
public VALUE_TYPE VALUE_GET_LAST_KEY() { return LAST_ENTRY_VALUE(); }
@Override
public VALUE_TYPE VALUE_REMOVE_LAST_KEY() {
VALUE_TYPE result = LAST_ENTRY_VALUE();
POLL_LAST_ENTRY_KEY();
return result;
}
#if VALUE_OBJECT
@Override
public void forEach(Consumer VALUE_SUPER_GENERIC_TYPE action) {
@@ -715,7 +799,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry();
public FastEntryIterator() {}
public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(T from) {
super(from);
}
@@ -742,7 +826,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry;
public EntryIterator() {}
public EntryIterator(boolean start) { super(start); }
public EntryIterator(T from) {
super(from);
}
@@ -772,7 +856,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {}
public KeyIterator(boolean start) { super(start); }
public KeyIterator(T from) {
super(from);
}
@@ -794,7 +878,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
}
private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {}
public ValueIterator(boolean start) { super(start); }
@Override
public VALUE_TYPE VALUE_PREVIOUS() {
@@ -815,16 +899,20 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
}
private class MapIterator {
boolean forward;
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
MapIterator() {
next = firstIndex;
MapIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
}
MapIterator(T from) {
this.forward = true;
previous = from.ordinal() - 1;
index = from.ordinal();
next = from.ordinal();
@@ -832,11 +920,11 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
}
public boolean hasNext() {
return next != -1;
return (forward ? next : previous) != -1;
}
public boolean hasPrevious() {
return previous != -1;
return (forward ? previous : next) != -1;
}
public int nextIndex() {
@@ -871,20 +959,30 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
current = previous;
previous = (int)(links[current] >> 32);
next = current;
if(forward) moveBackwards();
else moveForwards();
if(index >= 0) index--;
return current;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
if(forward) moveForwards();
else moveBackwards();
if(index >= 0) index++;
return current;
}
private void moveBackwards() {
current = previous;
previous = (int)(links[current] >> 32);
next = current;
}
private void moveForwards() {
current = next;
next = (int)(links[current]);
previous = current;
if(index >= 0) index++;
return current;
}
private void ensureIndexKnown() {
@@ -6,15 +6,18 @@ import java.util.Map;
import java.util.Comparator;
#endif
import java.util.Objects;
import java.util.Optional;
import java.util.NoSuchElementException;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
@@ -37,9 +40,12 @@ import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if!VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
@@ -73,6 +79,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
#if !TYPE_OBJECT && !VALUE_OBJECT
@@ -1323,7 +1330,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1335,15 +1342,15 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
state = operator.APPLY_KEY_VALUE(state, entry.key);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
if(filter.test(entry.key)) return entry.key;
return EMPTY_KEY_VALUE;
if(filter.test(entry.key)) return OPTIONAL.GET_OPTIONAL(entry.key);
return OPTIONAL.empty();
}
@Override
@@ -2026,7 +2033,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -2038,19 +2045,19 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
subEntry.set(entry.key, entry.value);
if(filter.test(subEntry)) return subEntry;
if(filter.test(subEntry)) return Optional.ofNullable(subEntry);
}
return null;
return Optional.empty();
}
@Override
@@ -2165,7 +2172,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -2177,15 +2184,15 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
state = operator.APPLY_VALUE(state, entry.value);
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
if(filter.test(entry.value)) return entry.value;
return EMPTY_VALUE;
if(filter.test(entry.value)) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(entry.value);
return VALUE_OPTIONAL.empty();
}
@Override
@@ -2521,7 +2528,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -2533,15 +2540,15 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
state = operator.APPLY_VALUE(state, entry.value);
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
if(filter.test(entry.value)) return entry.value;
return EMPTY_VALUE;
if(filter.test(entry.value)) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(entry.value);
return VALUE_OPTIONAL.empty();
}
@Override
@@ -2687,7 +2694,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -2699,19 +2706,19 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
subEntry.set(entry.key, entry.value);
if(filter.test(subEntry)) return subEntry;
if(filter.test(subEntry)) return Optional.ofNullable(subEntry);
}
return null;
return Optional.empty();
}
@Override
@@ -6,15 +6,18 @@ import java.util.Map;
import java.util.Comparator;
#endif
import java.util.Objects;
import java.util.Optional;
import java.util.NoSuchElementException;
import java.util.function.Consumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -36,9 +39,12 @@ import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if!VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
@@ -72,6 +78,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif
#endif
#if !TYPE_OBJECT && !VALUE_OBJECT
@@ -1379,7 +1386,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
#endif
@Override
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true;
@@ -1391,15 +1398,15 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
state = operator.APPLY_KEY_VALUE(state, entry.key);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
if(filter.test(entry.key)) return entry.key;
return EMPTY_KEY_VALUE;
if(filter.test(entry.key)) return OPTIONAL.GET_OPTIONAL(entry.key);
return OPTIONAL.empty();
}
@Override
@@ -2092,7 +2099,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -2104,19 +2111,19 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
subEntry.set(entry.key, entry.value);
if(filter.test(subEntry)) return subEntry;
if(filter.test(subEntry)) return Optional.ofNullable(subEntry);
}
return null;
return Optional.empty();
}
@Override
@@ -2231,7 +2238,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -2243,15 +2250,15 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
state = operator.APPLY_VALUE(state, entry.value);
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
if(filter.test(entry.value)) return entry.value;
return EMPTY_VALUE;
if(filter.test(entry.value)) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(entry.value);
return VALUE_OPTIONAL.empty();
}
@Override
@@ -2587,7 +2594,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
#endif
@Override
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -2599,15 +2606,15 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
state = operator.APPLY_VALUE(state, entry.value);
}
return state;
return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
}
@Override
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
public VALUE_OPTIONAL VALUE_GENERIC_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
if(filter.test(entry.value)) return entry.value;
return EMPTY_VALUE;
if(filter.test(entry.value)) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(entry.value);
return VALUE_OPTIONAL.empty();
}
@Override
@@ -2753,7 +2760,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true;
@@ -2765,19 +2772,19 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
}
return state;
return empty ? Optional.empty() : Optional.ofNullable(state);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
public Optional<MAP.Entry KEY_VALUE_GENERIC_TYPE> findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return null;
if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
subEntry.set(entry.key, entry.value);
if(filter.test(subEntry)) return subEntry;
if(filter.test(subEntry)) return Optional.ofNullable(subEntry);
}
return null;
return Optional.empty();
}
@Override
@@ -154,7 +154,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
* @return the last present value or default return value.
*/
public default CLASS_VALUE_TYPE put(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) {
return put(entry.getKey(), entry.getValue());
return put(OBJ_TO_KEY(entry.getKey()), OBJ_TO_VALUE(entry.getValue()));
}
#endif
@@ -1,8 +1,15 @@
package speiger.src.collections.PACKAGE.maps.interfaces;
#if JAVA_VERSION>=21
import java.util.Map;
import java.util.SequencedMap;
#endif
#if MAPS_FEATURE
import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
#endif
@@ -17,7 +24,11 @@ import speiger.src.collections.objects.sets.ObjectOrderedSet;
* @Type(T)
* @ValueType(V)
*/
#if JAVA_VERSION>=21
public interface ORDERED_MAP KEY_VALUE_GENERIC_TYPE extends MAP KEY_VALUE_GENERIC_TYPE, SequencedMap<CLASS_TYPE, CLASS_VALUE_TYPE>
#else
public interface ORDERED_MAP KEY_VALUE_GENERIC_TYPE extends MAP KEY_VALUE_GENERIC_TYPE
#endif
{
/**
* A customized put method that allows you to insert into the first index.
@@ -37,6 +48,26 @@ public interface ORDERED_MAP KEY_VALUE_GENERIC_TYPE extends MAP KEY_VALUE_GENERI
*/
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value);
/**
* A alternative to putAndMoveToFirst.
* This method simply puts an entry at the first spot of the Map but only if the entry is missing.
* @param key the key that should be inserted
* @param value the value that should be inserted
* @return the previous present or default return value
* @see java.util.Map#put(Object, Object)
*/
public VALUE_TYPE putFirst(KEY_TYPE key, VALUE_TYPE value);
/**
* A alternative to putAndMoveToLast.
* This method simply puts an entry at the last spot of the Map but only if the entry is missing.
* @param key the key that should be inserted
* @param value the value that should be inserted
* @return the previous present or default return value
* @see java.util.Map#put(Object, Object)
*/
public VALUE_TYPE putLast(KEY_TYPE key, VALUE_TYPE value);
/**
* A specific move method to move a given key/value to the first index.
* @param key that should be moved to the first index
@@ -97,13 +128,34 @@ public interface ORDERED_MAP KEY_VALUE_GENERIC_TYPE extends MAP KEY_VALUE_GENERI
*/
public VALUE_TYPE LAST_ENTRY_VALUE();
@Java21
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry();
@Java21
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry();
@Java21
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry();
@Java21
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry();
@Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy();
@Override
public ORDERED_SET KEY_GENERIC_TYPE keySet();
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values();
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET();
@Java21
public default ORDERED_MAP KEY_VALUE_GENERIC_TYPE reversed() { return new ABSTRACT_MAP.REVERSED_ORDERED_MAPKV_BRACES(this); }
#if JAVA_VERSION>=21
@Override
default ORDERED_SET KEY_GENERIC_TYPE sequencedKeySet() { return keySet(); }
@Override
default VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE sequencedValues() { return values(); }
@Override
default ObjectOrderedSet<Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>> sequencedEntrySet() { return (ObjectOrderedSet<Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>>)(Object)ENTRY_SET(); }
#endif
#if MAPS_FEATURE
/**
* Creates a Wrapped SortedMap that is Synchronized
@@ -130,6 +182,22 @@ public interface ORDERED_MAP KEY_VALUE_GENERIC_TYPE extends MAP KEY_VALUE_GENERI
@Override
public default ORDERED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); }
#endif
#if JAVA_VERSION>=21
#if !SAME_TYPE || !TYPE_OBJECT
@Override
@Deprecated
public default CLASS_VALUE_TYPE putFirst(CLASS_TYPE k, CLASS_VALUE_TYPE v) {
return putFirst(OBJ_TO_KEY(k), OBJ_TO_VALUE(v));
}
@Override
@Deprecated
public default CLASS_VALUE_TYPE putLast(CLASS_TYPE k, CLASS_VALUE_TYPE v) {
return putLast(OBJ_TO_KEY(k), OBJ_TO_VALUE(v));
}
#endif
#endif
/**
* Fast Ordered Entry Set that allows for a faster Entry Iterator by recycling the Entry Object and just exchanging 1 internal value
@@ -7,12 +7,26 @@ import java.util.function.Consumer;
import java.util.function.BiFunction;
#endif
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#endif
import java.util.NoSuchElementException;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -99,6 +113,47 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
this(MIN_CAPACITY);
}
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a ArrayFIFOQueue
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, ARRAY_FIFO_QUEUE<T>, ARRAY_FIFO_QUEUE<T>> toQueue() {
return Collector.of(ARRAY_FIFO_QUEUE::new, ARRAY_FIFO_QUEUE::enqueue, ARRAY_FIFO_QUEUE::merge);
}
/**
* Collects a Stream to a ArrayFIFOQueue
* @Type(T)
* @return a queue with the contents of the Stream
*/
public static <T> ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE toQueue(Stream<T> stream) {
return stream.collect(ARRAY_FIFO_QUEUE::new, ARRAY_FIFO_QUEUE::enqueue, ARRAY_FIFO_QUEUE::merge);
}
private ARRAY_FIFO_QUEUE<T> merge(ARRAY_FIFO_QUEUE<T> a) {
enqueueAll(a.toArray((T[])new Object[a.size()]));
return this;
}
#else
/**
* Collects a Stream to a ArrayFIFOQueue
* @return a queue with the contents of the Stream
*/
public static ARRAY_FIFO_QUEUE toQueue(JAVA_STREAM stream) {
return stream.collect(ARRAY_FIFO_QUEUE::new, ARRAY_FIFO_QUEUE::enqueue, ARRAY_FIFO_QUEUE::merge);
}
private ARRAY_FIFO_QUEUE merge(ARRAY_FIFO_QUEUE a) {
enqueueAll(a.TO_ARRAY());
return this;
}
#endif
#endif
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new Iter();
@@ -318,17 +373,17 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length;
if(filter.test(array[index])) {
KEY_TYPE data = array[index];
removeIndex(index);
return data;
return OPTIONAL.GET_OPTIONAL(data);
}
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
#if !TYPE_OBJECT
@@ -355,7 +410,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -367,7 +422,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
}
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
@@ -8,12 +8,26 @@ import java.util.function.Consumer;
import java.util.function.BiFunction;
#endif
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -190,7 +204,47 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
queue.size = size;
return queue;
}
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a ArrayPriorityQueue
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, ARRAY_PRIORITY_QUEUE<T>, ARRAY_PRIORITY_QUEUE<T>> toQueue() {
return Collector.of(ARRAY_PRIORITY_QUEUE::new, ARRAY_PRIORITY_QUEUE::enqueue, ARRAY_PRIORITY_QUEUE::merge);
}
/**
* Collects a Stream to a ArrayPriorityQueue
* @Type(T)
* @return a queue with the contents of the Stream
*/
public static <T> ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE toQueue(Stream<T> stream) {
return stream.collect(ARRAY_PRIORITY_QUEUE::new, ARRAY_PRIORITY_QUEUE::enqueue, ARRAY_PRIORITY_QUEUE::merge);
}
private ARRAY_PRIORITY_QUEUE<T> merge(ARRAY_PRIORITY_QUEUE<T> a) {
enqueueAll(a.toArray((T[])new Object[a.size()]));
return this;
}
#else
/**
* Collects a Stream to a ArrayPriorityQueue
* @return a queue with the contents of the Stream
*/
public static ARRAY_PRIORITY_QUEUE toQueue(JAVA_STREAM stream) {
return stream.collect(ARRAY_PRIORITY_QUEUE::new, ARRAY_PRIORITY_QUEUE::enqueue, ARRAY_PRIORITY_QUEUE::merge);
}
private ARRAY_PRIORITY_QUEUE merge(ARRAY_PRIORITY_QUEUE a) {
enqueueAll(a.TO_ARRAY());
return this;
}
#endif
#endif
@Override
public void enqueue(KEY_TYPE e) {
if(size == array.length) array = Arrays.copyOf(array, (int)Math.max(Math.min((long)array.length + (long)(array.length >> 1), (long)SanityChecks.MAX_ARRAY_SIZE), size+1));
@@ -346,7 +400,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -358,20 +412,20 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
}
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) {
KEY_TYPE data = array[i];
removeIndex(i);
return data;
return OPTIONAL.GET_OPTIONAL(data);
}
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -8,12 +8,26 @@ import java.util.function.Consumer;
import java.util.function.BiFunction;
#endif
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -193,6 +207,47 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
return queue;
}
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a ArrayFIFOQueue
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, HEAP_PRIORITY_QUEUE<T>, HEAP_PRIORITY_QUEUE<T>> toQueue() {
return Collector.of(HEAP_PRIORITY_QUEUE::new, HEAP_PRIORITY_QUEUE::enqueue, HEAP_PRIORITY_QUEUE::merge);
}
/**
* Collects a Stream to a ArrayFIFOQueue
* @Type(T)
* @return a queue with the contents of the Stream
*/
public static <T> HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE toQueue(Stream<T> stream) {
return stream.collect(HEAP_PRIORITY_QUEUE::new, HEAP_PRIORITY_QUEUE::enqueue, HEAP_PRIORITY_QUEUE::merge);
}
private HEAP_PRIORITY_QUEUE<T> merge(HEAP_PRIORITY_QUEUE<T> a) {
enqueueAll(a.toArray((T[])new Object[a.size()]));
return this;
}
#else
/**
* Collects a Stream to a ArrayFIFOQueue
* @return a queue with the contents of the Stream
*/
public static HEAP_PRIORITY_QUEUE toQueue(JAVA_STREAM stream) {
return stream.collect(HEAP_PRIORITY_QUEUE::new, HEAP_PRIORITY_QUEUE::enqueue, HEAP_PRIORITY_QUEUE::merge);
}
private HEAP_PRIORITY_QUEUE merge(HEAP_PRIORITY_QUEUE a) {
enqueueAll(a.TO_ARRAY());
return this;
}
#endif
#endif
@Override
public int size() {
return size;
@@ -326,7 +381,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -338,20 +393,20 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
}
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) {
KEY_TYPE data = array[i];
removeIndex(i);
return data;
return OPTIONAL.GET_OPTIONAL(data);
}
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -10,6 +10,15 @@ import java.util.function.BiFunction;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
@@ -19,6 +28,9 @@ import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
@@ -208,6 +220,42 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
while(iterator.hasNext()) add(iterator.NEXT());
}
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a AVLTreeSet
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, AVL_TREE_SET<T>, AVL_TREE_SET<T>> toSet() {
return Collector.of(AVL_TREE_SET::new, AVL_TREE_SET::add, AVL_TREE_SET::merge);
}
/**
* Collects a Stream to a AVLTreeSet
* @Type(T)
* @return a set with the contents of the Stream
*/
public static <T> AVL_TREE_SET KEY_GENERIC_TYPE toSet(Stream<T> stream) {
return stream.collect(AVL_TREE_SET::new, AVL_TREE_SET::add, AVL_TREE_SET::merge);
}
private AVL_TREE_SET<T> merge(AVL_TREE_SET<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a AVLTreeSet
* @return a set with the contents of the Stream
*/
public static AVL_TREE_SET toSet(JAVA_STREAM stream) {
return stream.collect(AVL_TREE_SET::new, AVL_TREE_SET::add, AVL_TREE_SET::addAll);
}
#endif
#endif
#if !TYPE_OBJECT
@Override
public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; }
@@ -405,12 +453,12 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.test(entry.key)) return entry.key;
if(filter.test(entry.key)) return OPTIONAL.GET_OPTIONAL(entry.key);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
#if !TYPE_OBJECT
@@ -437,7 +485,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -449,7 +497,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
state = operator.APPLY_VALUE(state, entry.key);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
@@ -1314,7 +1362,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1326,16 +1374,16 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
state = operator.APPLY_VALUE(state, entry.key);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.test(entry.key)) return entry.key;
if(filter.test(entry.key)) return OPTIONAL.GET_OPTIONAL(entry.key);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -6,6 +6,7 @@ import java.util.Objects;
import java.util.Set;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
/**
@@ -47,4 +48,105 @@ public abstract class ABSTRACT_SET KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return false;
}
}
#if ORDERED_SET_FEATURE
public static class REVERSED_ORDERED_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements ORDERED_SET KEY_GENERIC_TYPE {
protected ORDERED_SET KEY_GENERIC_TYPE set;
public REVERSED_ORDERED_SET(ORDERED_SET KEY_GENERIC_TYPE set) {
this.set = set;
}
@Override
public REVERSED_ORDERED_SET KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
return set.iterator(fromElement);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
return set.reverseIterator();
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return set.iterator();
}
@Override
public void addFirst(KEY_TYPE o) {
set.addLast(o);
}
@Override
public void addLast(KEY_TYPE o) {
set.addFirst(o);
}
@Override
#if !TYPE_OBJECT
public boolean remove(KEY_TYPE o) {
#else
public boolean remove(Object o) {
#endif
return set.remove(o);
}
@Override
public boolean add(KEY_TYPE o) {
return set.add(o);
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) {
return set.addAndMoveToLast(o);
}
@Override
public boolean addAndMoveToLast(KEY_TYPE o) {
return set.addAndMoveToFirst(o);
}
@Override
public boolean moveToFirst(KEY_TYPE o) {
return set.moveToLast(o);
}
@Override
public boolean moveToLast(KEY_TYPE o) {
return set.moveToFirst(o);
}
@Override
public KEY_TYPE GET_FIRST_KEY() {
return set.GET_LAST_KEY();
}
@Override
public KEY_TYPE REMOVE_FIRST_KEY() {
return set.REMOVE_LAST_KEY();
}
@Override
public KEY_TYPE GET_LAST_KEY() {
return set.GET_FIRST_KEY();
}
@Override
public KEY_TYPE REMOVE_LAST_KEY() {
return set.REMOVE_FIRST_KEY();
}
@Override
public ORDERED_SET KEY_GENERIC_TYPE reversed() {
return set;
}
@Override
public int size() {
return set.size();
}
}
#endif
}
@@ -8,6 +8,15 @@ import java.util.function.BiFunction;
#endif
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
import java.util.Set;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
@@ -18,7 +27,9 @@ import java.util.function.JAVA_PREDICATE;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
@@ -69,7 +80,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
* @param array the array that should be used for set.
*/
public ARRAY_SET(KEY_TYPE[] array) {
this(array, array.length);
this(array, 0, array.length);
}
/**
@@ -83,6 +94,18 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
addAll(array, length);
}
/**
* Constructur using initial Array
* @param array the array that should be used for set.
* @param offset the starting offset of where the array should be copied from
* @param length the amount of elements present within the array
* @throws NegativeArraySizeException if the length is negative
*/
public ARRAY_SET(KEY_TYPE[] array, int offset, int length) {
this(length);
addAll(array, offset, length);
}
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param c the elements that should be added to the set.
@@ -126,6 +149,42 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
for(ITERATOR KEY_GENERIC_TYPE iter = s.iterator();iter.hasNext();data[size++] = iter.NEXT());
}
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a ArraySet
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, ARRAY_SET<T>, ARRAY_SET<T>> toList() {
return Collector.of(ARRAY_SET::new, ARRAY_SET::add, ARRAY_SET::merge);
}
/**
* Collects a Stream to a ArraySet
* @Type(T)
* @return a set with the contents of the Stream
*/
public static <T> ARRAY_SET KEY_GENERIC_TYPE toList(Stream<T> stream) {
return stream.collect(ARRAY_SET::new, ARRAY_SET::add, ARRAY_SET::merge);
}
private ARRAY_SET<T> merge(ARRAY_SET<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a ArraySet
* @return a set with the contents of the Stream
*/
public static ARRAY_SET toList(JAVA_STREAM stream) {
return stream.collect(ARRAY_SET::new, ARRAY_SET::add, ARRAY_SET::addAll);
}
#endif
#endif
@Override
public boolean add(KEY_TYPE o) {
int index = findIndex(o);
@@ -148,6 +207,25 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
}
#endif
@Override
public void addFirst(KEY_TYPE o) {
int index = findIndex(o);
if(index == -1) {
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
System.arraycopy(data, 0, data, 1, size++);
data[0] = o;
}
}
@Override
public void addLast(KEY_TYPE o) {
int index = findIndex(o);
if(index == -1) {
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
data[size++] = o;
}
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) {
int index = findIndex(o);
@@ -219,13 +297,13 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
#endif
@Override
public KEY_TYPE FIRST_KEY() {
public KEY_TYPE GET_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
return data[0];
}
@Override
public KEY_TYPE LAST_KEY() {
public KEY_TYPE GET_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
return data[size - 1];
}
@@ -354,7 +432,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
#endif
@Override
public KEY_TYPE POLL_FIRST_KEY() {
public KEY_TYPE REMOVE_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
KEY_TYPE result = data[0];
System.arraycopy(data, 1, data, 0, --size);
@@ -365,7 +443,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
public KEY_TYPE REMOVE_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
size--;
#if TYPE_OBJECT
@@ -438,12 +516,12 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(data[i])) return data[i];
if(filter.test(data[i])) return OPTIONAL.GET_OPTIONAL(data[i]);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
#if !TYPE_OBJECT
@@ -470,7 +548,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -482,7 +560,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
}
state = operator.APPLY_VALUE(state, data[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
@@ -511,13 +589,18 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator(0);
return new SetIterator(true, 0);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new SetIterator(false, size);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
int index = findIndex(fromElement);
if(index != -1) return new SetIterator(index);
if(index != -1) return new SetIterator(true, index);
throw new NoSuchElementException();
}
@@ -570,45 +653,57 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
}
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int index;
int lastReturned = -1;
public SetIterator(int index) {
public SetIterator(boolean forward, int index) {
this.forward = forward;
this.index = index;
}
@Override
public boolean hasNext() {
return index < size();
return forward ? index < size() : index > 0;
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
lastReturned = index;
return data[index++];
if(forward) {
lastReturned = index;
return data[index++];
}
index--;
return data[(lastReturned = index)];
}
@Override
public boolean hasPrevious() {
return index > 0;
return forward ? index > 0 : index < size();
}
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
--index;
return data[(lastReturned = index)];
if(forward) {
index--;
return data[(lastReturned = index)];
}
lastReturned = index;
return data[index++];
}
@Override
public int nextIndex() {
return index;
if(forward) return index;
return size - index;
}
@Override
public int previousIndex() {
return index-1;
if(forward) return index-1;
return (size - index)-1;
}
@Override
@@ -637,15 +732,23 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
return forward ? moveForward(amount) : moveBackwards(amount);
}
@Override
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
return forward ? moveBackwards(amount) : moveForward(amount);
}
private int moveForward(int amount) {
int steps = Math.min(amount, size() - index);
index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps;
}
@Override
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
private int moveBackwards(int amount) {
int steps = Math.min(amount, index);
index -= steps;
if(steps > 0) lastReturned = Math.min(index, size()-1);
@@ -9,6 +9,9 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
@@ -19,6 +22,9 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
@@ -258,6 +264,10 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -285,22 +295,22 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
}
@Override
public KEY_TYPE FIRST_KEY() {
public KEY_TYPE GET_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[firstIndex];
}
@Override
public KEY_TYPE POLL_FIRST_KEY() { throw new UnsupportedOperationException(); }
public KEY_TYPE REMOVE_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE LAST_KEY() {
public KEY_TYPE GET_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[lastIndex];
}
@Override
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); }
public KEY_TYPE REMOVE_LAST_KEY() { throw new UnsupportedOperationException(); }
@Override
public boolean remove(Object o) { throw new UnsupportedOperationException(); }
@@ -414,7 +424,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -427,18 +437,18 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
else state = operator.APPLY_VALUE(state, keys[index]);
index = (int)links[index];
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int index = firstIndex;
while(index != -1) {
if(filter.test(keys[index])) return keys[index];
if(filter.test(keys[index])) return OPTIONAL.GET_OPTIONAL(keys[index]);
index = (int)links[index];
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -455,7 +465,12 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator();
return new SetIterator(true);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new SetIterator(false);
}
@Override
@@ -521,16 +536,20 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
}
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
int index = -1;
SetIterator() {
next = firstIndex;
SetIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
}
SetIterator(KEY_TYPE from) {
this.forward = true;
if(KEY_EQUALS_NULL(from)) {
if(containsNull) {
next = (int) links[nullIndex];
@@ -559,48 +578,60 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override
public int skip(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
int result = forward ? moveForward(amount) : moveBackwards(amount);
if(index >= 0) index+=result;
return result;
}
@Override
public int back(int amount) {
int result = forward ? moveBackwards(amount) : moveForward(amount);
if(index >= 0) index-=result;
return result;
}
private int moveForward(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
return result;
}
private int moveBackwards(int amount) {
int result = 0;
while(previous != -1 && result != amount) {
current = next = previous;
previous = (int)(links[current] >> 32);
result++;
}
if(index >= 0) index-=result;
return result;
}
@Override
public boolean hasNext() {
return next != -1;
return (forward ? next : previous) != -1;
}
@Override
public boolean hasPrevious() {
return previous != -1;
return (forward ? previous : next) != -1;
}
@Override
public int nextIndex() {
ensureIndexKnown();
return index;
if(forward) return index;
return size - index;
}
@Override
public int previousIndex() {
ensureIndexKnown();
return index - 1;
if(forward) return index-1;
return (size - index)-1;
}
@Override
@@ -609,8 +640,8 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous;
previous = (int)(links[current] >> 32);
if(forward) moveBackwards();
else moveForwards();
if(index >= 0) index--;
return keys[current];
}
@@ -618,12 +649,22 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
current = previous = next;
next = (int)(links[current]);
if(forward) moveForwards();
else moveBackwards();
if(index >= 0) index++;
return keys[current];
}
private void moveBackwards() {
current = next = previous;
previous = (int)(links[current] >> 32);
}
private void moveForwards() {
current = previous = next;
next = (int)(links[current]);
}
private void ensureIndexKnown() {
if(index == -1) {
if(previous == -1) {
@@ -9,6 +9,15 @@ import java.util.Objects;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
#if JDK_TYPE
import java.util.OPTIONAL;
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
@@ -18,6 +27,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
@@ -235,6 +247,82 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
}
#endif
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a LinkedCustomHashSet
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, LINKED_CUSTOM_HASH_SET<T>, LINKED_CUSTOM_HASH_SET<T>> toLinkedSet(STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
return Collector.of(() -> new LINKED_CUSTOM_HASH_SET<>(strategy), LINKED_CUSTOM_HASH_SET::add, LINKED_CUSTOM_HASH_SET::merge);
}
/**
* Collects a Stream to a LinkedCustomHashSet
* @Type(T)
* @return a set with the contents of the Stream
*/
public static <T> LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE toLinkedSet(Stream<T> stream, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
return stream.collect(() -> new LINKED_CUSTOM_HASH_SET<>(strategy), LINKED_CUSTOM_HASH_SET::add, LINKED_CUSTOM_HASH_SET::merge);
}
private LINKED_CUSTOM_HASH_SET<T> merge(LINKED_CUSTOM_HASH_SET<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a LinkedCustomHashSet
* @return a set with the contents of the Stream
*/
public static LINKED_CUSTOM_HASH_SET toList(JAVA_STREAM stream, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
return stream.collect(() -> new LINKED_CUSTOM_HASH_SET(strategy), LINKED_CUSTOM_HASH_SET::add, LINKED_CUSTOM_HASH_SET::addAll);
}
#endif
#endif
@Override
public void addFirst(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) return;
containsNull = true;
onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex);
}
else {
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], o)) return;
pos = ++pos & mask;
}
keys[pos] = o;
onNodeAdded(pos);
moveToFirstIndex(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
}
@Override
public void addLast(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) return;
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], o)) return;
pos = ++pos & mask;
}
keys[pos] = o;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
@@ -291,7 +379,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override
public boolean moveToFirst(KEY_TYPE o) {
if(isEmpty() || strategy.equals(FIRST_KEY(), o)) return false;
if(isEmpty() || strategy.equals(GET_FIRST_KEY(), o)) return false;
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
@@ -313,7 +401,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override
public boolean moveToLast(KEY_TYPE o) {
if(isEmpty() || strategy.equals(LAST_KEY(), o)) return false;
if(isEmpty() || strategy.equals(GET_LAST_KEY(), o)) return false;
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToLastIndex(nullIndex);
@@ -370,13 +458,13 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
}
@Override
public KEY_TYPE FIRST_KEY() {
public KEY_TYPE GET_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[firstIndex];
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
public KEY_TYPE REMOVE_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = firstIndex;
onNodeRemoved(pos);
@@ -392,13 +480,13 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
}
@Override
public KEY_TYPE LAST_KEY() {
public KEY_TYPE GET_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[lastIndex];
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
public KEY_TYPE REMOVE_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = lastIndex;
onNodeRemoved(pos);
@@ -656,7 +744,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -669,18 +757,18 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
else state = operator.APPLY_VALUE(state, keys[index]);
index = (int)links[index];
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int index = firstIndex;
while(index != -1) {
if(filter.test(keys[index])) return keys[index];
if(filter.test(keys[index])) return OPTIONAL.GET_OPTIONAL(keys[index]);
index = (int)links[index];
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -697,7 +785,12 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator();
return new SetIterator(true);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new SetIterator(false);
}
@Override
@@ -722,16 +815,20 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
}
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
int index = -1;
SetIterator() {
next = firstIndex;
SetIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
}
SetIterator(KEY_TYPE from) {
this.forward = true;
if(strategy.equals(from, EMPTY_KEY_VALUE)) {
if(containsNull) {
next = (int) links[nullIndex];
@@ -760,48 +857,60 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override
public boolean hasNext() {
return next != -1;
return (forward ? next : previous) != -1;
}
@Override
public boolean hasPrevious() {
return previous != -1;
return (forward ? previous : next) != -1;
}
@Override
public int skip(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
int result = forward ? moveForward(amount) : moveBackwards(amount);
if(index >= 0) index+=result;
return result;
}
@Override
public int back(int amount) {
int result = forward ? moveBackwards(amount) : moveForward(amount);
if(index >= 0) index-=result;
return result;
}
private int moveForward(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
return result;
}
private int moveBackwards(int amount) {
int result = 0;
while(previous != -1 && result != amount) {
current = next = previous;
previous = (int)(links[current] >> 32);
result++;
}
if(index >= 0) index-=result;
return result;
}
@Override
public int nextIndex() {
ensureIndexKnown();
return index;
if(forward) return index;
return size - index;
}
@Override
public int previousIndex() {
ensureIndexKnown();
return index - 1;
if(forward) return index-1;
return (size - index)-1;
}
@Override
@@ -850,8 +959,8 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous;
previous = (int)(links[current] >> 32);
if(forward) moveBackwards();
else moveForwards();
if(index >= 0) index--;
return keys[current];
}
@@ -859,12 +968,22 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
current = previous = next;
next = (int)(links[current]);
if(forward) moveForwards();
else moveBackwards();
if(index >= 0) index++;
return keys[current];
}
private void moveBackwards() {
current = next = previous;
previous = (int)(links[current] >> 32);
}
private void moveForwards() {
current = previous = next;
next = (int)(links[current]);
}
private void ensureIndexKnown() {
if(index == -1) {
if(previous == -1) {
@@ -5,6 +5,15 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#if TYPE_OBJECT
import java.util.function.Consumer;
import java.util.function.BiFunction;
@@ -21,6 +30,9 @@ import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
@@ -206,6 +218,82 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
}
#endif
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a LinkedHashSet
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, LINKED_HASH_SET<T>, LINKED_HASH_SET<T>> toLinkedSet() {
return Collector.of(LINKED_HASH_SET::new, LINKED_HASH_SET::add, LINKED_HASH_SET::merge);
}
/**
* Collects a Stream to a LinkedHashSet
* @Type(T)
* @return a set with the contents of the Stream
*/
public static <T> LINKED_HASH_SET KEY_GENERIC_TYPE toLinkedSet(Stream<T> stream) {
return stream.collect(LINKED_HASH_SET::new, LINKED_HASH_SET::add, LINKED_HASH_SET::merge);
}
private LINKED_HASH_SET<T> merge(LINKED_HASH_SET<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a LinkedHashSet
* @return a set with the contents of the Stream
*/
public static LINKED_HASH_SET toLinkedSet(JAVA_STREAM stream) {
return stream.collect(LINKED_HASH_SET::new, LINKED_HASH_SET::add, LINKED_HASH_SET::addAll);
}
#endif
#endif
@Override
public void addFirst(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) {
if(containsNull) return;
containsNull = true;
onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], o)) return;
pos = ++pos & mask;
}
keys[pos] = o;
onNodeAdded(pos);
moveToFirstIndex(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
}
@Override
public void addLast(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) {
if(containsNull) return;
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], o)) return;
pos = ++pos & mask;
}
keys[pos] = o;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) {
@@ -262,7 +350,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override
public boolean moveToFirst(KEY_TYPE o) {
if(isEmpty() || KEY_EQUALS(FIRST_KEY(), o)) return false;
if(isEmpty() || KEY_EQUALS(GET_FIRST_KEY(), o)) return false;
if(KEY_EQUALS_NULL(o)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
@@ -284,7 +372,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override
public boolean moveToLast(KEY_TYPE o) {
if(isEmpty() || KEY_EQUALS(LAST_KEY(), o)) return false;
if(isEmpty() || KEY_EQUALS(GET_LAST_KEY(), o)) return false;
if(KEY_EQUALS_NULL(o)) {
if(containsNull) {
moveToLastIndex(nullIndex);
@@ -341,13 +429,13 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
}
@Override
public KEY_TYPE FIRST_KEY() {
public KEY_TYPE GET_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[firstIndex];
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
public KEY_TYPE REMOVE_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = firstIndex;
onNodeRemoved(pos);
@@ -363,13 +451,13 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
}
@Override
public KEY_TYPE LAST_KEY() {
public KEY_TYPE GET_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[lastIndex];
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
public KEY_TYPE REMOVE_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = lastIndex;
onNodeRemoved(pos);
@@ -511,7 +599,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -524,18 +612,18 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
else state = operator.APPLY_VALUE(state, keys[index]);
index = (int)links[index];
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int index = firstIndex;
while(index != -1) {
if(filter.test(keys[index])) return keys[index];
if(filter.test(keys[index])) return OPTIONAL.GET_OPTIONAL(keys[index]);
index = (int)links[index];
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -668,7 +756,12 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator();
return new SetIterator(true);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE reverseIterator() {
return new SetIterator(false);
}
@Override
@@ -693,16 +786,20 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
}
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
int index = -1;
SetIterator() {
next = firstIndex;
SetIterator(boolean start) {
this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
}
SetIterator(KEY_TYPE from) {
this.forward = true;
if(KEY_EQUALS_NULL(from)) {
if(containsNull) {
next = (int) links[nullIndex];
@@ -731,48 +828,60 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override
public int skip(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
int result = forward ? moveForward(amount) : moveBackwards(amount);
if(index >= 0) index+=result;
return result;
}
@Override
public int back(int amount) {
int result = forward ? moveBackwards(amount) : moveForward(amount);
if(index >= 0) index-=result;
return result;
}
private int moveForward(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
return result;
}
private int moveBackwards(int amount) {
int result = 0;
while(previous != -1 && result != amount) {
current = next = previous;
previous = (int)(links[current] >> 32);
result++;
}
if(index >= 0) index-=result;
return result;
}
@Override
public boolean hasNext() {
return next != -1;
return (forward ? next : previous) != -1;
}
@Override
public boolean hasPrevious() {
return previous != -1;
return (forward ? previous : next) != -1;
}
@Override
public int nextIndex() {
ensureIndexKnown();
return index;
if(forward) return index;
return size - index;
}
@Override
public int previousIndex() {
ensureIndexKnown();
return index - 1;
if(forward) return index-1;
return (size - index)-1;
}
@Override
@@ -821,8 +930,8 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous;
previous = (int)(links[current] >> 32);
if(forward) moveBackwards();
else moveForwards();
if(index >= 0) index--;
return keys[current];
}
@@ -830,12 +939,22 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
current = previous = next;
next = (int)(links[current]);
if(forward) moveForwards();
else moveBackwards();
if(index >= 0) index++;
return keys[current];
}
private void moveBackwards() {
current = next = previous;
previous = (int)(links[current] >> 32);
}
private void moveForwards() {
current = previous = next;
next = (int)(links[current]);
}
private void ensureIndexKnown() {
if(index == -1) {
if(previous == -1) {
@@ -6,6 +6,15 @@ import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#if TYPE_OBJECT
import java.util.function.Consumer;
import java.util.function.BiFunction;
@@ -16,6 +25,9 @@ import java.util.function.PREDICATE;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -251,6 +263,42 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
while(iterator.hasNext()) add(iterator.NEXT());
}
#endif
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a CustomHashSet
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, CUSTOM_HASH_SET<T>, CUSTOM_HASH_SET<T>> toSet(STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
return Collector.of(() -> new CUSTOM_HASH_SET<>(strategy), CUSTOM_HASH_SET::add, CUSTOM_HASH_SET::merge);
}
/**
* Collects a Stream to a CustomHashSet
* @Type(T)
* @return a set with the contents of the Stream
*/
public static <T> CUSTOM_HASH_SET KEY_GENERIC_TYPE toSet(Stream<T> stream, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
return stream.collect(() -> new CUSTOM_HASH_SET<>(strategy), CUSTOM_HASH_SET::add, CUSTOM_HASH_SET::merge);
}
private CUSTOM_HASH_SET<T> merge(CUSTOM_HASH_SET<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a CustomHashSet
* @return a set with the contents of the Stream
*/
public static CUSTOM_HASH_SET toSet(JAVA_STREAM stream, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
return stream.collect(() -> new CUSTOM_HASH_SET(strategy), CUSTOM_HASH_SET::add, CUSTOM_HASH_SET::addAll);
}
#endif
#endif
/**
* Helper getter function to get the current strategy
@@ -635,7 +683,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -652,18 +700,18 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
}
state = operator.APPLY_VALUE(state, keys[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE;
if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex];
if(size() <= 0) return OPTIONAL.empty();
if(containsNull && filter.test(keys[nullIndex])) return OPTIONAL.GET_OPTIONAL(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return keys[i];
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return OPTIONAL.GET_OPTIONAL(keys[i]);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -6,6 +6,15 @@ import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#if TYPE_OBJECT
import java.util.function.Consumer;
import java.util.function.BiFunction;
@@ -20,6 +29,9 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
@@ -218,6 +230,42 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
while(iterator.hasNext()) add(iterator.NEXT());
}
#endif
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a HashSet
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, HASH_SET<T>, HASH_SET<T>> toSet() {
return Collector.of(HASH_SET::new, HASH_SET::add, HASH_SET::merge);
}
/**
* Collects a Stream to a HashSet
* @Type(T)
* @return a set with the contents of the Stream
*/
public static <T> HASH_SET KEY_GENERIC_TYPE toSet(Stream<T> stream) {
return stream.collect(HASH_SET::new, HASH_SET::add, HASH_SET::merge);
}
private HASH_SET<T> merge(HASH_SET<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a HashSet
* @return a set with the contents of the Stream
*/
public static HASH_SET toSet(JAVA_STREAM stream) {
return stream.collect(HASH_SET::new, HASH_SET::add, HASH_SET::addAll);
}
#endif
#endif
@Override
public boolean add(KEY_TYPE o) {
@@ -498,7 +546,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -515,18 +563,18 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
}
state = operator.APPLY_VALUE(state, keys[i]);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE;
if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex];
if(size() <= 0) return OPTIONAL.empty();
if(containsNull && filter.test(keys[nullIndex])) return OPTIONAL.GET_OPTIONAL(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return keys[i];
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return OPTIONAL.GET_OPTIONAL(keys[i]);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1,10 +1,16 @@
package speiger.src.collections.PACKAGE.sets;
#if JAVA_VERSION>=21
import java.util.SequencedSet;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.ORDERED_COLLECTION;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET.REVERSED_ORDERED_SET;
#if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS;
#endif
@@ -17,7 +23,11 @@ import speiger.src.collections.PACKAGE.utils.SETS;
*
* @Type(T)
*/
public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
#if JAVA_VERSION>=21
public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, ORDERED_COLLECTION KEY_GENERIC_TYPE, SequencedSet<CLASS_TYPE>
#else
public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, ORDERED_COLLECTION KEY_GENERIC_TYPE
#endif
{
/**
* A customized add method that allows you to insert into the first index.
@@ -54,6 +64,7 @@ public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator();
public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator();
/**
* A type Specific Iterator starting from a given key
@@ -76,23 +87,76 @@ public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
* A method to get the first element in the set
* @return first element in the set
*/
public KEY_TYPE FIRST_KEY();
public KEY_TYPE GET_FIRST_KEY();
/**
* A method to get and remove the first element in the set
* @return first element in the set
*/
public KEY_TYPE POLL_FIRST_KEY();
public KEY_TYPE REMOVE_FIRST_KEY();
/**
* A method to get the last element in the set
* @return last element in the set
*/
public KEY_TYPE LAST_KEY();
public KEY_TYPE GET_LAST_KEY();
/**
* A method to get and remove the last element in the set
* @return last element in the set
*/
public KEY_TYPE POLL_LAST_KEY();
public KEY_TYPE REMOVE_LAST_KEY();
#if JAVA_VERSION>=21 && !TYPE_OBJECT
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default void addFirst(CLASS_TYPE e) { addAndMoveToFirst(OBJ_TO_KEY(e)); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default void addLast(CLASS_TYPE e) { addAndMoveToLast(OBJ_TO_KEY(e)); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default CLASS_TYPE getFirst() { return GET_FIRST_KEY(); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default CLASS_TYPE getLast() { return GET_LAST_KEY(); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default CLASS_TYPE removeFirst() { return REMOVE_FIRST_KEY(); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default CLASS_TYPE removeLast() { return REMOVE_LAST_KEY(); }
#endif
@Java21
public default ORDERED_SET KEY_GENERIC_TYPE reversed() { return new REVERSED_ORDERED_SETBRACES(this); }
#if SETS_FEATURE
/**
* Creates a Wrapped OrderedSet that is Synchronized
@@ -2,6 +2,15 @@ package speiger.src.collections.PACKAGE.sets;
import java.util.Collection;
import java.util.Collections;
#if JDK_TYPE
import java.util.OPTIONAL;
#if !TYPE_OBJECT
import java.util.stream.JAVA_STREAM;
#else
import java.util.stream.Stream;
import java.util.stream.Collector;
#endif
#endif
#if TYPE_OBJECT
import java.util.Comparator;
import java.util.function.Consumer;
@@ -19,6 +28,9 @@ import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
@@ -208,6 +220,42 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
while(iterator.hasNext()) add(iterator.NEXT());
}
#if JDK_TYPE && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
#if TYPE_OBJECT
/**
* Creates a Collector for a RBTreeSet
* @Type(T)
* @return a collector
*/
public static <T> Collector<T, RB_TREE_SET<T>, RB_TREE_SET<T>> toSet() {
return Collector.of(RB_TREE_SET::new, RB_TREE_SET::add, RB_TREE_SET::merge);
}
/**
* Collects a Stream to a RBTreeSet
* @Type(T)
* @return a set with the contents of the Stream
*/
public static <T> RB_TREE_SET KEY_GENERIC_TYPE toSet(Stream<T> stream) {
return stream.collect(RB_TREE_SET::new, RB_TREE_SET::add, RB_TREE_SET::merge);
}
private RB_TREE_SET<T> merge(RB_TREE_SET<T> a) {
addAll(a);
return this;
}
#else
/**
* Collects a Stream to a RBTreeSet
* @return a set with the contents of the Stream
*/
public static RB_TREE_SET toSet(JAVA_STREAM stream) {
return stream.collect(RB_TREE_SET::new, RB_TREE_SET::add, RB_TREE_SET::addAll);
}
#endif
#endif
#if !TYPE_OBJECT
@Override
public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; }
@@ -427,7 +475,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -439,16 +487,16 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
state = operator.APPLY_VALUE(state, entry.key);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.test(entry.key)) return entry.key;
if(filter.test(entry.key)) return OPTIONAL.GET_OPTIONAL(entry.key);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -1374,7 +1422,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
@@ -1386,16 +1434,16 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
}
state = operator.APPLY_VALUE(state, entry.key);
}
return state;
return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.test(entry.key)) return entry.key;
if(filter.test(entry.key)) return OPTIONAL.GET_OPTIONAL(entry.key);
}
return EMPTY_VALUE;
return OPTIONAL.empty();
}
@Override
@@ -17,6 +17,7 @@ import java.util.function.IntFunction;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.utils.SanityChecks;
import speiger.src.collections.utils.Swapper;
/**
* A Helper class for Arrays
@@ -337,6 +338,69 @@ public class ARRAYS
return array;
}
/**
* Simple Shuffle method for Arrays.
* With a Callback for indirect shuffling
* @param array the elements that should be shuffled
* @param swapper the callback on the swaps
* @ArrayType(T)
* @note This uses the SanityChecks#getRandom
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, Swapper swapper) {
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
}
/**
* Simple Shuffle method for Arrays.
* With a Callback for indirect shuffling
* @param array the elements that should be shuffled
* @param random the Random Number Generator that should be used for the shuffling
* @param swapper the callback on the swaps
* @ArrayType(T)
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, RANDOM random, Swapper swapper) {
return indirectShuffle(array, 0, array.length, random, swapper);
}
/**
* Simple Shuffle method for Arrays.
* With a Callback for indirect shuffling
* @param array the elements that should be shuffled
* @param length the length of the array
* @param random the Random Number Generator that should be used for the shuffling
* @param swapper the callback on the swaps
* @ArrayType(T)
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, int length, RANDOM random, Swapper swapper) {
return indirectShuffle(array, 0, length, random, swapper);
}
/**
* Simple Shuffle method for Arrays.
* With a Callback for indirect shuffling
* @param array the elements that should be shuffled
* @param offset the start array
* @param length the length of the array
* @param random the Random Number Generator that should be used for the shuffling
* @param swapper the callback on the swaps
* @ArrayType(T)
* @return the provided sorted array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, int offset, int length, RANDOM random, Swapper swapper) {
for(int i = length-1; i>=0;i--) {
int j = offset + i;
int p = offset + random.nextInt(i + 1);
swapper.swap(j, p);
KEY_TYPE t = array[j];
array[j] = array[p];
array[p] = t;
}
return array;
}
/**
* Simple Array Reversal method
* @param array the Array that should flip
@@ -575,6 +639,55 @@ public class ARRAYS
}
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
* On top of that allows to sort other things along with it.
* @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
* @return input array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectInsertionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectInsertionSort(array, 0, array.length, comp, swapper);
return array;
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
* On top of that allows to sort other things along with it.
* @param array the array that needs to be sorted
* @param length the maxmium size of the array to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectInsertionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectInsertionSort(array, 0, length, comp, swapper);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
* On top of that allows to sort other things along with it.
* @param array the array that needs to be sorted
* @param from where the array should be sorted from
* @param to where the array should be sorted to
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectInsertionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
for (int i = from+1;i<to; i++) {
KEY_TYPE current = array[i];
int j = i - 1;
while(j >= from && comp.compare(current, array[j]) < 0) {
swapper.swap(j+1, j);
array[j+1] = array[j--];
}
array[j+1] = current;
}
}
/**
* Sorts an array according to the natural ascending order using InsertionSort,
* @param array the array that needs to be sorted
@@ -661,6 +774,60 @@ public class ARRAYS
}
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
* On top of that allows to sort other things along with it.
* @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
* @return input array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectSelectionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectSelectionSort(array, 0, array.length, comp, swapper);
return array;
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
* On top of that allows to sort other things along with it.
* @param array the array that needs to be sorted
* @param length the maxmium size of the array to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectSelectionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectSelectionSort(array, 0, length, comp, swapper);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
* On top of that allows to sort other things along with it.
* @param array the array that needs to be sorted
* @param from where the array should be sorted from
* @param to where the array should be sorted to
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectSelectionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
for (int i = from; i < to; i++) {
KEY_TYPE min = array[i];
int minId = i;
for(int j = i+1; j < to; j++) {
if(comp.compare(array[j], min) < 0) {
min = array[j];
minId = j;
}
}
swapper.swap(i, minId);
KEY_TYPE temp = array[i];
array[i] = min;
array[minId] = temp;
}
}
/**
* Sorts an array according to the natural ascending order using Selection Sort,
* @param array the array that needs to be sorted
@@ -760,6 +927,72 @@ public class ARRAYS
}
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
* On top of that allows to sort other things along with it.
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
* @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
* @return input array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectMergeSort(array, null, 0, array.length, comp, swapper);
return array;
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
* On top of that allows to sort other things along with it.
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
* @param array the array that needs to be sorted
* @param length the maxmium size of the array to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectMergeSort(array, null, 0, length, comp, swapper);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
* On top of that allows to sort other things along with it.
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
* @param array the array that needs to be sorted
* @param supp the auxillary array that is used to simplify the sorting
* @param from where the array should be sorted from
* @param to where the array should be sorted to
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
if(to - from < BASE_THRESHOLD) {
indirectInsertionSort(array, from, to, comp, swapper);
return;
}
if(supp == null) supp = Arrays.copyOf(array, to);
int mid = (from + to) >>> 1;
indirectMergeSort(supp, array, from, mid, comp, swapper);
indirectMergeSort(supp, array, mid, to, comp, swapper);
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
{
System.arraycopy(supp, from, array, from, to - from);
return;
}
for(int p = from, q = mid;from < to;from++) {
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
swapper.swap(from, p);
array[from] = supp[p++];
continue;
}
swapper.swap(from, q);
array[from] = supp[q++];
}
}
/**
* Sorts an array according to the natural ascending order using Merge Sort,
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
@@ -856,6 +1089,56 @@ public class ARRAYS
mergeSort(array, supp, from, to, comp);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
* On top of that allows to sort other things along with it.
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
* @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectParallelMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
* On top of that allows to sort other things along with it.
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
* @param array the array that needs to be sorted
* @param length the maxmium size of the array to be sorted
* @param swapper the callback which elements were swapped
* @param comp the Comparator that decides the sorting order
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectParallelMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
* On top of that allows to sort other things along with it.
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
* @param array the array that needs to be sorted
* @param supp the auxillary array that is used to simplify the sorting
* @param from where the array should be sorted from
* @param to where the array should be sorted to
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectParallelMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
SanityChecks.invokeTask(new MergeSortActionCompSwapBRACES(array, supp, from, to, comp, swapper));
return;
}
indirectMergeSort(array, supp, from, to, comp, swapper);
}
/**
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
@@ -1209,6 +1492,73 @@ public class ARRAYS
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
* On top of that allows to sort other things along with it.
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
* @return input array
*/
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectQuickSort(array, 0, array.length, comp, swapper);
return array;
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
* On top of that allows to sort other things along with it.
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param length the maxmium size of the array to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectQuickSort(array, 0, length, comp, swapper);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
* On top of that allows to sort other things along with it.
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param from where the array should be sorted from
* @param to where the array should be sorted to
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
*/
public static GENERIC_KEY_BRACES void indirectQuickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
int length = to - from;
if(length <= 0) return;
if(length < BASE_THRESHOLD) {
indirectSelectionSort(array, from, to, comp, swapper);
return;
}
KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
int a = from, b = a, c = to - 1, d = c;
for(int compare;;swap(array, b++, c--, swapper)) {
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
if(compare == 0) swap(array, a++, b, swapper);
}
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
if(compare == 0) swap(array, c, d--, swapper);
}
if(b>c) break;
}
swap(array, from, b, Math.min(a - from, b - a), swapper);
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
}
/**
* Sorts an array according to the natural ascending order using Quick Sort,
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
@@ -1313,6 +1663,58 @@ public class ARRAYS
quickSort(array, from, to, comp);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
* On top of that allows to sort other things along with it.
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
*/
public static GENERIC_KEY_BRACES void indirectParallelQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
* On top of that allows to sort other things along with it.
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param length the maxmium size of the array to be sorted
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
*/
public static GENERIC_KEY_BRACES void indirectParallelQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
indirectParallelQuickSort(array, 0, length, comp, swapper);
}
/**
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
* On top of that allows to sort other things along with it.
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages12491265, 1993.
* @param array the array that needs to be sorted
* @param from where the array should be sorted from
* @param to where the array should be sorted to
* @param comp the Comparator that decides the sorting order
* @param swapper the callback which elements were swapped
* @ArrayType(T)
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
*/
public static GENERIC_KEY_BRACES void indirectParallelQuickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
SanityChecks.invokeTask(new QuickSortActionCompSwapBRACES(array, from, to, comp, swapper));
return;
}
indirectQuickSort(array, from, to, comp, swapper);
}
/**
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
@@ -1367,6 +1769,18 @@ public class ARRAYS
for(int i = 0;i<length;i++,swap(a, from++, to++));
}
static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to, Swapper swapper) {
swapper.swap(from, to);
KEY_TYPE t = a[from];
a[from] = a[to];
a[to] = t;
}
static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to, int length, Swapper swapper) {
to -= length;
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
}
static GENERIC_KEY_BRACES int subMedium(KEY_TYPE[] data, int a, int b, int c, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
}
@@ -1389,16 +1803,14 @@ public class ARRAYS
int from;
int to;
QuickSortAction(KEY_TYPE[] array, int from, int to)
{
QuickSortAction(KEY_TYPE[] array, int from, int to) {
this.array = array;
this.from = from;
this.to = to;
}
@Override
protected void compute()
{
protected void compute() {
int length = to - from;
if(length <= 0) return;
if(length < BASE_THRESHOLD) {
@@ -1431,8 +1843,7 @@ public class ARRAYS
int to;
COMPARATOR KEY_GENERIC_TYPE comp;
QuickSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
{
QuickSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
this.array = array;
this.from = from;
this.to = to;
@@ -1440,8 +1851,7 @@ public class ARRAYS
}
@Override
protected void compute()
{
protected void compute() {
int length = to - from;
if(length <= 0) return;
if(length < BASE_THRESHOLD) {
@@ -1467,6 +1877,49 @@ public class ARRAYS
}
}
static class QuickSortActionCompSwap KEY_GENERIC_TYPE extends RecursiveAction {
private static final long serialVersionUID = 0L;
KEY_TYPE[] array;
int from;
int to;
COMPARATOR KEY_GENERIC_TYPE comp;
Swapper swapper;
QuickSortActionCompSwap(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
this.array = array;
this.from = from;
this.to = to;
this.comp = comp;
this.swapper = swapper;
}
@Override
protected void compute() {
int length = to - from;
if(length <= 0) return;
if(length < BASE_THRESHOLD) {
indirectSelectionSort(array, from, to, comp, swapper);
return;
}
KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
int a = from, b = a, c = to - 1, d = c;
for(int compare;;swap(array, b++, c--, swapper)) {
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
if(compare == 0) swap(array, a++, b, swapper);
}
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
if(compare == 0) swap(array, c, d--, swapper);
}
if(b>c) break;
}
swap(array, from, b, Math.min(a - from, b - a), swapper);
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwapBRACES(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwapBRACES(array, to - (d - c), to, comp, swapper));
else if(b - a > 1) new QuickSortActionCompSwapBRACES(array, from, from + (b - a), comp, swapper).invoke();
else if(d - c > 1) new QuickSortActionCompSwapBRACES(array, to - (d - c), to, comp, swapper).invoke();
}
}
static class MergeSortAction KEY_GENERIC_TYPE extends RecursiveAction {
private static final long serialVersionUID = 0L;
KEY_TYPE[] array;
@@ -1474,8 +1927,7 @@ public class ARRAYS
int from;
int to;
MergeSortAction(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to)
{
MergeSortAction(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) {
this.array = array;
this.supp = supp;
this.from = from;
@@ -1483,8 +1935,7 @@ public class ARRAYS
}
@Override
protected void compute()
{
protected void compute() {
if(to - from < BASE_THRESHOLD) {
insertionSort(array, from, to);
return;
@@ -1512,8 +1963,7 @@ public class ARRAYS
int to;
COMPARATOR KEY_GENERIC_TYPE comp;
MergeSortActionComp(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
{
MergeSortActionComp(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
this.array = array;
this.supp = supp;
this.from = from;
@@ -1522,8 +1972,7 @@ public class ARRAYS
}
@Override
protected void compute()
{
protected void compute() {
if(to - from < BASE_THRESHOLD) {
insertionSort(array, from, to, comp);
return;
@@ -1543,22 +1992,64 @@ public class ARRAYS
}
}
static class MergeSortActionCompSwap KEY_GENERIC_TYPE extends RecursiveAction {
private static final long serialVersionUID = 0L;
KEY_TYPE[] array;
KEY_TYPE[] supp;
int from;
int to;
COMPARATOR KEY_GENERIC_TYPE comp;
Swapper swapper;
MergeSortActionCompSwap(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
this.array = array;
this.supp = supp;
this.from = from;
this.to = to;
this.comp = comp;
this.swapper = swapper;
}
@Override
protected void compute() {
if(to - from < BASE_THRESHOLD) {
indirectInsertionSort(array, from, to, comp, swapper);
return;
}
if(supp == null) supp = Arrays.copyOf(array, to);
int mid = (from + to) >>> 1;
invokeAll(new MergeSortActionCompSwapBRACES(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwapBRACES(supp, array, mid, to, comp, swapper));
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
{
System.arraycopy(supp, from, array, from, to - from);
return;
}
for(int p = from, q = mid;from < to;from++) {
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
swapper.swap(from, p);
array[from] = supp[p++];
continue;
}
swapper.swap(from, q);
array[from] = supp[q++];
}
}
}
static class MemFreeMergeSortAction KEY_GENERIC_TYPE extends RecursiveAction {
private static final long serialVersionUID = 0L;
KEY_TYPE[] array;
int from;
int to;
MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to)
{
MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to) {
this.array = array;
this.from = from;
this.to = to;
}
@Override
protected void compute()
{
protected void compute() {
if(to - from < BASE_THRESHOLD) {
insertionSort(array, from, to);
return;
@@ -1604,8 +2095,7 @@ public class ARRAYS
int to;
COMPARATOR KEY_GENERIC_TYPE comp;
MemFreeMergeSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
{
MemFreeMergeSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
this.array = array;
this.from = from;
this.to = to;
@@ -1613,8 +2103,7 @@ public class ARRAYS
}
@Override
protected void compute()
{
protected void compute() {
if(to - from < BASE_THRESHOLD) {
insertionSort(array, from, to, comp);
return;
@@ -7,6 +7,11 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.LockSupport;
import java.util.function.Consumer;
#if JDK_TYPE
import java.util.OPTIONAL;
#else
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -299,9 +304,8 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
* @param operator that reduces the elements.
* @return self with the reduce action applied
*/
public ASYNC_BUILDER KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
task = new SimpleReduceTaskBRACES(iterable.iterator(), operator);
return this;
public ObjectAsyncBuilder<OPTIONAL KEY_GENERIC_TYPE> reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
return new ObjectAsyncBuilder<>(new SimpleReduceTaskBRACES(iterable.iterator(), operator));
}
#if TYPE_OBJECT
@@ -435,9 +439,8 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
* @param filter that decides the desired elements
* @return self with the findFirst function applied
*/
public ASYNC_BUILDER KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
task = new FindFirstTaskBRACES(iterable.iterator(), filter);
return this;
public ObjectAsyncBuilder<OPTIONAL KEY_GENERIC_TYPE> findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
return new ObjectAsyncBuilder<>(new FindFirstTaskBRACES(iterable.iterator(), filter));
}
#if INT_ASYNC_MODULE
@@ -590,7 +593,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
}
#endif
private static class SimpleReduceTask KEY_GENERIC_TYPE extends BASE_TASK KEY_GENERIC_TYPE
private static class SimpleReduceTask KEY_GENERIC_TYPE extends BaseObjectTask<OPTIONAL KEY_GENERIC_TYPE>
{
ITERATOR KEY_GENERIC_TYPE iter;
UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator;
@@ -600,6 +603,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
public SimpleReduceTask(ITERATOR KEY_GENERIC_TYPE iter, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
this.iter = iter;
this.operator = operator;
this.setResult(OPTIONAL.empty());
}
@Override
@@ -614,7 +618,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
}
}
if(!iter.hasNext()) {
setResult(value);
setResult(OPTIONAL.GET_OPTIONAL(value));
return true;
}
return false;
@@ -689,7 +693,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
}
#endif
private static class FindFirstTask KEY_GENERIC_TYPE extends BASE_TASK KEY_GENERIC_TYPE
private static class FindFirstTask KEY_GENERIC_TYPE extends BaseObjectTask<OPTIONAL KEY_GENERIC_TYPE>
{
ITERATOR KEY_GENERIC_TYPE iter;
PREDICATE KEY_GENERIC_TYPE filter;
@@ -697,6 +701,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
public FindFirstTask(ITERATOR KEY_GENERIC_TYPE iter, PREDICATE KEY_GENERIC_TYPE filter) {
this.iter = iter;
this.filter = filter;
this.setResult(OPTIONAL.empty());
}
@Override
@@ -704,7 +709,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
while(shouldRun() && iter.hasNext()) {
KEY_TYPE entry = iter.NEXT();
if(filter.test(iter.NEXT())) {
setResult(entry);
setResult(OPTIONAL.GET_OPTIONAL(entry));
return true;
}
}
@@ -8,6 +8,9 @@ import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#endif
#if TYPE_OBJECT
import java.util.Comparator;
import java.util.function.BiFunction;
@@ -23,10 +26,16 @@ import java.util.function.Consumer;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if ORDERED_MAP_FEATURE
import speiger.src.collections.PACKAGE.collections.ORDERED_COLLECTION;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -76,6 +85,37 @@ public class COLLECTIONS
return c instanceof UnmodifiableCollection ? c : new UnmodifiableCollectionBRACES(c);
}
/**
* Returns a Immutable Ordered Collection instance based on the instance given.
* @param c that should be made immutable/unmodifiable
* @Type(T)
* @return a unmodifiable Ordered collection wrapper. If the Collection already a unmodifiable wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES ORDERED_COLLECTION KEY_GENERIC_TYPE unmodifiable(ORDERED_COLLECTION KEY_GENERIC_TYPE c) {
return c instanceof UnmodifiableOrderedCollection ? c : new UnmodifiableOrderedCollectionBRACES(c);
}
/**
* Returns a synchronized ordered Collection instance based on the instance given.
* @param c that should be synchronized
* @Type(T)
* @return a synchronized ordered collection wrapper. If the Collection already a synchronized wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES ORDERED_COLLECTION KEY_GENERIC_TYPE synchronize(ORDERED_COLLECTION KEY_GENERIC_TYPE c) {
return c instanceof SynchronizedOrderedCollection ? c : new SynchronizedOrderedCollectionBRACES(c);
}
/**
* Returns a synchronized ordered Collection instance based on the instance given.
* @param c that should be synchronized
* @param mutex is the controller of the synchronization block.
* @Type(T)
* @return a synchronized ordered collection wrapper. If the Collection already a synchronized wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES ORDERED_COLLECTION KEY_GENERIC_TYPE synchronize(ORDERED_COLLECTION KEY_GENERIC_TYPE c, Object mutex) {
return c instanceof SynchronizedOrderedCollection ? c : new SynchronizedOrderedCollectionBRACES(c, mutex);
}
/**
* Returns a synchronized Collection instance based on the instance given.
* @param c that should be synchronized
@@ -107,7 +147,10 @@ public class COLLECTIONS
return new SingletonCollectionBRACES(element);
}
protected static GENERIC_KEY_BRACES CollectionWrapper KEY_GENERIC_TYPE wrapper() {
/**
* Internal Use mainly. Its a collection wrapper with 0 dependencies for those actions where a collector is needed.
*/
public static GENERIC_KEY_BRACES CollectionWrapper KEY_GENERIC_TYPE wrapper() {
return new CollectionWrapperBRACES();
}
@@ -668,6 +711,38 @@ public class COLLECTIONS
@Override
public SingletonCollection KEY_GENERIC_TYPE copy() { return new SingletonCollectionBRACES(element); }
}
/**
* Synchronized Ordered Collection Wrapper for the synchronizedCollection function
* @Type(T)
*/
public static class SynchronizedOrderedCollection KEY_GENERIC_TYPE extends SynchronizedCollection KEY_GENERIC_TYPE implements ORDERED_COLLECTION KEY_GENERIC_TYPE {
ORDERED_COLLECTION KEY_GENERIC_TYPE c;
SynchronizedOrderedCollection(ORDERED_COLLECTION KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
this.c = c;
}
SynchronizedOrderedCollection(ORDERED_COLLECTION KEY_GENERIC_TYPE c) {
super(c);
this.c = c;
}
@Override
public ORDERED_COLLECTION KEY_GENERIC_TYPE reversed() { return COLLECTIONS.synchronize(c.reversed(), mutex); }
@Override
public void addFirst(KEY_TYPE e) { synchronized(mutex) { this.c.addFirst(e); } }
@Override
public void addLast(KEY_TYPE e) { synchronized(mutex) { this.c.addLast(e); } }
@Override
public KEY_TYPE GET_FIRST_KEY() { synchronized(mutex) { return this.c.GET_FIRST_KEY(); } }
@Override
public KEY_TYPE REMOVE_FIRST_KEY() { synchronized(mutex) { return this.c.REMOVE_FIRST_KEY(); } }
@Override
public KEY_TYPE GET_LAST_KEY() { synchronized(mutex) { return this.c.GET_LAST_KEY(); } }
@Override
public KEY_TYPE REMOVE_LAST_KEY() { synchronized(mutex) { return this.c.REMOVE_LAST_KEY(); } }
}
/**
* Synchronized Collection Wrapper for the synchronizedCollection function
@@ -803,13 +878,41 @@ public class COLLECTIONS
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { synchronized(mutex) { return c.reduce(identity, operator); } }
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { synchronized(mutex) { return c.reduce(operator); } }
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { synchronized(mutex) { return c.reduce(operator); } }
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return c.findFirst(filter); } }
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return c.findFirst(filter); } }
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return c.count(filter); } }
}
/**
* Unmodifyable Ordered Collection Wrapper for the unmodifyableCollection method
* @Type(T)
*/
public static class UnmodifiableOrderedCollection KEY_GENERIC_TYPE extends UnmodifiableCollection KEY_GENERIC_TYPE implements ORDERED_COLLECTION KEY_GENERIC_TYPE {
ORDERED_COLLECTION KEY_GENERIC_TYPE c;
UnmodifiableOrderedCollection(ORDERED_COLLECTION KEY_GENERIC_TYPE c) {
super(c);
this.c = c;
}
@Override
public ORDERED_COLLECTION KEY_GENERIC_TYPE reversed() { return COLLECTIONS.unmodifiable(c.reversed()); }
@Override
public void addFirst(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE GET_FIRST_KEY() { return c.GET_FIRST_KEY(); }
@Override
public KEY_TYPE REMOVE_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE GET_LAST_KEY() { return c.GET_LAST_KEY(); }
@Override
public KEY_TYPE REMOVE_LAST_KEY() { throw new UnsupportedOperationException(); }
}
/**
* Unmodifyable Collection Wrapper for the unmodifyableCollection method
* @Type(T)
@@ -927,9 +1030,9 @@ public class COLLECTIONS
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { return c.reduce(identity, operator); }
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { return c.reduce(operator); }
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { return c.reduce(operator); }
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { return c.findFirst(filter); }
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { return c.findFirst(filter); }
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) { return c.count(filter); }
}
@@ -65,7 +65,7 @@ public class ITERATORS
* @Type(T)
* @return an empty iterator
*/
public static GENERIC_KEY_BRACES EmptyIterator KEY_GENERIC_TYPE empty() {
public static GENERIC_KEY_BRACES LIST_ITERATOR KEY_GENERIC_TYPE empty() {
#if TYPE_OBJECT
return (EmptyIterator<KEY_TYPE>)EMPTY;
#else
@@ -400,7 +400,7 @@ public class ITERATORS
* @ArrayType(T)
* @return a Iterator that is wrapping a array.
*/
public static GENERIC_KEY_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE... a) {
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE wrap(KEY_TYPE... a) {
return wrap(a, 0, a.length);
}
@@ -412,7 +412,7 @@ public class ITERATORS
* @ArrayType(T)
* @return a Iterator that is wrapping a array.
*/
public static GENERIC_KEY_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE[] a, int start, int end) {
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE wrap(KEY_TYPE[] a, int start, int end) {
return new ArrayIteratorBRACES(a, start, end);
}
@@ -45,7 +45,7 @@ public class LISTS
* @Type(T)
* @return an empty list
*/
public static GENERIC_KEY_BRACES EmptyList KEY_GENERIC_TYPE empty() {
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE empty() {
#if TYPE_OBJECT
return (EmptyList<KEY_TYPE>)EMPTY;
#else
@@ -4,16 +4,22 @@ package speiger.src.collections.PACKAGE.utils;
import java.util.Collection;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.BiFunction;
#endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
#if JDK_TYPE
import java.util.OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if DEQUEUE_FEATURE
import speiger.src.collections.PACKAGE.queues.PRIORITY_DEQUEUE;
#endif
@@ -24,6 +30,7 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
/**
@@ -140,7 +147,15 @@ public class PRIORITY_QUEUES
@Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.matchesAll(filter); } }
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.findFirst(filter); } }
public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.findFirst(filter); } }
#if TYPE_OBJECT
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) { synchronized(mutex) { return queue.reduce(identity, operator); } }
#else
@Override
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { synchronized(mutex) { return queue.reduce(identity, operator); } }
#endif
@Override
public OPTIONAL KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { synchronized(mutex) { return queue.reduce(operator); } }
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.count(filter); } }
}
@@ -360,6 +360,10 @@ public class SETS
s = c;
}
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
@@ -371,17 +375,19 @@ public class SETS
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return ITERATORS.unmodifiable(s.iterator()); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator() { return ITERATORS.unmodifiable(s.reverseIterator()); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return ITERATORS.unmodifiable(s.iterator(fromElement)); }
@Override
public ORDERED_SET KEY_GENERIC_TYPE copy() { return s.copy(); }
@Override
public KEY_TYPE FIRST_KEY() { return s.FIRST_KEY(); }
public KEY_TYPE GET_FIRST_KEY() { return s.GET_FIRST_KEY(); }
@Override
public KEY_TYPE POLL_FIRST_KEY() { throw new UnsupportedOperationException(); }
public KEY_TYPE REMOVE_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE LAST_KEY() { return s.LAST_KEY(); }
public KEY_TYPE GET_LAST_KEY() { return s.GET_LAST_KEY(); }
@Override
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); }
public KEY_TYPE REMOVE_LAST_KEY() { throw new UnsupportedOperationException(); }
}
#endif
@@ -648,7 +654,11 @@ public class SETS
super(c, mutex);
s = c;
}
@Override
public void addFirst(KEY_TYPE o) { synchronized(mutex) { s.addFirst(o); } }
@Override
public void addLast(KEY_TYPE o) { synchronized(mutex) { s.addLast(o); } }
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { synchronized(mutex) { return s.addAndMoveToFirst(o); } }
@Override
@@ -660,17 +670,19 @@ public class SETS
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { synchronized(mutex) { return s.iterator(); } }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator() { synchronized(mutex) { return s.reverseIterator(); } }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { synchronized(mutex) { return s.iterator(fromElement); } }
@Override
public ORDERED_SET KEY_GENERIC_TYPE copy() { synchronized(mutex) { return s.copy(); } }
@Override
public KEY_TYPE FIRST_KEY() { synchronized(mutex) { return s.FIRST_KEY(); } }
public KEY_TYPE GET_FIRST_KEY() { synchronized(mutex) { return s.GET_FIRST_KEY(); } }
@Override
public KEY_TYPE POLL_FIRST_KEY() { synchronized(mutex) { return s.POLL_FIRST_KEY(); } }
public KEY_TYPE REMOVE_FIRST_KEY() { synchronized(mutex) { return s.REMOVE_FIRST_KEY(); } }
@Override
public KEY_TYPE LAST_KEY() { synchronized(mutex) { return s.LAST_KEY(); } }
public KEY_TYPE GET_LAST_KEY() { synchronized(mutex) { return s.GET_LAST_KEY(); } }
@Override
public KEY_TYPE POLL_LAST_KEY() { synchronized(mutex) { return s.POLL_LAST_KEY(); } }
public KEY_TYPE REMOVE_LAST_KEY() { synchronized(mutex) { return s.REMOVE_LAST_KEY(); } }
}
#endif
@@ -56,6 +56,9 @@ import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.utils.SETS;
#endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
#if ORDERED_MAP_FEATURE
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
#endif
#if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
#endif
@@ -553,6 +556,10 @@ public class MAPS
@Override
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE putFirst(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE putLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(KEY_TYPE key) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToLast(KEY_TYPE key) { throw new UnsupportedOperationException(); }
@@ -573,13 +580,25 @@ public class MAPS
@Override
public VALUE_TYPE LAST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { return map.firstEntry(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() { return map.lastEntry(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() { throw new UnsupportedOperationException(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() { throw new UnsupportedOperationException(); }
@Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { return map.copy(); }
@Override
public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keys == null) keys = SETS.unmodifiable(map.keySet());
return (ORDERED_SET KEY_GENERIC_TYPE)keys;
}
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(values == null) values = VALUE_COLLECTIONS.unmodifiable(map.values());
return (VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE)values;
}
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new UnmodifyableOrderedEntrySetKV_BRACES(map.ENTRY_SET());
@@ -735,7 +754,11 @@ public class MAPS
super(c);
set = c;
}
@Override
public void addFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
@@ -749,15 +772,17 @@ public class MAPS
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { return ObjectIterators.unmodifiable(set.iterator()); }
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> reverseIterator() { return ObjectIterators.unmodifiable(set.reverseIterator()); }
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator(MAP.Entry KEY_VALUE_GENERIC_TYPE fromElement) { return ObjectIterators.unmodifiable(set.iterator(fromElement)); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() { return set.first(); }
public MAP.Entry KEY_VALUE_GENERIC_TYPE getFirst() { return set.getFirst(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() { throw new UnsupportedOperationException(); }
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeFirst() { throw new UnsupportedOperationException(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() { return set.last(); }
public MAP.Entry KEY_VALUE_GENERIC_TYPE getLast() { return set.getLast(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() { throw new UnsupportedOperationException(); }
public MAP.Entry KEY_VALUE_GENERIC_TYPE removeLast() { throw new UnsupportedOperationException(); }
}
#endif
@@ -938,6 +963,10 @@ public class MAPS
@Override
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.putAndMoveToLast(key, value); } }
@Override
public VALUE_TYPE putFirst(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.putFirst(key, value); } }
@Override
public VALUE_TYPE putLast(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.putLast(key, value); } }
@Override
public boolean moveToFirst(KEY_TYPE key) { synchronized(mutex) { return map.moveToFirst(key); } }
@Override
public boolean moveToLast(KEY_TYPE key) { synchronized(mutex) { return map.moveToLast(key); } }
@@ -958,13 +987,25 @@ public class MAPS
@Override
public VALUE_TYPE LAST_ENTRY_VALUE() { synchronized(mutex) { return map.LAST_ENTRY_VALUE(); } }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { synchronized(mutex) { return map.firstEntry(); } }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() { synchronized(mutex) { return map.lastEntry(); } }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() { synchronized(mutex) { return map.pollFirstEntry(); } }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() { synchronized(mutex) { return map.pollLastEntry(); } }
@Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { synchronized(mutex) { return map.copy(); } }
@Override
public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keys == null) keys = SETS.synchronize(map.keySet(), mutex);
return (ORDERED_SET KEY_GENERIC_TYPE)keys;
}
@Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(values == null) values = VALUE_COLLECTIONS.synchronize(map.values(), mutex);
return (VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE)values;
}
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = ObjectSets.synchronize(map.ENTRY_SET(), mutex);
@@ -1,16 +1,29 @@
package speiger.src.testers.PACKAGE.builder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.google.common.collect.testing.AbstractTester;
import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.OneSizeTestContainerGenerator;
import com.google.common.collect.testing.SampleElements;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.Feature;
import junit.framework.TestSuite;
import speiger.src.collections.PACKAGE.collections.ITERABLE;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.PACKAGE.utils.LISTS;
import speiger.src.testers.PACKAGE.generators.TEST_ORDERED_SET_GENERATOR;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetMoveTester;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetIterationTester;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetNavigationTester;
import speiger.src.testers.PACKAGE.utils.SAMPLE_ELEMENTS;
import speiger.src.testers.utils.SpecialFeature;
@SuppressWarnings("javadoc")
public class ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE extends SET_TEST_BUILDER KEY_GENERIC_TYPE {
@@ -35,4 +48,68 @@ public class ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE extends SET_TEST_BUILDER
#endignore
return super.createTestSuite();
}
@Override
protected List<TestSuite> createDerivedSuites(
FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Collection<CLASS_TYPE>, CLASS_TYPE>> parentBuilder) {
List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
if (!parentBuilder.getFeatures().contains(SpecialFeature.REVERSE)) {
derivedSuites.add(createReverseSuite(parentBuilder));
}
return derivedSuites;
}
private TestSuite createReverseSuite(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Collection<CLASS_TYPE>, CLASS_TYPE>> parentBuilder) {
TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE delegate = (TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE) parentBuilder.getSubjectGenerator().getInnerGenerator();
List<Feature<?>> features = new ArrayList<>();
features.add(SpecialFeature.REVERSE);
features.addAll(parentBuilder.getFeatures());
features.remove(SpecialFeature.COPYING);
features.remove(SpecialFeature.CHILDREN_COPY);
return ORDERED_SET_TEST_BUILDER.using(new TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE() {
@Override
public SampleElements<CLASS_TYPE> samples() {
return delegate.samples();
}
@Override
public SAMPLE_ELEMENTS KEY_GENERIC_TYPE getSamples() {
return delegate.getSamples();
}
@Override
public ITERABLE KEY_GENERIC_TYPE order(LIST KEY_GENERIC_TYPE insertionOrder) {
return insertionOrder;
}
@Override
public Iterable<CLASS_TYPE> order(List<CLASS_TYPE> insertionOrder) {
return insertionOrder;
}
#if !TYPE_OBJECT
@Override
public ORDERED_SET KEY_GENERIC_TYPE create(KEY_TYPE... elements) {
LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(elements);
LISTS.reverse(list);
return delegate.create(list.TO_ARRAY()).reversed();
}
#endif
@Override
public ORDERED_SET KEY_GENERIC_TYPE create(Object... elements) {
LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
for (Object e : elements) {
list.add(CLASS_TO_KEY(e));
}
LISTS.reverse(list);
return delegate.create(list.toArray()).reversed();
}
}).named(parentBuilder.getName() + " reversing").withFeatures(features)
.suppressing(parentBuilder.getSuppressedTests()).createTestSuite();
}
}
@@ -238,21 +238,17 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
private static Set<Feature<?>> computeEntrySetFeatures(Set<Feature<?>> mapFeatures) {
Set<Feature<?>> entrySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) {
entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
}
if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) {
entrySetFeatures.add(SpecialFeature.COPYING);
}
else {
entrySetFeatures.remove(SpecialFeature.COPYING);
}
if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) {
entrySetFeatures.add(SpecialFeature.MODIFIABLE);
}
else {
entrySetFeatures.remove(SpecialFeature.MODIFIABLE);
}
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) entrySetFeatures.add(SpecialFeature.COPYING);
else entrySetFeatures.remove(SpecialFeature.COPYING);
if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) entrySetFeatures.add(SpecialFeature.MODIFIABLE);
else entrySetFeatures.remove(SpecialFeature.MODIFIABLE);
if(mapFeatures.contains(SpecialFeature.REVERSE)) entrySetFeatures.add(SpecialFeature.REVERSE);
else entrySetFeatures.remove(SpecialFeature.REVERSE);
entrySetFeatures.add(SpecialFeature.MAP_ENTRY);
#endignore
return entrySetFeatures;
@@ -262,23 +258,17 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
Set<Feature<?>> keySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore
keySetFeatures.add(CollectionFeature.SUBSET_VIEW);
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) {
keySetFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
} else if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEY_QUERIES)) {
keySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
}
if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) {
keySetFeatures.add(SpecialFeature.COPYING);
}
else {
keySetFeatures.remove(SpecialFeature.COPYING);
}
if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) {
keySetFeatures.add(SpecialFeature.MODIFIABLE);
}
else {
keySetFeatures.remove(SpecialFeature.MODIFIABLE);
}
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) keySetFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
else if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEY_QUERIES)) keySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) keySetFeatures.add(SpecialFeature.COPYING);
else keySetFeatures.remove(SpecialFeature.COPYING);
if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) keySetFeatures.add(SpecialFeature.MODIFIABLE);
else keySetFeatures.remove(SpecialFeature.MODIFIABLE);
if(mapFeatures.contains(SpecialFeature.REVERSE)) keySetFeatures.add(SpecialFeature.REVERSE);
else keySetFeatures.remove(SpecialFeature.REVERSE);
#endignore
return keySetFeatures;
}
@@ -287,18 +277,15 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
private static Set<Feature<?>> computeValuesCollectionFeatures(Set<Feature<?>> mapFeatures) {
Set<Feature<?>> valuesCollectionFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) {
valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
}
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) {
valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
}
if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) {
valuesCollectionFeatures.add(SpecialFeature.COPYING);
}
else {
valuesCollectionFeatures.remove(SpecialFeature.COPYING);
}
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) valuesCollectionFeatures.add(SpecialFeature.COPYING);
else valuesCollectionFeatures.remove(SpecialFeature.COPYING);
if(mapFeatures.contains(SpecialFeature.REVERSE)) valuesCollectionFeatures.add(SpecialFeature.REVERSE);
else valuesCollectionFeatures.remove(SpecialFeature.REVERSE);
#endignore
return valuesCollectionFeatures;
}
@@ -1,9 +1,14 @@
package speiger.src.testers.PACKAGE.builder.maps;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.common.collect.testing.AbstractTester;
import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
import com.google.common.collect.testing.OneSizeTestContainerGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.Feature;
import junit.framework.TestSuite;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
@@ -12,14 +17,17 @@ import speiger.src.testers.PACKAGE.builder.SET_TEST_BUILDER;
import speiger.src.testers.PACKAGE.generators.TEST_ORDERED_SET_GENERATOR;
import speiger.src.testers.PACKAGE.generators.TEST_SET_GENERATOR;
import speiger.src.testers.PACKAGE.generators.maps.TEST_ORDERED_MAP_GENERATOR;
import speiger.src.testers.PACKAGE.impl.maps.DERIVED_MAP_GENERATORS;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapMoveTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapNavigationTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapPutTester;
#if !TYPE_OBJECT
import speiger.src.testers.objects.builder.ObjectSetTestSuiteBuilder;
import speiger.src.testers.objects.generators.TestObjectSetGenerator;
import speiger.src.testers.objects.builder.ObjectOrderedSetTestSuiteBuilder;
import speiger.src.testers.objects.generators.TestObjectOrderedSetGenerator;
#endif
import speiger.src.testers.utils.SpecialFeature;
@SuppressWarnings("javadoc")
public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE
@@ -34,6 +42,7 @@ public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BU
List<Class<? extends AbstractTester>> testers = super.getTesters();
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapMoveTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapNavigationTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapPutTester.class);
return testers;
}
@@ -45,6 +54,15 @@ public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BU
return super.createTestSuite();
}
@Override
protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Map<CLASS_TYPE, CLASS_VALUE_TYPE>, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>>> parentBuilder) {
List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
if (!parentBuilder.getFeatures().contains(SpecialFeature.REVERSE)) {
derivedSuites.add(createReverseSuite(parentBuilder));
}
return derivedSuites;
}
protected ObjectSetTestSuiteBuilder<MAP.Entry KEY_VALUE_GENERIC_TYPE> createDerivedEntrySetSuite(TestObjectSetGenerator<MAP.Entry KEY_VALUE_GENERIC_TYPE> entrySetGenerator) {
return ObjectOrderedSetTestSuiteBuilder.using((TestObjectOrderedSetGenerator<MAP.Entry KEY_VALUE_GENERIC_TYPE>)entrySetGenerator);
}
@@ -52,4 +70,17 @@ public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BU
protected SET_TEST_BUILDER KEY_GENERIC_TYPE createDerivedKeySetSuite(TEST_SET_GENERATOR KEY_GENERIC_TYPE generator) {
return ORDERED_SET_TEST_BUILDER.using((TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE)generator);
}
private TestSuite createReverseSuite(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Map<CLASS_TYPE, CLASS_VALUE_TYPE>, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>>> parentBuilder) {
TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE delegate = (TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE) parentBuilder.getSubjectGenerator().getInnerGenerator();
List<Feature<?>> features = new ArrayList<>();
features.add(SpecialFeature.REVERSE);
features.addAll(parentBuilder.getFeatures());
features.remove(SpecialFeature.COPYING);
features.remove(SpecialFeature.CHILDREN_COPY);
return ORDERED_MAP_TEST_BUILDER.using(new DERIVED_MAP_GENERATORS.ReverseTestOrderedMapGeneratorKV_BRACES(delegate))
.named(parentBuilder.getName() + " reversed").withFeatures(features)
.suppressing(parentBuilder.getSuppressedTests()).createTestSuite();
}
}
@@ -20,6 +20,7 @@ import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP.Entry;
import speiger.src.collections.PACKAGE.maps.interfaces.NAVIGABLE_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.SORTED_MAP;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.SET;
@@ -206,6 +207,22 @@ public class DERIVED_MAP_GENERATORS {
}
}
public static class ReverseTestOrderedMapGenerator KEY_VALUE_GENERIC_TYPE extends MapGenerator KEY_VALUE_GENERIC_TYPE implements TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE {
TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE parent;
public ReverseTestOrderedMapGenerator(TEST_ORDERED_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE parent) {
super(parent);
this.parent = parent;
}
@Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE create(Entry KEY_VALUE_GENERIC_TYPE... elements) {
ObjectList<Entry KEY_VALUE_GENERIC_TYPE> entries = new ObjectArrayList<Entry KEY_VALUE_GENERIC_TYPE>(elements);
ObjectLists.reverse(entries);
return ((ORDERED_MAP KEY_VALUE_GENERIC_TYPE)parent.create(entries.toArray(Entry[]::new))).reversed();
}
}
public static class MapGenerator KEY_VALUE_GENERIC_TYPE implements TEST_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE
{
TEST_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE parent;
@@ -27,6 +27,8 @@ import speiger.src.collections.PACKAGE.maps.impl.concurrent.CONCURRENT_HASH_MAP;
#if TYPE_OBJECT
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP;
import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP;
import speiger.src.collections.PACKAGE.maps.impl.reference.REF_MAP;
import speiger.src.collections.PACKAGE.maps.impl.reference.LINKED_REF_MAP;
#endif
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
@@ -134,6 +136,97 @@ public class MAP_CONSTRUCTOR_TESTS
}
#if TYPE_OBJECT
public static class RefMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester KEY_VALUE_STRING_GENERIC_TYPE
{
public RefMap() {
setSimpleConstructor(REF_MAP::new);
setSizeConstructor(REF_MAP::new);
setPArrayConstructor(REF_MAP::new);
#if !TYPE_OBJECT || !VALUE_OBJECT
setArrayConstructor(REF_MAP::new);
#endif
setPMapConstructor(REF_MAP::new);
setMapConstructor(REF_MAP::new);
}
@Test
public void testWrongLoadFactorSize() {
setSizeConstructor(T -> new REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 0F));
try {
testSizeConstructor_smallSize();
fail("A Constructor using a 0 LoadFactor should error");
} catch(IllegalStateException e) {}
setSizeConstructor(T -> new REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 1F));
try {
testSizeConstructor_smallSize();
fail("A Constructor using a 1 LoadFactor should error");
} catch(IllegalStateException e) {}
}
#if TYPE_OBJECT
@Override
protected String[] createKeyElements() {
return Arrays.copyOfRange(StringSortTest.NAMES, 0, 100);
}
#endif
#if VALUE_OBJECT
@Override
protected String[] createValueElements() {
return Arrays.copyOfRange(StringSortTest.NAMES, 100, 200);
}
#endif
}
public static class LinkedRefMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester KEY_VALUE_STRING_GENERIC_TYPE
{
public LinkedRefMap() {
setSimpleConstructor(LINKED_REF_MAP::new);
setSizeConstructor(LINKED_REF_MAP::new);
setPArrayConstructor(LINKED_REF_MAP::new);
#if !TYPE_OBJECT || !VALUE_OBJECT
setArrayConstructor(LINKED_REF_MAP::new);
#endif
setPMapConstructor(LINKED_REF_MAP::new);
setMapConstructor(LINKED_REF_MAP::new);
}
@Test
public void testWrongLoadFactorSize() {
setSizeConstructor(T -> new LINKED_REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 0F));
try {
testSizeConstructor_smallSize();
fail("A Constructor using a 0 LoadFactor should error");
} catch(IllegalStateException e) {
}
setSizeConstructor(T -> new LINKED_REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 1F));
try {
testSizeConstructor_smallSize();
fail("A Constructor using a 1 LoadFactor should error");
} catch(IllegalStateException e) {
}
}
#if TYPE_OBJECT
@Override
protected String[] createKeyElements() {
return Arrays.copyOfRange(StringSortTest.NAMES, 0, 100);
}
#endif
#if VALUE_OBJECT
@Override
protected String[] createValueElements() {
return Arrays.copyOfRange(StringSortTest.NAMES, 100, 200);
}
#endif
}
#if VALUE_OBJECT
public static class EnumMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester<AnEnum, String>
#else
@@ -25,6 +25,15 @@ public class FILE_KEY_TYPECollectionForEachTester KEY_GENERIC_TYPE extends ABSTR
collection.forEach(elements::add);
HELPERS.assertContentsAnyOrder(elements, createSamplesArray());
}
#ignore
@CollectionFeature.Require(absent = KNOWN_ORDER)
public void testIndexedForEachUnknownOrder() {
#endignore
LIST KEY_GENERIC_TYPE elements = new ARRAY_LISTBRACES();
collection.forEachIndexed((K, V) -> elements.add(V));
HELPERS.assertContentsAnyOrder(elements, createSamplesArray());
}
#ignore
@CollectionFeature.Require(absent = KNOWN_ORDER)
@@ -43,6 +52,15 @@ public class FILE_KEY_TYPECollectionForEachTester KEY_GENERIC_TYPE extends ABSTR
collection.forEach(elements::add);
assertEquals("Different ordered iteration", HELPERS.copyToList(getOrderedElements()), elements);
}
#ignore
@CollectionFeature.Require(KNOWN_ORDER)
public void testIndexedForEachKnownOrder() {
#endignore
LIST KEY_GENERIC_TYPE elements = new ARRAY_LISTBRACES();
collection.forEachIndexed((K, V) -> elements.add(V));
assertEquals("Different ordered iteration", HELPERS.copyToList(getOrderedElements()), elements);
}
#ignore
@CollectionFeature.Require(KNOWN_ORDER)
@@ -4,6 +4,12 @@ package speiger.src.testers.PACKAGE.tests.iterable;
import java.util.Objects;
#endif
#if JDK_TYPE
import java.util.OPTIONAL;
#else
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import org.junit.Ignore;
import com.google.common.collect.testing.features.CollectionSize;
@@ -27,17 +33,17 @@ public class FILE_KEY_TYPEIterableFindFirstTester KEY_GENERIC_TYPE extends ABSTR
@CollectionSize.Require(absent = CollectionSize.ZERO)
#endignore
public void testIterableFindFirst_FindFirstElements() {
assertEquals("First Element should be found", e0(), container.findFirst(T -> KEY_EQUALS(T, e0())));
assertEquals("First Element should be found", e0(), container.findFirst(T -> KEY_EQUALS(T, e0())).SUPPLY_GET());
}
public void testIterableFindFirst_FindNothing() {
assertEquals("No element should be found", EMPTY_KEY_VALUE, container.findFirst(T -> KEY_EQUALS(T, e4())));
assertEquals("No element should be found", OPTIONAL.empty(), container.findFirst(T -> KEY_EQUALS(T, e4())));
}
#ignore
@CollectionSize.Require(CollectionSize.SEVERAL)
#endignore
public void testIterableFindFirst_FindLastElement() {
assertEquals("Last Element should be found", e2(), container.findFirst(T -> KEY_EQUALS(T, e2())));
assertEquals("Last Element should be found", e2(), container.findFirst(T -> KEY_EQUALS(T, e2())).SUPPLY_GET());
}
}
@@ -3,9 +3,16 @@ package speiger.src.testers.PACKAGE.tests.iterable;
#if TYPE_OBJECT
import java.util.Objects;
#endif
#if JDK_TYPE
import java.util.OPTIONAL;
#else
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import org.junit.Ignore;
import com.google.common.collect.testing.features.CollectionSize;
import speiger.src.testers.PACKAGE.tests.base.ABSTRACT_COLLECTION_TESTER;
@Ignore
@@ -29,7 +36,7 @@ public class FILE_KEY_TYPEIterableReduceTester KEY_GENERIC_TYPE extends ABSTRACT
}
public void testIterableReduce() {
assertEquals("The sum of the collection should match", getSum(), collection.reduce(this::sum));
assertEquals("The sum of the collection should match", size == CollectionSize.ZERO ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(getSum()), collection.reduce(this::sum));
}
public void testIterableExtraReduce() {
@@ -27,6 +27,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapContainsTester KEY_VALUE_GENERIC_TY
#ignore
@CollectionSize.Require(absent = ZERO)
@SuppressWarnings("unlikely-arg-type")
#endignore
public void testContainsObject_yes() {
assertTrue("contains(present) should return true", getMap().ENTRY_SET().contains(new AbstractMap.SimpleEntry<>(e0())));
@@ -36,6 +37,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapContainsTester KEY_VALUE_GENERIC_TY
assertFalse("contains(notPresent) should return false", getMap().ENTRY_SET().contains(e3()));
}
@SuppressWarnings("unlikely-arg-type")
public void testContainsObject_no() {
assertFalse("contains(notPresent) should return false", getMap().ENTRY_SET().contains(new AbstractMap.SimpleEntry<>(e3())));
}
@@ -136,6 +136,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapRemoveEntryTester KEY_VALUE_GENERIC
#ignore
@CollectionSize.Require(ONE)
@MapFeature.Require(SUPPORTS_REMOVE)
@SuppressWarnings("unlikely-arg-type")
#endignore
public void testRemove_supportedObjectEntryPresent() {
assertTrue(getMap().ENTRY_SET().remove(new AbstractMap.SimpleEntry<>(e0())));
@@ -154,6 +155,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapRemoveEntryTester KEY_VALUE_GENERIC
#ignore
@CollectionSize.Require(ONE)
@MapFeature.Require(SUPPORTS_REMOVE)
@SuppressWarnings("unlikely-arg-type")
#endignore
public void testRemove_supportedObjectEntryMissing() {
assertFalse(getMap().ENTRY_SET().remove(new AbstractMap.SimpleEntry<>(e3())));
@@ -0,0 +1,118 @@
package speiger.src.testers.PACKAGE.tests.maps;
#ignore
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
import static org.junit.Assert.assertNotEquals;
#endignore
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.testers.PACKAGE.tests.base.maps.ABSTRACT_MAP_TESTER;
import speiger.src.testers.objects.utils.ObjectHelpers;
@SuppressWarnings("javadoc")
public class FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapPutTester KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP_TESTER KEY_VALUE_GENERIC_TYPE
{
private ORDERED_MAP KEY_VALUE_GENERIC_TYPE orderedMap;
private ObjectList<MAP.Entry KEY_VALUE_GENERIC_TYPE> values;
private KEY_TYPE a;
private VALUE_TYPE aValue;
@Override
public void setUp() throws Exception {
super.setUp();
orderedMap = (ORDERED_MAP KEY_VALUE_GENERIC_TYPE)getMap();
values = ObjectHelpers.copyToList(getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements()));
if (values.size() >= 1) {
a = values.get(0).ENTRY_KEY();
aValue = values.get(0).ENTRY_VALUE();
}
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testPutFirst() {
assertEquals(aValue, orderedMap.putFirst(a, v3()));
assertNotEquals(v3(), orderedMap.FIRST_ENTRY_VALUE());
assertEquals(orderedMap.getDefaultReturnValue(), orderedMap.putFirst(k4(), v4()));
assertEquals(v4(), orderedMap.FIRST_ENTRY_VALUE());
assertEquals(e4(), orderedMap.firstEntry());
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testPutLast() {
assertEquals(aValue, orderedMap.putLast(a, v3()));
assertNotEquals(v3(), orderedMap.LAST_ENTRY_VALUE());
assertEquals(orderedMap.getDefaultReturnValue(), orderedMap.putLast(k4(), v4()));
assertEquals(v4(), orderedMap.LAST_ENTRY_VALUE());
assertEquals(e4(), orderedMap.lastEntry());
}
#ignore
@MapFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(CollectionSize.ONE)
#endignore
public void testPollFirst() {
assertFalse(orderedMap.isEmpty());
assertEquals(e0(), orderedMap.pollFirstEntry());
assertTrue(orderedMap.isEmpty());
}
#ignore
@MapFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(CollectionSize.ONE)
#endignore
public void testPollLast() {
assertFalse(orderedMap.isEmpty());
assertEquals(e0(), orderedMap.pollLastEntry());
assertTrue(orderedMap.isEmpty());
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
#endignore
public void testUnsupportedPutFirst() {
try { orderedMap.putFirst(a, aValue); }
catch (UnsupportedOperationException tolerated) {}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
#endignore
public void testUnsupportedPutLast() {
try { orderedMap.putLast(a, aValue); }
catch (UnsupportedOperationException tolerated) {}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_REMOVE)
#endignore
public void testUnsupportedPollFirst() {
try { orderedMap.pollFirstEntry(); }
catch (UnsupportedOperationException tolerated) {}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_REMOVE)
#endignore
public void testUnsupportedPollLast() {
try { orderedMap.pollFirstEntry(); }
catch (UnsupportedOperationException tolerated) {}
expectUnchanged();
}
}
@@ -2,6 +2,11 @@ package speiger.src.testers.PACKAGE.tests.queue.iterators;
#if TYPE_OBJECT
import java.util.Objects;
#endif
#if JDK_TYPE
import java.util.OPTIONAL;
#else
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import org.junit.Ignore;
@@ -27,17 +32,17 @@ public class FILE_KEY_TYPEQueueFindFirstTester KEY_GENERIC_TYPE extends ABSTRACT
@CollectionSize.Require(absent = CollectionSize.ZERO)
#endignore
public void testQueueFindFirst_FindFirstElements() {
assertEquals("First Element should be found", e0(), queue.findFirst(T -> KEY_EQUALS(T, e0())));
assertEquals("First Element should be found", e0(), queue.findFirst(T -> KEY_EQUALS(T, e0())).SUPPLY_GET());
}
public void testQueueFindFirst_FindNothing() {
assertEquals("No element should be found", EMPTY_KEY_VALUE, queue.findFirst(T -> KEY_EQUALS(T, e4())));
assertEquals("No element should be found", OPTIONAL.empty(), queue.findFirst(T -> KEY_EQUALS(T, e4())));
}
#ignore
@CollectionSize.Require(CollectionSize.SEVERAL)
#endignore
public void testQueueFindFirst_FindLastElement() {
assertEquals("Last Element should be found", e2(), queue.findFirst(T -> KEY_EQUALS(T, e2())));
assertEquals("Last Element should be found", e2(), queue.findFirst(T -> KEY_EQUALS(T, e2())).SUPPLY_GET());
}
}
@@ -3,10 +3,16 @@ package speiger.src.testers.PACKAGE.tests.queue.iterators;
#if TYPE_OBJECT
import java.util.Objects;
#endif
#if JDK_TYPE
import java.util.OPTIONAL;
#else
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import org.junit.Ignore;
import speiger.src.testers.PACKAGE.tests.base.ABSTRACT_QUEUE_TESTER;
import com.google.common.collect.testing.features.CollectionSize;
@Ignore
@SuppressWarnings("javadoc")
@@ -29,7 +35,7 @@ public class FILE_KEY_TYPEQueueReduceTester KEY_GENERIC_TYPE extends ABSTRACT_QU
}
public void testQueueReduce() {
assertEquals("The sum of the queue should match", getSum(), queue.reduce(this::sum));
assertEquals("The sum of the queue should match", size == CollectionSize.ZERO ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(getSum()), queue.reduce(this::sum));
}
public void testQueueExtraReduce() {
@@ -45,10 +45,10 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testaddMoveToFirstMissing()
{
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(true, orderedSet.addAndMoveToFirst(e4()));
assertNotEquals(a, orderedSet.FIRST_KEY());
assertEquals(e4(), orderedSet.FIRST_KEY());
assertNotEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(e4(), orderedSet.GET_FIRST_KEY());
}
#ignore
@@ -57,10 +57,10 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testaddMoveToFirstPreset()
{
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(false, orderedSet.addAndMoveToFirst(c));
assertNotEquals(a, orderedSet.FIRST_KEY());
assertEquals(c, orderedSet.FIRST_KEY());
assertNotEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(c, orderedSet.GET_FIRST_KEY());
}
#ignore
@@ -69,10 +69,10 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testaddMoveToLastMissing()
{
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(true, orderedSet.addAndMoveToLast(e4()));
assertNotEquals(c, orderedSet.LAST_KEY());
assertEquals(e4(), orderedSet.LAST_KEY());
assertNotEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(e4(), orderedSet.GET_LAST_KEY());
}
#ignore
@@ -81,10 +81,10 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testaddMoveToLastPreset()
{
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(false, orderedSet.addAndMoveToLast(a));
assertNotEquals(c, orderedSet.LAST_KEY());
assertEquals(a, orderedSet.LAST_KEY());
assertNotEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(a, orderedSet.GET_LAST_KEY());
}
#ignore
@@ -93,9 +93,9 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testMoveToFirstMissing()
{
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(false, orderedSet.moveToFirst(e4()));
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
}
#ignore
@@ -104,10 +104,10 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testMoveToFirstPreset()
{
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(true, orderedSet.moveToFirst(c));
assertNotEquals(a, orderedSet.FIRST_KEY());
assertEquals(c, orderedSet.FIRST_KEY());
assertNotEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(c, orderedSet.GET_FIRST_KEY());
}
#ignore
@@ -116,9 +116,9 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testMoveToLastMissing()
{
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(false, orderedSet.moveToLast(e4()));
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
}
#ignore
@@ -127,10 +127,10 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testMoveToLastPreset()
{
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(true, orderedSet.moveToLast(a));
assertNotEquals(c, orderedSet.LAST_KEY());
assertEquals(a, orderedSet.LAST_KEY());
assertNotEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(a, orderedSet.GET_LAST_KEY());
}
#ignore
@@ -139,10 +139,10 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testMoveCenterToLast()
{
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
assertTrue(orderedSet.moveToLast(e1()));
assertNotEquals(c, orderedSet.LAST_KEY());
assertEquals(e1(), orderedSet.LAST_KEY());
assertNotEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(e1(), orderedSet.GET_LAST_KEY());
}
#ignore
@@ -151,10 +151,10 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testMoveCenterToFirst()
{
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
assertTrue(orderedSet.moveToFirst(e1()));
assertNotEquals(c, orderedSet.FIRST_KEY());
assertEquals(e1(), orderedSet.FIRST_KEY());
assertNotEquals(c, orderedSet.GET_FIRST_KEY());
assertEquals(e1(), orderedSet.GET_FIRST_KEY());
}
#ignore
@@ -163,13 +163,13 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testMoveForthAndBack()
{
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
assertTrue(orderedSet.moveToLast(e0()));
assertNotEquals(c, orderedSet.LAST_KEY());
assertEquals(a, orderedSet.LAST_KEY());
assertNotEquals(a, orderedSet.FIRST_KEY());
assertNotEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(a, orderedSet.GET_LAST_KEY());
assertNotEquals(a, orderedSet.GET_FIRST_KEY());
assertTrue(orderedSet.moveToFirst(e0()));
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
}
#ignore
@@ -178,13 +178,13 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testMoveBackAndForth()
{
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
assertTrue(orderedSet.moveToFirst(e2()));
assertNotEquals(a, orderedSet.FIRST_KEY());
assertEquals(c, orderedSet.FIRST_KEY());
assertNotEquals(c, orderedSet.LAST_KEY());
assertNotEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(c, orderedSet.GET_FIRST_KEY());
assertNotEquals(c, orderedSet.GET_LAST_KEY());
assertTrue(orderedSet.moveToLast(e2()));
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
}
#ignore
@@ -193,13 +193,13 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testAddForthAndBack()
{
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
assertFalse(orderedSet.addAndMoveToLast(e0()));
assertNotEquals(c, orderedSet.LAST_KEY());
assertEquals(a, orderedSet.LAST_KEY());
assertNotEquals(a, orderedSet.FIRST_KEY());
assertNotEquals(c, orderedSet.GET_LAST_KEY());
assertEquals(a, orderedSet.GET_LAST_KEY());
assertNotEquals(a, orderedSet.GET_FIRST_KEY());
assertFalse(orderedSet.addAndMoveToFirst(e0()));
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
}
#ignore
@@ -208,13 +208,13 @@ public class FILE_KEY_TYPEOrderedSetMoveTester KEY_GENERIC_TYPE extends ABSTRACT
#endignore
public void testAddBackAndForth()
{
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
assertFalse(orderedSet.addAndMoveToFirst(e2()));
assertNotEquals(a, orderedSet.FIRST_KEY());
assertEquals(c, orderedSet.FIRST_KEY());
assertNotEquals(c, orderedSet.LAST_KEY());
assertNotEquals(a, orderedSet.GET_FIRST_KEY());
assertEquals(c, orderedSet.GET_FIRST_KEY());
assertNotEquals(c, orderedSet.GET_LAST_KEY());
assertFalse(orderedSet.addAndMoveToLast(e2()));
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
}
#ignore
@@ -68,7 +68,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
int polled = 0;
int expectedPolls = orderedSet.size();
while(polled < expectedPolls) {
orderedSet.POLL_FIRST_KEY();
orderedSet.REMOVE_FIRST_KEY();
polled++;
}
assertTrue("Map should be empty", orderedSet.isEmpty());
@@ -82,7 +82,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
int polled = 0;
int expectedPolls = orderedSet.size();
while(polled < expectedPolls) {
orderedSet.POLL_LAST_KEY();
orderedSet.REMOVE_LAST_KEY();
polled++;
}
assertTrue("Map should be empty", orderedSet.isEmpty());
@@ -94,8 +94,8 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
#endignore
public void testEmptySetPollFirst() {
try {
orderedSet.POLL_FIRST_KEY();
fail("OrderedSet.POLL_FIRST_KEY should throw NoSuchElementException");
orderedSet.REMOVE_FIRST_KEY();
fail("OrderedSet.REMOVE_FIRST_KEY should throw NoSuchElementException");
} catch (NoSuchElementException e) {
}
expectUnchanged();
@@ -107,8 +107,8 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
#endignore
public void testEmptySetPollLast() {
try {
orderedSet.POLL_LAST_KEY();
fail("OrderedSet.POLL_LAST_KEY should throw NoSuchElementException");
orderedSet.REMOVE_LAST_KEY();
fail("OrderedSet.REMOVE_LAST_KEY should throw NoSuchElementException");
} catch (NoSuchElementException e) {
}
expectUnchanged();
@@ -119,8 +119,8 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
#endignore
public void testUnsupportedSetPollFirst() {
try {
orderedSet.POLL_FIRST_KEY();
fail("OrderedSet.POLL_FIRST_KEY should throw UnsupportedOperationException");
orderedSet.REMOVE_FIRST_KEY();
fail("OrderedSet.REMOVE_FIRST_KEY should throw UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
}
expectUnchanged();
@@ -131,8 +131,8 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
#endignore
public void testUnsupportedSetPollLast() {
try {
orderedSet.POLL_LAST_KEY();
fail("OrderedSet.POLL_LAST_KEY should throw UnsupportedOperationException");
orderedSet.REMOVE_LAST_KEY();
fail("OrderedSet.REMOVE_LAST_KEY should throw UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
}
expectUnchanged();
@@ -143,7 +143,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
@CollectionSize.Require(ONE)
#endignore
public void testSingletonSetPollFirst() {
assertEquals(a, orderedSet.POLL_FIRST_KEY());
assertEquals(a, orderedSet.REMOVE_FIRST_KEY());
assertTrue(orderedSet.isEmpty());
}
@@ -152,7 +152,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
@CollectionSize.Require(ONE)
#endignore
public void testSingletonSetPollLast() {
assertEquals(a, orderedSet.POLL_LAST_KEY());
assertEquals(a, orderedSet.REMOVE_LAST_KEY());
assertTrue(orderedSet.isEmpty());
}
@@ -161,7 +161,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
@CollectionSize.Require(SEVERAL)
#endignore
public void testPollFirst() {
assertEquals(a, orderedSet.POLL_FIRST_KEY());
assertEquals(a, orderedSet.REMOVE_FIRST_KEY());
assertEquals(values.subList(1, values.size()), HELPERS.copyToList(orderedSet));
}
@@ -170,7 +170,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
@CollectionSize.Require(SEVERAL)
#endignore
public void testPollLast() {
assertEquals(c, orderedSet.POLL_LAST_KEY());
assertEquals(c, orderedSet.REMOVE_LAST_KEY());
assertEquals(values.subList(0, values.size()-1), HELPERS.copyToList(orderedSet));
}
@@ -179,7 +179,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
#endignore
public void testPollFirstUnsupported() {
try {
orderedSet.POLL_FIRST_KEY();
orderedSet.REMOVE_FIRST_KEY();
fail();
} catch (UnsupportedOperationException e) {
}
@@ -190,7 +190,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
#endignore
public void testPollLastUnsupported() {
try {
orderedSet.POLL_LAST_KEY();
orderedSet.REMOVE_LAST_KEY();
fail();
} catch (UnsupportedOperationException e) {
}
@@ -201,7 +201,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
#endignore
public void testEmptySetFirst() {
try {
orderedSet.FIRST_KEY();
orderedSet.GET_FIRST_KEY();
fail();
} catch (NoSuchElementException e) {
}
@@ -212,7 +212,7 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
#endignore
public void testEmptySetLast() {
try {
orderedSet.LAST_KEY();
orderedSet.GET_LAST_KEY();
fail();
} catch (NoSuchElementException e) {
}
@@ -222,27 +222,27 @@ public class FILE_KEY_TYPEOrderedSetNavigationTester KEY_GENERIC_TYPE extends AB
@CollectionSize.Require(ONE)
#endignore
public void testSingletonSetFirst() {
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
}
#ignore
@CollectionSize.Require(ONE)
#endignore
public void testSingletonSetLast() {
assertEquals(a, orderedSet.LAST_KEY());
assertEquals(a, orderedSet.GET_LAST_KEY());
}
#ignore
@CollectionSize.Require(SEVERAL)
#endignore
public void testFirst() {
assertEquals(a, orderedSet.FIRST_KEY());
assertEquals(a, orderedSet.GET_FIRST_KEY());
}
#ignore
@CollectionSize.Require(SEVERAL)
#endignore
public void testLast() {
assertEquals(c, orderedSet.LAST_KEY());
assertEquals(c, orderedSet.GET_LAST_KEY());
}
}
@@ -12,6 +12,9 @@ import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.SetFeature;
import com.google.common.collect.testing.features.Feature;
#if TYPE_OBJECT
import com.google.common.collect.testing.testers.CollectionAddTester;
import com.google.common.collect.testing.testers.CollectionAddAllTester;
import com.google.common.collect.testing.testers.CollectionCreationTester;
import com.google.common.collect.testing.features.CollectionFeature;
#endif
import junit.framework.Test;
@@ -122,6 +125,9 @@ public class SET_TESTS extends TestCase
#ignore
.withFeatures(getSizes(size)).withFeatures(features);
if(nullValues) builder.withFeatures(CollectionFeature.ALLOWS_NULL_VALUES);
builder.suppressing(CollectionAddTester.getAddNullUnsupportedMethod(), CollectionAddTester.getAddNullSupportedMethod());
builder.suppressing(CollectionAddAllTester.getAddAllNullUnsupportedMethod());
builder.suppressing(CollectionCreationTester.getCreateWithNullUnsupportedMethod());
#endignore
return builder.createTestSuite();
}
@@ -41,6 +41,8 @@ import speiger.src.collections.PACKAGE.maps.impl.misc.ARRAY_MAP;
#if TYPE_OBJECT
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP;
import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP;
import speiger.src.collections.PACKAGE.maps.impl.reference.REF_MAP;
import speiger.src.collections.PACKAGE.maps.impl.reference.LINKED_REF_MAP;
#endif
import speiger.src.collections.PACKAGE.maps.impl.tree.AVL_TREE_MAP;
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
@@ -104,6 +106,7 @@ public class MAP_TESTS extends TestCase
#if TYPE_OBJECT
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.EnumMap.class));
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.LinkedEnumMap.class));
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.RefMap.class));
#endif
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.CustomHashMap.class));
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.LinkedCustomHashMap.class));
@@ -130,27 +133,29 @@ public class MAP_TESTS extends TestCase
}
public static void suite(TestSuite suite) {
suite.addTest(mapSuite("HASH_MAP", HASH_MAP::new, getFeatures(), -1, true));
suite.addTest(orderedMapSuite("LINKED_HASH_MAP", LINKED_HASH_MAP::new, getFeatures(), -1));
suite.addTest(orderedMapSuite("IMMUTABLE_HASH_MAP", IMMUTABLE_HASH_MAP::new, getImmutableFeatures(), -1));
suite.addTest(mapSuite("HASH_MAP", HASH_MAP::new, getFeatures(), -1, true, true));
suite.addTest(orderedMapSuite("LINKED_HASH_MAP", LINKED_HASH_MAP::new, getFeatures(), -1, true));
suite.addTest(orderedMapSuite("IMMUTABLE_HASH_MAP", IMMUTABLE_HASH_MAP::new, getImmutableFeatures(), -1, true));
#if TYPE_OBJECT
suite.addTest(enumMapSuite("ENUM_MAP", ENUM_MAP::new, getFeatures(), 5));
suite.addTest(enumOrderedMapSuite("LINKED_ENUM_MAP", (K, V) -> K.length <= 0 ? new LINKED_ENUM_MAP<>(AnEnum.class) : new LINKED_ENUM_MAP<>(K, V), getFeatures(), 5));
suite.addTest(mapSuite("REF_MAP", REF_MAP::new, getFeatures(), - 1, true, false));
suite.addTest(orderedMapSuite("LINKED_REF_MAP", LINKED_REF_MAP::new, getFeatures(), - 1, false));
#endif
suite.addTest(mapSuite("CUSTOM_HASH_MAP", (K, V) -> new CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true));
suite.addTest(orderedMapSuite("LINKED_CUSTOM_HASH_MAP", (K, V) -> new LINKED_CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1));
suite.addTest(orderedMapSuite("ARRAY_MAP", ARRAY_MAP::new, getFeatures(), -1));
suite.addTest(mapSuite("CUSTOM_HASH_MAP", (K, V) -> new CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true, true));
suite.addTest(orderedMapSuite("LINKED_CUSTOM_HASH_MAP", (K, V) -> new LINKED_CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true));
suite.addTest(orderedMapSuite("ARRAY_MAP", ARRAY_MAP::new, getFeatures(), -1, true));
suite.addTest(concurrentMapSuite("CONCURRENT_HASH_MAP", CONCURRENT_HASH_MAP::new, getFeatures(), 2));
suite.addTest(concurrentMapSuite("CONCURRENT_HASH_MAP", CONCURRENT_HASH_MAP::new, getFeatures(), 3));
suite.addTest(navigableMapSuite("RB_TREE_MAP", RB_TREE_MAP::new, getFeatures(), -1));
suite.addTest(navigableMapSuite("AVL_TREE_MAP", AVL_TREE_MAP::new, getFeatures(), -1));
suite.addTest(navigableMapSuite("SynchronizedRB_TREE_MAP", (K, V) -> new RB_TREE_MAPKV_BRACES(K, V).synchronize(), getLimitedFeatures(), -1));
suite.addTest(navigableMapSuite("UnmodifiableRB_TREE_MAP", (K, V) -> new RB_TREE_MAPKV_BRACES(K, V).unmodifiable(), getLimitedImmutableFeatures(), -1));
suite.addTest(orderedMapSuite("SynchronizedORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).synchronize(), getFeatures(), -1));
suite.addTest(orderedMapSuite("UnmodifiableORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).unmodifiable(), getImmutableFeatures(), -1));
suite.addTest(mapSuite("EmptyMAP", (K, V) -> MAPS.empty(), getEmptyFeatures(), 0, false));
suite.addTest(mapSuite("SingletonMAP", (K, V) -> MAPS.singleton(K[0], V[0]), getEmptyFeatures(), 1, false));
suite.addTest(mapSuite("AbstractMap", SIMPLE_TEST_MAP::new, getTestFeatures(), -1, false));
suite.addTest(orderedMapSuite("SynchronizedORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).synchronize(), getFeatures(), -1, true));
suite.addTest(orderedMapSuite("UnmodifiableORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).unmodifiable(), getImmutableFeatures(), -1, true));
suite.addTest(mapSuite("EmptyMAP", (K, V) -> MAPS.empty(), getEmptyFeatures(), 0, false, true));
suite.addTest(mapSuite("SingletonMAP", (K, V) -> MAPS.singleton(K[0], V[0]), getEmptyFeatures(), 1, false, true));
suite.addTest(mapSuite("AbstractMap", SIMPLE_TEST_MAP::new, getTestFeatures(), -1, false, true));
}
#if TYPE_OBJECT
@@ -209,14 +214,14 @@ public class MAP_TESTS extends TestCase
#endif
private static Test mapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean sorted) {
private static Test mapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean sorted, boolean allowNullKeys) {
SIMPLE_MAP_TEST_GENERATOR.Maps KEY_VALUE_STRING_GENERIC_TYPE generator = new SIMPLE_MAP_TEST_GENERATOR.Maps KEY_VALUE_STRING_GENERIC_TYPE(factory);
MAP_TEST_BUILDER KEY_VALUE_STRING_GENERIC_TYPE builder = MAP_TEST_BUILDER.using(generator);
builder.shouldBlockKeys(sorted);
#if TYPE_OBJECT
generator.setKeys(createKeys());
#ignore
builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
if(allowNullKeys) builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
#endignore
#endif
#if VALUE_OBJECT
@@ -265,13 +270,13 @@ public class MAP_TESTS extends TestCase
return builder.named(name).createTestSuite();
}
private static Test orderedMapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], ORDERED_MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size) {
private static Test orderedMapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], ORDERED_MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean allowNullKeys) {
SIMPLE_MAP_TEST_GENERATOR.OrderedMaps KEY_VALUE_STRING_GENERIC_TYPE generator = new SIMPLE_MAP_TEST_GENERATOR.OrderedMaps KEY_VALUE_STRING_GENERIC_TYPE(factory);
ORDERED_MAP_TEST_BUILDER KEY_VALUE_STRING_GENERIC_TYPE builder = ORDERED_MAP_TEST_BUILDER.using(generator);
#if TYPE_OBJECT
generator.setKeys(createKeys());
#ignore
builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
if(allowNullKeys) builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
#endignore
#endif
#if VALUE_OBJECT
@@ -0,0 +1,5 @@
package speiger.src.collections.utils;
public interface Swapper {
public void swap(int fromIndex, int toIndex);
}
@@ -9,8 +9,7 @@ import speiger.src.collections.ints.maps.interfaces.Int2IntNavigableMap;
import speiger.src.collections.tests.NavigableSetTest;
@SuppressWarnings("javadoc")
public abstract class BaseInt2IntNavigableMapTest extends BaseInt2IntSortedMapTest
{
public abstract class BaseInt2IntNavigableMapTest extends BaseInt2IntSortedMapTest {
@Override
public abstract Int2IntNavigableMap createMap(int[] keys, int[] values);
@Override
@@ -29,30 +28,22 @@ public abstract class BaseInt2IntNavigableMapTest extends BaseInt2IntSortedMapTe
@Test
public void lowerTest() {
if(getValidNavigableMapTests().contains(NavigableSetTest.LOWER)) {
Assert.assertTrue(createMap(TEST_ARRAY, TEST_ARRAY).lowerKey(50) < 50);
}
if(getValidNavigableMapTests().contains(NavigableSetTest.LOWER)) { Assert.assertTrue(createMap(TEST_ARRAY, TEST_ARRAY).lowerKey(50) < 50); }
}
@Test
public void higherTest() {
if(getValidNavigableMapTests().contains(NavigableSetTest.HIGHER)) {
Assert.assertTrue(createMap(TEST_ARRAY, TEST_ARRAY).higherKey(50) > 50);
}
if(getValidNavigableMapTests().contains(NavigableSetTest.HIGHER)) { Assert.assertTrue(createMap(TEST_ARRAY, TEST_ARRAY).higherKey(50) > 50); }
}
@Test
public void ceilTest() {
if(getValidNavigableMapTests().contains(NavigableSetTest.CEILING)) {
Assert.assertTrue(createMap(TEST_ARRAY, TEST_ARRAY).ceilingKey(50) >= 50);
}
if(getValidNavigableMapTests().contains(NavigableSetTest.CEILING)) { Assert.assertTrue(createMap(TEST_ARRAY, TEST_ARRAY).ceilingKey(50) >= 50); }
}
@Test
public void floorTest() {
if(getValidNavigableMapTests().contains(NavigableSetTest.FLOOR)) {
Assert.assertTrue(createMap(TEST_ARRAY, TEST_ARRAY).floorKey(50) <= 50);
}
if(getValidNavigableMapTests().contains(NavigableSetTest.FLOOR)) { Assert.assertTrue(createMap(TEST_ARRAY, TEST_ARRAY).floorKey(50) <= 50); }
}
@Test
@@ -75,7 +66,7 @@ public abstract class BaseInt2IntNavigableMapTest extends BaseInt2IntSortedMapTe
Assert.assertTrue(subSet.lowerKey(50) < 50);
Assert.assertTrue(subSet.higherKey(50) > 50);
Assert.assertTrue(subSet.ceilingKey(50) >= 50);
Assert.assertTrue(subSet.floorKey(50) <= 50);
Assert.assertTrue(subSet.floorKey(50) <= 50);
}
}
@@ -23,10 +23,10 @@ public abstract class BaseInt2IntOrderedMapTest extends BaseInt2IntMapTest
{
if(!getValidOrderedMapTests().contains(OrderedMapTests.PUT_MOVE)) return;
Int2IntOrderedMap map = createMap(TEST_ARRAY, TEST_ARRAY);
Assert.assertEquals(0, map.putAndMoveToFirst(120, -1));
Assert.assertEquals(-1, map.putAndMoveToFirst(120, -1));
Assert.assertEquals(120, map.firstIntKey());
Assert.assertEquals(-1, map.firstIntValue());
Assert.assertEquals(0, map.putAndMoveToLast(121, -2));
Assert.assertEquals(-1, map.putAndMoveToLast(121, -2));
Assert.assertEquals(121, map.lastIntKey());
Assert.assertEquals(-2, map.lastIntValue());
}
@@ -96,7 +96,7 @@ public abstract class BaseIntIterableTest
public void testStreamFindFirst() {
if(getValidIterableTests().contains(IterableTest.STREAM_FIND_FIRST)) {
int expected = IntStream.of(TEST_ARRAY).filter(T -> T / 50 > 0).findFirst().getAsInt();
int actual = create(TEST_ARRAY).findFirst(T -> T / 50 > 0);
int actual = create(TEST_ARRAY).findFirst(T -> T / 50 > 0).getAsInt();
Assert.assertEquals(expected, actual);
}
}
@@ -40,8 +40,8 @@ public abstract class BaseIntOrderedSetTest extends BaseIntCollectionTest
public void peekTest() {
if(getValidOrderedSetTests().contains(OrderedSetTest.PEEK)) {
IntOrderedSet set = create(TEST_ARRAY);
Assert.assertEquals(set.firstInt(), 0);
Assert.assertEquals(set.lastInt(), 99);
Assert.assertEquals(set.getFirstInt(), 0);
Assert.assertEquals(set.getLastInt(), 99);
}
}
@@ -51,12 +51,12 @@ public abstract class BaseIntOrderedSetTest extends BaseIntCollectionTest
IntOrderedSet set = create(TEST_ARRAY);
for(int i = 0;i<100;i++)
{
Assert.assertEquals(i, set.pollFirstInt());
Assert.assertEquals(i, set.removeFirstInt());
}
set = create(TEST_ARRAY);
for(int i = 99;i>=0;i--)
{
Assert.assertEquals(i, set.pollLastInt());
Assert.assertEquals(i, set.removeLastInt());
}
}
}
@@ -113,7 +113,6 @@ public abstract class BaseIntPriorityQueueTest extends BaseIntIterableTest
}
@Test
@SuppressWarnings("deprecation")
public void testToArray() {
if(getValidPriorityQueueTests().contains(PriorityQueueTest.TO_ARRAY)) {
IntPriorityQueue queue = create(EMPTY_ARRAY);
@@ -18,6 +18,7 @@ public enum SpecialFeature implements Feature<Collection> {
ITERATOR_MODIFIABLE,
MAP_ENTRY,
DESCENDING,
REVERSE,
SUBMAP;
private final Set<Feature<? super Collection>> implied;