28 Commits
Author SHA1 Message Date
Speiger 8ff1d4f0b5 Last Sync for now 2026-05-14 21:33:31 +02:00
Speiger e56e136459 Sync with latest changes 2026-05-14 19:24:20 +02:00
Speiger 4db9c69a54 Source Sync 2026-05-14 02:54:57 +02:00
Speiger 91aabe2096 Sync Source Changes :) 2026-05-12 13:40:48 +02:00
Speiger 4c565f2cf3 Sync Latest Update 2026-05-11 18:02:31 +02:00
Speiger 720fa44eed Whoops forgot the special cases 2026-05-11 00:25:20 +02:00
Speiger c46baa10b4 Updated Workflow 2026-05-11 00:21:34 +02:00
Speiger 29ddc55947 Synced first part of the next update 2026-05-11 00:20:50 +02:00
Speiger 2a2d9e8d95 Updated to 0.9.0 src 2023-06-29 22:59:18 +02:00
Speiger 49ce7fbfbe Merge branch 'master' into debug 2023-06-29 22:56:43 +02:00
Speiger 6afed5e174 Version Bump 2023-06-29 22:52:44 +02:00
Speiger 640a1a8161 Fixed tests and added missing changelog 2023-06-29 20:04:45 +02:00
Speiger 274d37c4d6 New Features.
-Added: List.indexedIterator which allows you to create a iterator with a customized iteration indecies. Useful if you want to transform lists output.
-Added: PriorityQueue.contains is now a function
-Added: Iterators/Async Builders now support MapToPrimitiveType function on the object variant. So more processing can be done. (Will be expanded upon later versions)
-Updated: SimpleCodeGenerator 1.3.0 is now being used which allows for iterative code support.
2023-06-29 18:30:22 +02:00
Speiger a89c812c06 Added Infinite Iterators 2023-06-17 01:22:56 +02:00
Speiger 867b3b4d9a Fixing Debug Branch by bringing it up to date! 2023-06-15 19:05:47 +02:00
Speiger 6af0656216 Adding coverage to master to make things simpler! 2023-06-15 18:53:08 +02:00
Speiger e76db94136 Upgrading Other dependencies! 2023-06-15 18:31:22 +02:00
Speiger 7011101b05 Upgraded Gradle to be java19/20 friendly 2023-06-15 18:19:12 +02:00
Speiger d0599b99ec Upgraded Build Script and support now java19/20 2023-06-15 18:09:14 +02:00
Speiger d7c5b9ad7d Optimized SelectionSort a tiny bit. 2023-06-15 18:08:57 +02:00
Speiger d2c81e7779 Fixed all the reported issues by the Unit testing. 2023-06-15 17:12:11 +02:00
Speiger ef5fdbd377 Finished Code Cleanup with Compute functions and added ReversedWrappers 2023-06-14 17:40:27 +02:00
Speiger 5e67e45910 Fixed failing tests/errors 2023-06-06 11:21:52 +02:00
Speiger 63ef68fb95 New Compute function and better toArray implementations 2023-06-05 23:40:48 +02:00
Speiger 0f9751bf70 Fixed that setValue wasn't working with ForEach implementations. 2023-05-18 23:02:27 +02:00
Speiger bcc2ffdc13 New features.
-Added: Improved Map documentation for compute methods
-Added: Dedicated toArray implementations to TreeSets
2023-05-17 09:58:55 +02:00
Speiger 2da4588430 Added getFirst/getLast/removeFirst/removeLast to lists 2023-05-17 09:20:45 +02:00
Speiger ed9ce60af4 Small Fixes to doc and Useless Imports 2023-05-17 09:01:09 +02:00
2408 changed files with 1817759 additions and 61473 deletions
-6
View File
@@ -6,12 +6,6 @@
<attribute name="gradle_used_by_scope" value="main,test"/> <attribute name="gradle_used_by_scope" value="main,test"/>
</attributes> </attributes>
</classpathentry> </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"> <classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes> <attributes>
<attribute name="gradle_scope" value="test"/> <attribute name="gradle_scope" value="test"/>
+5 -4
View File
@@ -11,19 +11,20 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
jdk: [8, 11, 14, 16, 17, 18] jdk: [8, 11, 16, 17, 18, 19, 20]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up JDK ${{ matrix.jdk }} - name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v1 uses: actions/setup-java@v3
with: with:
distribution: 'temurin'
java-version: ${{ matrix.jdk }} java-version: ${{ matrix.jdk }}
- name: Validate Gradle wrapper - name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b uses: gradle/wrapper-validation-action@v1
- name: Make gradlew executable - name: Make gradlew executable
run: chmod +x ./gradlew run: chmod +x ./gradlew
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
name: Unit Tests name: Unit Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
+27
View File
@@ -0,0 +1,27 @@
name: Measure coverage
on:
push:
branches: [ debug ]
jobs:
build:
name: Code Quality Check
runs-on: ubuntu-latest
steps:
- 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@v5
with:
distribution: 'temurin'
java-version: 11
cache: 'gradle'
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Build and analyze
run: ./gradlew generateTestSource test jacocoTestReport --info -Dfull_test_suite=true
- name: Upload to CodeCov
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: bash <(curl -s https://codecov.io/bash) -t $CODECOV_TOKEN
+1 -9
View File
@@ -20,15 +20,7 @@ gradle-app.setting
/bin/ /bin/
/storage/ /storage/
#Generated Code #Generated Code
/src/main/java/speiger/src/collections/booleans/*
/src/main/java/speiger/src/collections/bytes/*
/src/main/java/speiger/src/collections/shorts/*
/src/main/java/speiger/src/collections/chars/*
/src/main/java/speiger/src/collections/ints/*
/src/main/java/speiger/src/collections/longs/*
/src/main/java/speiger/src/collections/floats/*
/src/main/java/speiger/src/collections/doubles/*
/src/main/java/speiger/src/collections/objects/*
#Generated Tests #Generated Tests
/src/test/java/speiger/src/testers/booleans/* /src/test/java/speiger/src/testers/booleans/*
+20
View File
@@ -1,5 +1,25 @@
# Changelog of versions # Changelog of versions
### Version 0.8.1
- Added: getFirst/getLast/removeFirst/removeLast to List.class.
- Added: Dedicated Set toArray implementations.
- Added: ToArray/pushTop functions to Stack.class.
- Added: ComputeNonDefault functions which will contain the current behavior of the Compute function, while the Compute will be changed to be more java compliant!
- Added: List.reversed, which returns a SubList that has all elements in reversed order and also inserts reversed.
- Added: Iterators.infinite as an option that will create a Infinite Iterator based on the inputed one.
- Added: List.indexedIterator which allows you to create a iterator with a customized iteration indecies. Useful if you want to transform lists output.
- Added: PriorityQueue.contains is now a function
- Added: Iterators/Async Builders now support MapToPrimitiveType function on the object variant. So more processing can be done. (Will be expanded upon later versions)
- Fixed: SetValue wasn't working on forEach implementations.
- Fixed: Compute functions now perform with primitives more java compliant. Meaning that getDefaultReturnValue function no longer is seen as null.
- Fixed: Supplier was using the wrong dataType in their function name.
- Updated: SimpleCodeGenerator 1.3.0 is now being used which allows for iterative code support.
### Version 0.8.0
- Added: getFirst/getLast/removeFirst/removeLast to Lists
- Added: Dedicated implementations for toArray into TreeSets
- Fixed: forEach methods in Maps now can use "setValue" functions.
### Version 0.8.0 ### Version 0.8.0
- Added: ISizeProvider interface (Optimization Helper) - Added: ISizeProvider interface (Optimization Helper)
- Added: ISizeProvider into most Iterable implementations (Distinct/Filter/FlatMap/ArrayFlatMap don't support it, for obvious reasons) - Added: ISizeProvider into most Iterable implementations (Distinct/Filter/FlatMap/ArrayFlatMap don't support it, for obvious reasons)
+1 -1
View File
@@ -50,7 +50,7 @@ repositories {
} }
} }
dependencies { dependencies {
implementation 'com.github.Speiger:Primitive-Collections:0.7.0' implementation 'com.github.Speiger:Primitive-Collections:0.9.0'
} }
``` ```
+34 -26
View File
@@ -19,7 +19,7 @@ repositories {
} }
archivesBaseName = 'Primitive Collections' archivesBaseName = 'Primitive Collections'
version = '0.8.0'; version = '0.9.0';
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaVersion.current(); sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaVersion.current();
@@ -46,9 +46,9 @@ configurations {
dependencies { dependencies {
builderImplementation 'com.google.code.gson:gson:2.10' builderImplementation 'com.google.code.gson:gson:2.10'
builderImplementation 'de.speiger:Simple-Code-Generator:1.2.2' builderImplementation 'de.speiger:Simple-Code-Generator:1.3.0'
testImplementation 'junit:junit:4.12' 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'
} }
@@ -83,6 +83,14 @@ task generateTestSource(type: JavaExec) {
args = ['tests', 'silent'] args = ['tests', 'silent']
} }
task forceGenerateTestSource(type: JavaExec) {
group = 'internal'
description = 'Builds the sourcecode for the Tests'
classpath = sourceSets.builder.runtimeClasspath
main = 'speiger.src.builder.PrimitiveCollectionsBuilder'
args = ['tests', 'silent', 'force']
}
task generateLimitSource(type: JavaExec) { task generateLimitSource(type: JavaExec) {
group = 'internal' group = 'internal'
description = 'Builds the Sourcecode with the ModuleSettings.json applied' description = 'Builds the Sourcecode with the ModuleSettings.json applied'
@@ -93,12 +101,12 @@ task generateLimitSource(type: JavaExec) {
task javadocJar(type: Jar) { task javadocJar(type: Jar) {
from javadoc from javadoc
classifier = 'javadoc' archiveClassifier = 'javadoc'
} }
task srcJar(type: Jar) { task srcJar(type: Jar) {
from sourceSets.main.allSource from sourceSets.main.allSource
classifier = 'sources' archiveClassifier = 'sources'
} }
compileJava.dependsOn generateGithubSource compileJava.dependsOn generateGithubSource
@@ -121,7 +129,7 @@ task testBooleans(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
} }
task testBytes(type: Test) { task testBytes(type: Test) {
@@ -133,8 +141,8 @@ task testBytes(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
maxParallelForks = 2 maxParallelForks = testThreads as Integer
} }
task testShorts(type: Test) { task testShorts(type: Test) {
@@ -146,8 +154,8 @@ task testShorts(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
maxParallelForks = 2 maxParallelForks = testThreads as Integer
} }
task testChars(type: Test) { task testChars(type: Test) {
@@ -159,8 +167,8 @@ task testChars(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
maxParallelForks = 2 maxParallelForks = testThreads as Integer
} }
task testInts(type: Test) { task testInts(type: Test) {
@@ -172,8 +180,8 @@ task testInts(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
maxParallelForks = 2 maxParallelForks = testThreads as Integer
} }
task testLongs(type: Test) { task testLongs(type: Test) {
@@ -185,8 +193,8 @@ task testLongs(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
maxParallelForks = 2 maxParallelForks = testThreads as Integer
} }
task testFloats(type: Test) { task testFloats(type: Test) {
@@ -198,8 +206,8 @@ task testFloats(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
maxParallelForks = 2 maxParallelForks = testThreads as Integer
} }
task testDoubles(type: Test) { task testDoubles(type: Test) {
@@ -211,8 +219,8 @@ task testDoubles(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
maxParallelForks = 2 maxParallelForks = testThreads as Integer
} }
task testObjects(type: Test) { task testObjects(type: Test) {
@@ -224,8 +232,8 @@ task testObjects(type: Test) {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
maxParallelForks = 2 maxParallelForks = testThreads as Integer
} }
if(System.getProperty("full_test_suite", "false").toBoolean()) { if(System.getProperty("full_test_suite", "false").toBoolean()) {
@@ -248,15 +256,15 @@ test {
} }
useJUnit() useJUnit()
ignoreFailures = true ignoreFailures = true
maxHeapSize = "1024m" maxHeapSize = maxMemory
} }
jacocoTestReport { jacocoTestReport {
executionData fileTree(project.buildDir.absolutePath).include("jacoco/*.exec") executionData fileTree(project.buildDir.absolutePath).include("jacoco/*.exec")
reports { reports {
xml.enabled true xml.required = true
html.enabled = true html.required = true
csv.enabled true csv.required = true
} }
} }
+3
View File
@@ -1 +1,4 @@
org.gradle.jvmargs=-Xmx3G org.gradle.jvmargs=-Xmx3G
maxMemory = 2048m
testThreads = 4
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
@@ -45,23 +45,19 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
SettingsManager manager = new SettingsManager(); SettingsManager manager = new SettingsManager();
int flags; int flags;
public PrimitiveCollectionsBuilder() public PrimitiveCollectionsBuilder() {
{
this(false); this(false);
} }
public PrimitiveCollectionsBuilder(boolean silencedSuccess) public PrimitiveCollectionsBuilder(boolean silencedSuccess) {
{
super(silencedSuccess, Paths.get("src/builder/resources/speiger/assets/collections/templates/"), Paths.get("src/main/java/speiger/src/collections/"), Paths.get("src/builder/resources/speiger/assets/collections/")); super(silencedSuccess, Paths.get("src/builder/resources/speiger/assets/collections/templates/"), Paths.get("src/main/java/speiger/src/collections/"), Paths.get("src/builder/resources/speiger/assets/collections/"));
} }
public PrimitiveCollectionsBuilder(Path sourceFolder, Path outputFolder, Path dataFolder) public PrimitiveCollectionsBuilder(Path sourceFolder, Path outputFolder, Path dataFolder) {
{
this(false, sourceFolder, outputFolder, dataFolder); this(false, sourceFolder, outputFolder, dataFolder);
} }
public PrimitiveCollectionsBuilder(boolean silencedSuccess, Path sourceFolder, Path outputFolder, Path dataFolder) public PrimitiveCollectionsBuilder(boolean silencedSuccess, Path sourceFolder, Path outputFolder, Path dataFolder) {
{
super(silencedSuccess, sourceFolder, outputFolder, dataFolder); super(silencedSuccess, sourceFolder, outputFolder, dataFolder);
} }
@@ -88,42 +84,24 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
} }
@Override @Override
protected boolean isFileValid(Path fileName) protected boolean isFileValid(Path fileName) { return true; }
{ @Override
return true; protected boolean relativePackages() { return true; }
} @Override
protected boolean debugUnusedMappers() { return false; }
@Override @Override
protected boolean relativePackages() protected void afterFinish() {
{ if((flags & SPECIAL) == 0 && getVersion() > 8) {
return true;
}
@Override
protected boolean debugUnusedMappers()
{
return false;
}
@Override
protected void afterFinish()
{
if((flags & SPECIAL) == 0 && getVersion() > 8)
{
Path basePath = Paths.get("src/main/java"); Path basePath = Paths.get("src/main/java");
try(BufferedWriter writer = Files.newBufferedWriter(basePath.resolve("module-info.java"))) try(BufferedWriter writer = Files.newBufferedWriter(basePath.resolve("module-info.java"))) {
{
writer.write(getModuleInfo(basePath)); writer.write(getModuleInfo(basePath));
} }
catch(Exception e) catch(Exception e) { e.printStackTrace(); }
{
e.printStackTrace();
}
} }
} }
public List<BaseModule> createModules() public List<BaseModule> createModules() {
{
List<BaseModule> modules = new ArrayList<>(); List<BaseModule> modules = new ArrayList<>();
modules.add(JavaModule.INSTANCE); modules.add(JavaModule.INSTANCE);
modules.add(FunctionModule.INSTANCE); modules.add(FunctionModule.INSTANCE);
@@ -139,38 +117,32 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
@Override @Override
protected void init() protected void init() {
{
prepPackages(); prepPackages();
//Init Modules here //Init Modules here
addModules(createModules()); addModules(createModules());
finishPackages(); finishPackages();
} }
public void addModules(List<BaseModule> modules) public void addModules(List<BaseModule> modules) {
{
for(int i = 0,m=modules.size();i<m;i++) { for(int i = 0,m=modules.size();i<m;i++) {
modules.get(i).setManager(manager); modules.get(i).setManager(manager);
} }
manager.resolve();
for(int i = 0,m=modules.size();i<m;i++) { for(int i = 0,m=modules.size();i<m;i++) {
biPackages.forEach(modules.get(i)::init); biPackages.forEach(modules.get(i)::init);
} }
for(int i = 0,m=modules.size();i<m;i++) { modules.forEach(BaseModule::cleanup);
modules.get(i).cleanup();
}
} }
private void finishPackages() private void finishPackages() {
{
biPackages.forEach(ModulePackage::finish); biPackages.forEach(ModulePackage::finish);
if((flags & SAVE) != 0) manager.save(); if((flags & SAVE) != 0) manager.save();
} }
private void prepPackages() private void prepPackages() {
{
if((flags & LOAD) != 0) manager.load(); if((flags & LOAD) != 0) manager.load();
for(ModulePackage entry : ModulePackage.createPackages(globalFlags)) for(ModulePackage entry : ModulePackage.createPackages(globalFlags)) {
{
entry.setRequirements(requirements::put); entry.setRequirements(requirements::put);
biPackages.add(entry); biPackages.add(entry);
if(entry.isSame()) simplePackages.add(entry); if(entry.isSame()) simplePackages.add(entry);
@@ -179,11 +151,9 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
} }
@Override @Override
public void createProcesses(String fileName, Consumer<TemplateProcess> process) public void createProcesses(String fileName, Consumer<TemplateProcess> process) {
{
List<ModulePackage> packages = getPackagesByRequirement(requirements.get(fileName)); List<ModulePackage> packages = getPackagesByRequirement(requirements.get(fileName));
for(int i = 0,m=packages.size();i<m;i++) for(int i = 0,m=packages.size();i<m;i++) {
{
packages.get(i).process(fileName, process); packages.get(i).process(fileName, process);
} }
} }
@@ -197,8 +167,7 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
private String getModuleInfo(Path basePath) { private String getModuleInfo(Path basePath) {
StringJoiner joiner = new StringJoiner("\n", "", "\n"); StringJoiner joiner = new StringJoiner("\n", "", "\n");
try(Stream<Path> stream = Files.walk(getOutputFolder())) try(Stream<Path> stream = Files.walk(getOutputFolder())) {
{
stream.filter(Files::isDirectory) stream.filter(Files::isDirectory)
.filter(this::containsFiles) .filter(this::containsFiles)
.map(basePath::relativize) .map(basePath::relativize)
@@ -206,8 +175,7 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
.map(this::sanitize) .map(this::sanitize)
.forEach(T -> joiner.add("\texports "+T+";")); .forEach(T -> joiner.add("\texports "+T+";"));
} }
catch(Exception e) catch(Exception e) {
{
e.printStackTrace(); e.printStackTrace();
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -218,34 +186,26 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
return builder.toString(); return builder.toString();
} }
private String sanitize(String input) private String sanitize(String input) {
{
return input.replace("\\", ".").replace("/", "."); return input.replace("\\", ".").replace("/", ".");
} }
private boolean containsFiles(Path path) private boolean containsFiles(Path path) {
{ try(Stream<Path> stream = Files.walk(path, 1)) {
try(Stream<Path> stream = Files.walk(path, 1))
{
return stream.filter(Files::isRegularFile).findFirst().isPresent(); return stream.filter(Files::isRegularFile).findFirst().isPresent();
} }
catch(Exception e) catch(Exception e) { e.printStackTrace(); }
{
e.printStackTrace();
}
return false; return false;
} }
private int getVersion() private int getVersion() {
{
String version = System.getProperty("java.version"); String version = System.getProperty("java.version");
if(version.startsWith("1.")) return Integer.parseInt(version.substring(2, 3)); if(version.startsWith("1.")) return Integer.parseInt(version.substring(2, 3));
int dot = version.indexOf("."); int dot = version.indexOf(".");
return Integer.parseInt(dot != -1 ? version.substring(0, dot) : version); return Integer.parseInt(dot != -1 ? version.substring(0, dot) : version);
} }
public static void main(String...args) public static void main(String...args) {
{
try try
{ {
Set<String> flags = new HashSet<>(Arrays.asList(args)); Set<String> flags = new HashSet<>(Arrays.asList(args));
@@ -1,54 +1,100 @@
package speiger.src.builder; package speiger.src.builder;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.internal.Streams; import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.IDependency.LoadingState;
import speiger.src.builder.modules.BaseModule; import speiger.src.builder.modules.BaseModule;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class SettingsManager public class SettingsManager
{ {
boolean loaded; boolean loaded;
Map<String, LoadingState> parsedData = new TreeMap<>();
JsonObject data = new JsonObject(); JsonObject data = new JsonObject();
Set<String> moduleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); Set<String> moduleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
Set<IDependency> allDependencies = new LinkedHashSet<>();
public boolean isModuleEnabled(BaseModule base, ClassType keyType, ClassType valueType) { public void resolve() {
if(!loaded) return true; if(!loaded) return;
if(!isEnabled(data, base.getModuleName())) return false; Set<IDependency> roots = new LinkedHashSet<>();
JsonObject result = getObject(data, keyType.getClassPath(), false); Set<IDependency> leafs = new LinkedHashSet<>();
if(!isEnabled(result, "Enabled")) return false; for(IDependency entry : allDependencies) {
if(base.isBiModule()) { if(entry.isRoot()) {
result = getObject(result, valueType.getClassPath(), false); roots.add(entry);
if(!isEnabled(result, "Enabled")) return false; }
if(entry.isLeaf()) {
leafs.add(entry);
}
}
/**
* This has to be 2 iteration passes.
* Due to Key Value Pairs, first pass does all initials keys, and the second pass processes the values.
* May require more passes but extremely unlikely
*/
for(int i = 0;i<2;i++) {
for(ClassType keyType : ModulePackage.TYPE) {
for(ClassType valueType : ModulePackage.TYPE) {
for(IDependency entry : roots) {
entry.resolveRequirements(keyType, valueType);
}
}
} }
result = getObject(result, base.getModuleName(), false);
return (result.size() <= 0 || isEnabled(result, "Enabled")) && base.areDependenciesLoaded();
} }
public boolean isModuleEnabled(BaseModule base, ClassType keyType, ClassType valueType, String entry) List<String> errors = new ArrayList<>();
{ for(ClassType keyType : ModulePackage.TYPE) {
if(!loaded) return true; for(ClassType valueType : ModulePackage.TYPE) {
if(!isEnabled(data, base.getModuleName())) return false; for(IDependency entry : leafs) {
JsonObject result = getObject(data, keyType.getClassPath(), false); entry.validateDependency(errors::add, keyType, valueType);
if(!isEnabled(result, "Enabled")) return false; }
if(base.isBiModule()) { }
result = getObject(result, valueType.getClassPath(), false); }
if(!isEnabled(result, "Enabled")) return false; if(errors.size() > 0) {
throw new IllegalStateException("Issues with dependencies found: "+String.join("\n", errors));
} }
result = getObject(result, base.getModuleName(), false);
return (result.size() <= 0 || (isEnabled(result, "Enabled") && isEnabled(result, entry))) && base.areDependenciesLoaded();
} }
public void addModule(BaseModule module) { public void addModule(BaseModule module) {
if(loaded) return; if(loaded) {
if(module.isBiModule()) {
for(ClassType keyType : ModulePackage.TYPE) {
for(ClassType valueType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, valueType)) continue;
for(IDependency dependency : module.getDependencies(keyType, valueType)) {
dependency.set(parsedData);
allDependencies.add(dependency);
}
}
}
return;
}
for(ClassType keyType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, keyType)) continue;
for(IDependency dependency : module.getDependencies(keyType, keyType)) {
dependency.set(parsedData);
allDependencies.add(dependency);
}
}
return;
}
String moduleName = module.getModuleName(); String moduleName = module.getModuleName();
moduleNames.add(moduleName); moduleNames.add(moduleName);
data.addProperty(moduleName, true); data.addProperty(moduleName, true);
@@ -57,9 +103,9 @@ public class SettingsManager
for(ClassType valueType : ModulePackage.TYPE) { for(ClassType valueType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, valueType)) continue; if(!module.isModuleValid(keyType, valueType)) continue;
JsonObject obj = new JsonObject(); JsonObject obj = new JsonObject();
obj.addProperty("Enabled", true); for(IDependency dependency : module.getDependencies(keyType, valueType)) {
for(String key : module.getModuleKeys(keyType, valueType)) { String key = dependency.getName();
obj.addProperty(key, true); if(key != null) obj.addProperty(key, true);
} }
addModule(keyType, valueType, true, moduleName, obj); addModule(keyType, valueType, true, moduleName, obj);
} }
@@ -69,18 +115,61 @@ public class SettingsManager
for(ClassType keyType : ModulePackage.TYPE) { for(ClassType keyType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, keyType)) continue; if(!module.isModuleValid(keyType, keyType)) continue;
JsonObject obj = new JsonObject(); JsonObject obj = new JsonObject();
obj.addProperty("Enabled", true); for(IDependency dependency : module.getDependencies(keyType, keyType)) {
for(String key : module.getModuleKeys(keyType, keyType)) { String key = dependency.getName();
obj.addProperty(key, true); if(key != null) obj.addProperty(key, true);
} }
addModule(keyType, keyType, false, moduleName, obj); addModule(keyType, keyType, false, moduleName, obj);
} }
} }
public void printModuleSettings(List<BaseModule> modules) {
JsonObject data = new JsonObject();
for(BaseModule module : modules) {
String moduleName = module.getModuleName();
if(module.isBiModule()) {
for(ClassType keyType : ModulePackage.TYPE) {
for(ClassType valueType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, valueType)) continue;
JsonObject obj = new JsonObject();
for(IDependency dependency : module.getDependencies(keyType, valueType)) {
String key = dependency.getName();
if(key != null) obj.addProperty(key, dependency.isLoaded(keyType, valueType).getJsonResult());
}
addModule(data, keyType, valueType, true, moduleName, obj);
}
}
continue;
}
for(ClassType keyType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, keyType)) continue;
JsonObject obj = new JsonObject();
for(IDependency dependency : module.getDependencies(keyType, keyType)) {
String key = dependency.getName();
if(key != null) obj.addProperty(key, dependency.isLoaded(keyType, keyType).getJsonResult());
}
addModule(data, keyType, keyType, false, moduleName, obj);
}
}
try {
System.out.println();
JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));
writer.setIndent("\t");
Streams.write(data, writer);
writer.flush();
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
public void load() { public void load() {
try(BufferedReader reader = Files.newBufferedReader(Paths.get("ModulSettings.json"))) { try(BufferedReader reader = Files.newBufferedReader(Paths.get("ModulSettings.json"))) {
data = JsonParser.parseReader(reader).getAsJsonObject(); data = JsonParser.parseReader(reader).getAsJsonObject();
loaded = true; loaded = true;
IDependency.flatten("", false, data, parsedData);
JsonElement element = data.get("Default");
LoadingState.setOptionalResolver(LoadingState.of(element == null ? true : element.getAsBoolean()));
} }
catch(Exception e) { e.printStackTrace(); } catch(Exception e) { e.printStackTrace(); }
} }
@@ -100,6 +189,14 @@ public class SettingsManager
catch(Exception e) { e.printStackTrace(); } catch(Exception e) { e.printStackTrace(); }
} }
private void addModule(JsonObject data, ClassType keyType, ClassType valueType, boolean bi, String moduleName, JsonObject obj) {
JsonObject result = getObject(data, keyType.getClassPath(), true);
if(bi) {
result = getObject(result, valueType.getClassPath(), true);
}
result.add(moduleName, obj);
}
private void addModule(ClassType keyType, ClassType valueType, boolean bi, String moduleName, JsonObject obj) { private void addModule(ClassType keyType, ClassType valueType, boolean bi, String moduleName, JsonObject obj) {
JsonObject result = getObject(data, keyType.getClassPath(), true); JsonObject result = getObject(data, keyType.getClassPath(), true);
if(bi) { if(bi) {
@@ -117,9 +214,4 @@ public class SettingsManager
} }
return obj; return obj;
} }
private boolean isEnabled(JsonObject obj, String key) {
if(obj.has(key)) return obj.getAsJsonPrimitive(key).getAsBoolean();
return true;
}
} }
@@ -0,0 +1,137 @@
package speiger.src.builder.dependencies;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeSet;
import java.util.function.Consumer;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.Requirements.Requirement;
@SuppressWarnings("javadoc")
public abstract class BaseDependency implements IDependency {
protected static boolean FETCH_FAILURES = false;
protected static Set<String> FAILURE_KEYS = new TreeSet<>();
protected final String name;
protected final boolean biType;
protected Map<String, LoadingState> dependencies;
protected List<IDependency> children = new ArrayList<>();
protected List<Requirement> requirements = new ArrayList<>();
protected ClassType keyType;
protected ClassType valueType;
public BaseDependency(String name, boolean biType) {
this.name = name;
this.biType = biType;
}
@Override
public String toString() {
return name;
}
@Override
public void set(Map<String, LoadingState> dependency) {
dependencies = dependency;
}
@Override
public IDependency addDependency(Requirement require) {
requirements.add(require);
require.dependency.addChild(this);
return this;
}
@Override
public void addChild(IDependency child) {
children.add(child);
}
@Override
public boolean isLeaf() {
return children.isEmpty();
}
@Override
public boolean isRoot() {
return requirements.isEmpty();
}
protected LoadingState getGlobalState() {
return dependencies.getOrDefault(name, LoadingState.OPTIONAL);
}
@Override
public String getLocalStateKey(ClassType keyType, ClassType valueType) {
return (biType ? keyType.getClassPath()+"-"+valueType.getClassPath() : keyType.getClassPath())+"-"+name;
}
protected LoadingState getLocalState(ClassType keyType, ClassType valueType) {
return dependencies.getOrDefault(getLocalStateKey(keyType, valueType), LoadingState.OPTIONAL);
}
protected LoadingState getReqirementState(ClassType keyType, ClassType valueType) {
LoadingState state = requirements.isEmpty() ? LoadingState.REQUIRED : LoadingState.OPTIONAL;
for(int i = 0,m=requirements.size();i<m;i++) {
state = state.merge(requirements.get(i).test(keyType, valueType));
}
return state.resolveIfUndefined();
}
@Override
public void resolveRequirements(ClassType keyType, ClassType valueType) {
if(!children.isEmpty()) {
for(IDependency child : children) {
if(child == this) continue;
child.resolveRequirements(keyType, valueType);
}
}
if(getLocalState(keyType, valueType) == LoadingState.REQUIRED) {
for(Requirement req : requirements) {
dependencies.putIfAbsent(req.key(keyType, valueType), LoadingState.REQUIRED);
}
}
}
@Override
public void validateDependency(Consumer<String> result, ClassType keyType, ClassType valueType) {
if(getLocalState(keyType, valueType) == LoadingState.REQUIRED) {
FETCH_FAILURES = true;
for(Requirement req : requirements) {
req.test(keyType, valueType);
}
FETCH_FAILURES = false;
if(FAILURE_KEYS.size() > 0) {
int size = FAILURE_KEYS.size();
StringJoiner joiner = new StringJoiner("], [", "[", "]");
FAILURE_KEYS.forEach(joiner::add);
FAILURE_KEYS.clear();
String joins = size > 1 ? "["+joiner.toString()+"]" : joiner.toString();
result.accept("["+getLocalStateKey(keyType, valueType)+"] Requires "+joins+" but it specifically has been disabled!");
}
}
}
@Override
public void set(ClassType key, ClassType value) {
this.keyType = key;
this.valueType = value;
}
@Override
public boolean isEnabled() {
if(keyType == null || keyType == null) return false;
return isLoaded(keyType, valueType).getJsonResult();
}
@Override
public String getName() {
return name;
}
}
@@ -0,0 +1,29 @@
package speiger.src.builder.dependencies;
import speiger.src.builder.ClassType;
@SuppressWarnings("javadoc")
public class FunctionDependency extends BaseDependency {
ModuleDependency owner;
public FunctionDependency(ModuleDependency owner, String name) {
super(name, owner.biType);
this.owner = owner;
}
@Override
public LoadingState isLoaded(ClassType key, ClassType value) {
if(dependencies == null) return LoadingState.REQUIRED;
LoadingState result = getLocalState(key, value);
if(FETCH_FAILURES && result == LoadingState.REJECTED) {
FAILURE_KEYS.add(getLocalStateKey(key, value));
}
return result.resolveIfUndefined().merge(getReqirementState(key, value));
}
@Override
public String getLocalStateKey(ClassType keyType, ClassType valueType) {
return (biType ? keyType.getClassPath()+"-"+valueType.getClassPath() : keyType.getClassPath())+"-"+owner.getName()+"-"+name;
}
}
@@ -0,0 +1,104 @@
package speiger.src.builder.dependencies;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Consumer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.Requirements.Requirement;
@SuppressWarnings("javadoc")
public interface IDependency {
public void set(Map<String, LoadingState> dependency);
public void set(ClassType key, ClassType value);
public LoadingState isLoaded(ClassType key, ClassType value);
public String getLocalStateKey(ClassType keyType, ClassType valueType);
public boolean isEnabled();
public boolean isLeaf();
public boolean isRoot();
public String getName();
public void validateDependency(Consumer<String> result, ClassType keyType, ClassType valueType);
public void resolveRequirements(ClassType keyType, ClassType valueType);
public void addChild(IDependency child);
public <T extends IDependency> T addDependency(Requirement require);
public default <T extends IDependency> T addKeyDependency(IDependency dependency) { return addDependency(new Requirement(dependency, Requirements.KEY_TEST, Requirements.KEY_GETTER)); }
public default <T extends IDependency> T addValueDependency(IDependency dependency) { return addDependency(new Requirement(dependency, Requirements.VALUE_TEST, Requirements.VALUE_GETTER)); }
public default <T extends IDependency> T addEntryDependency(IDependency dependency) { return addDependency(new Requirement(dependency, Requirements.ENTRY_TEST, Requirements.ENTRY_GETTER)); }
public default <T extends IDependency> T addTypeDependency(IDependency dependency, ClassType type) { return addDependency(new Requirement(dependency, Requirements.typedTest(type), Requirements.typedKey(type))); }
public default <T extends IDependency> T addOptionalTypeDependency(IDependency dependency, ClassType type, boolean key) { return addDependency(new Requirement(dependency, Requirements.optionalTest(type, key), Requirements.optionalKey(type, key))); }
public default <T extends IDependency> T addOptionalTypeDependency(ClassType type, boolean key) { return addDependency(new Requirement(this, Requirements.optionalTest(type, key), Requirements.optionalKey(type, key))); }
public static void flatten(String prefix, boolean applyMiddle, JsonObject object, Map<String, LoadingState> result) {
if(applyMiddle) prefix+="-";
for(Entry<String, JsonElement> entry : object.entrySet()) {
String key = entry.getKey();
JsonElement value = entry.getValue();
if(value instanceof JsonPrimitive) {
String entryKey = prefix+key;
if("Enabled".equalsIgnoreCase(key)) {
entryKey = prefix.substring(0, prefix.length()-1);
}
result.put(entryKey, LoadingState.of(((JsonPrimitive)value).getAsBoolean()));
}
if(value instanceof JsonObject) {
flatten(prefix+key, true, (JsonObject)value, result);
}
}
}
public static enum LoadingState {
OPTIONAL,
REQUIRED,
REJECTED;
private static LoadingState RESOLVED = LoadingState.REQUIRED;
public static LoadingState of(boolean value) {
return value ? REQUIRED : REJECTED;
}
public LoadingState merge(LoadingState merge) {
return ordinal() > merge.ordinal() ? this : merge;
}
public LoadingState replaceIfUndefined(LoadingState state) {
return this == OPTIONAL ? state : this;
}
public LoadingState resolveIfUndefined() {
return this == OPTIONAL ? RESOLVED : this;
}
public LoadingState mergeDown(LoadingState merge) {
if(merge == REJECTED || ordinal() > merge.ordinal()) {
return this;
}
return merge;
}
public LoadingState mergeUp(LoadingState merge) {
if(merge == REQUIRED || ordinal() > merge.ordinal()) {
return this;
}
return merge;
}
public static void setOptionalResolver(LoadingState state) {
RESOLVED = state;
}
public boolean getJsonResult() {
LoadingState state = this == OPTIONAL ? RESOLVED : this;
return state == REQUIRED;
}
}
}
@@ -0,0 +1,31 @@
package speiger.src.builder.dependencies;
import speiger.src.builder.ClassType;
import speiger.src.builder.modules.BaseModule;
@SuppressWarnings("javadoc")
public class ModuleDependency extends BaseDependency {
BaseModule owner;
public ModuleDependency(BaseModule owner, boolean biType) {
super(owner.getModuleName(), biType);
this.owner = owner;
}
public FunctionDependency createDependency(String name) {
FunctionDependency result = new FunctionDependency(this, name);
if(biType) result.addEntryDependency(this);
else result.addKeyDependency(this);
return result;
}
@Override
public LoadingState isLoaded(ClassType key, ClassType value) {
if(dependencies == null) return LoadingState.REQUIRED;
LoadingState result = getLocalState(key, value);
if(FETCH_FAILURES && result == LoadingState.REJECTED) {
FAILURE_KEYS.add(getLocalStateKey(key, value));
}
return result.replaceIfUndefined(getGlobalState()).resolveIfUndefined().merge(getReqirementState(key, value));
}
}
@@ -0,0 +1,68 @@
package speiger.src.builder.dependencies;
import java.util.function.Consumer;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.IDependency.LoadingState;
@SuppressWarnings("javadoc")
public class Requirements {
public static final RequirementTest KEY_TEST = (T, K, V) -> T.isLoaded(K, K);
public static final RequirementTest VALUE_TEST = (T, K, V) -> T.isLoaded(V, V);
public static final RequirementTest ENTRY_TEST = (T, K, V) -> T.isLoaded(K, V);
public static RequirementTest typedTest(ClassType type) {
return (T, K, V) -> T.isLoaded(type, type);
}
public static RequirementTest optionalTest(ClassType type, boolean key) {
return (T, K, V) -> (key ? K : V) != type ? T.isLoaded(type, type) : LoadingState.REQUIRED;
}
public static final RequirementKey KEY_GETTER = (T, K, V) -> T.getLocalStateKey(K, K);
public static final RequirementKey VALUE_GETTER = (T, K, V) -> T.getLocalStateKey(V, V);
public static final RequirementKey ENTRY_GETTER = (T, K, V) -> T.getLocalStateKey(K, V);
public static RequirementKey typedKey(ClassType type) {
return (T, K, V) -> T.getLocalStateKey(type, type);
}
public static RequirementKey optionalKey(ClassType type, boolean key) {
return (T, K, V) -> (key ? K : V) != type ? T.getLocalStateKey(type, type) : "";
}
public interface RequirementTest {
public LoadingState test(IDependency test, ClassType keyType, ClassType valueType);
}
public static interface RequirementKey {
public String key(IDependency test, ClassType keyType, ClassType valueType);
}
public static interface RequirementResolver {
public void resolve(IDependency test, Consumer<String> result, ClassType keyType, ClassType valueType);
}
public static class Requirement {
IDependency dependency;
RequirementTest test;
RequirementKey key;
public Requirement(IDependency dependency, RequirementTest test, RequirementKey key) {
this.dependency = dependency;
this.test = test;
this.key = key;
}
public LoadingState test(ClassType keyType, ClassType valueType) {
return test.test(dependency, keyType, valueType);
}
public String key(ClassType keyType, ClassType valueType) {
return key.key(dependency, keyType, valueType);
}
}
}
@@ -1,9 +1,17 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class AsyncModule extends BaseModule public class AsyncModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new AsyncModule(); public static final BaseModule INSTANCE = new AsyncModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(JavaModule.MODULE);
@Override @Override
public String getModuleName() { return "Async"; } public String getModuleName() { return "Async"; }
@@ -16,16 +24,16 @@ public class AsyncModule extends BaseModule
@Override @Override
protected void loadFunctions() {} protected void loadFunctions() {}
@Override @Override
public boolean areDependenciesLoaded() { return isDependencyLoaded(CollectionModule.INSTANCE); } public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE); }
@Override @Override
protected void loadBlockades() { protected void loadBlockades() {
if(!isModuleEnabled()) { if(!MODULE.isEnabled()) {
addBlockedFiles("AsyncBuilder", "Task"); addBlockedFiles("AsyncBuilder", "Task");
} }
} }
@Override @Override
protected void loadFlags() { protected void loadFlags() {
if(isModuleEnabled()) { if(MODULE.isEnabled()) {
addKeyFlag("ASYNC_MODULE"); addKeyFlag("ASYNC_MODULE");
} }
} }
@@ -1,13 +1,15 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.ModulePackage; import speiger.src.builder.ModulePackage;
import speiger.src.builder.RequiredType; import speiger.src.builder.RequiredType;
import speiger.src.builder.SettingsManager; import speiger.src.builder.SettingsManager;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.mappers.ArgumentMapper; import speiger.src.builder.mappers.ArgumentMapper;
import speiger.src.builder.mappers.InjectMapper; import speiger.src.builder.mappers.InjectMapper;
import speiger.src.builder.mappers.LineMapper; import speiger.src.builder.mappers.LineMapper;
@@ -30,6 +32,9 @@ public abstract class BaseModule
this.entry = entry; this.entry = entry;
keyType = entry.getKeyType(); keyType = entry.getKeyType();
valueType = entry.getValueType(); valueType = entry.getValueType();
for(IDependency dependency : getDependencies(keyType, valueType)) {
dependency.set(keyType, valueType);
}
loadVariables(); loadVariables();
loadClasses(); loadClasses();
loadTestClasses(); loadTestClasses();
@@ -56,28 +61,11 @@ public abstract class BaseModule
public abstract String getModuleName(); public abstract String getModuleName();
public boolean isBiModule() { return false; } public boolean isBiModule() { return false; }
public Set<String> getModuleKeys(ClassType keyType, ClassType valueType) { return Collections.emptySet(); } public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Collections.emptyList(); }
public boolean isModuleValid(ClassType keyType, ClassType valueType) { return true; } public boolean isModuleValid(ClassType keyType, ClassType valueType) { return true; }
protected boolean isModuleEnabled() { public ClassType keyType() { return keyType; }
return manager == null || manager.isModuleEnabled(this, keyType, valueType); public ClassType valueType() { return valueType; }
}
protected boolean isModuleEnabled(String name) {
return manager == null || manager.isModuleEnabled(this, keyType, valueType, name);
}
protected boolean isDependencyLoaded(BaseModule module) {
return isDependencyLoaded(module, true);
}
protected boolean isDependencyLoaded(BaseModule module, boolean key) {
return manager == null || (module.isBiModule() ? manager.isModuleEnabled(module, keyType, valueType) : (key ? manager.isModuleEnabled(module, keyType, keyType) : manager.isModuleEnabled(module, valueType, valueType)));
}
public boolean areDependenciesLoaded() {
return true;
}
protected void addFlag(String name) { protected void addFlag(String name) {
entry.addFlag(name); entry.addFlag(name);
@@ -202,4 +190,9 @@ public abstract class BaseModule
entry.addMapper(mapper); entry.addMapper(mapper);
return mapper; return mapper;
} }
public static <T> T make(T input, Consumer<T> processor) {
processor.accept(input);
return input;
}
} }
@@ -1,52 +1,59 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.List;
import java.util.TreeSet;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class CollectionModule extends BaseModule public class CollectionModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new CollectionModule(); public static final BaseModule INSTANCE = new CollectionModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false)
.addKeyDependency(FunctionModule.MODULE)
.addOptionalTypeDependency(FunctionModule.MODULE, ClassType.OBJECT, true)
.addOptionalTypeDependency(FunctionModule.MODULE, ClassType.INT, true)
.addOptionalTypeDependency(ClassType.OBJECT, true);
public static final FunctionDependency STREAMS = MODULE.createDependency("Streams");
public static final FunctionDependency SPLIT_ITERATORS = MODULE.createDependency("Splititerators").addKeyDependency(STREAMS);
public static final FunctionDependency IARRAY = MODULE.createDependency("IArray");
public static final FunctionDependency STRATEGY = MODULE.createDependency("Strategy");
@Override @Override
public String getModuleName() { return "Collection"; } public String getModuleName() { return "Collection"; }
@Override @Override
protected void loadVariables() {} protected void loadVariables() {}
@Override @Override
public boolean areDependenciesLoaded(){ return isDependencyLoaded(JavaModule.INSTANCE); } public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, STREAMS, SPLIT_ITERATORS, IARRAY, STRATEGY); }
@Override
public Set<String> getModuleKeys(ClassType keyType, ClassType valueType)
{
return new TreeSet<>(Arrays.asList("Streams", "Splititerators", "IArray", "Strategy"));
}
@Override @Override
protected void loadFlags() { protected void loadFlags() {
if(isModuleEnabled()) addKeyFlag("COLLECTION_MODULE"); if(MODULE.isEnabled()) addKeyFlag("COLLECTION_MODULE");
if(isModuleEnabled("Streams")) addKeyFlag("STREAM_FEATURE"); if(STREAMS.isEnabled()) addKeyFlag("STREAM_FEATURE");
if(isModuleEnabled("Splititerators")) addKeyFlag("SPLIT_ITERATOR_FEATURE"); if(SPLIT_ITERATORS.isEnabled()) addKeyFlag("SPLIT_ITERATOR_FEATURE");
if(isModuleEnabled("IArray")) addKeyFlag("IARRAY_FEATURE"); if(IARRAY.isEnabled()) addKeyFlag("IARRAY_FEATURE");
} }
@Override @Override
protected void loadBlockades() { protected void loadBlockades() {
if(!isModuleEnabled()) { if(!MODULE.isEnabled()) {
addBlockedFiles("Iterable", "Iterables", "Iterator", "Iterators", "BidirectionalIterator", "ListIterator"); addBlockedFiles("Iterable", "Iterables", "Iterator", "Iterators", "BidirectionalIterator", "ListIterator");
addBlockedFiles("Arrays", "Collection", "AbstractCollection", "Collections", "Stack"); addBlockedFiles("Arrays", "Collection", "OrderedCollection", "AbstractCollection", "Collections", "Stack");
} }
if(!isModuleEnabled("Splititerators")) addBlockedFiles("Splititerator", "Splititerators"); if(!SPLIT_ITERATORS.isEnabled()) addBlockedFiles("Splititerator", "Splititerators");
if(!isModuleEnabled("IArray")) addBlockedFiles("IArray"); if(!IARRAY.isEnabled()) addBlockedFiles("IArray");
if(!isModuleEnabled("Strategy")) addBlockedFiles("Strategy"); if(!STRATEGY.isEnabled()) addBlockedFiles("Strategy");
if(keyType.isObject()) { if(keyType.isObject())
{
addBlockedFiles("Stack"); addBlockedFiles("Stack");
addBlockedFiles("CollectionStreamTester"); addBlockedFiles("CollectionStreamTester");
} }
if(keyType == ClassType.BOOLEAN) { if(keyType == ClassType.BOOLEAN)
{
addBlockedFiles("CollectionRemoveIfTester", "CollectionStreamTester"); addBlockedFiles("CollectionRemoveIfTester", "CollectionStreamTester");
addBlockedFilter(T -> T.endsWith("Tester") && T.startsWith("Iterable")); addBlockedFilter(T -> T.endsWith("Tester") && T.startsWith("Iterable"));
} }
@@ -84,6 +91,7 @@ public class CollectionModule extends BaseModule
{ {
//Abstract Classes //Abstract Classes
addAbstractMapper("ABSTRACT_COLLECTION", "Abstract%sCollection"); addAbstractMapper("ABSTRACT_COLLECTION", "Abstract%sCollection");
addAbstractMapper("REVERSED_ORDERED_COLLECTION", "Reverse%sOrderedCollection");
//Helper Classes //Helper Classes
addClassMapper("ARRAYS", "Arrays"); addClassMapper("ARRAYS", "Arrays");
@@ -94,6 +102,7 @@ public class CollectionModule extends BaseModule
//Interfaces //Interfaces
addClassMapper("COLLECTION", "Collection"); addClassMapper("COLLECTION", "Collection");
addClassMapper("ORDERED_COLLECTION", "OrderedCollection");
addClassMapper("ITERABLE", "Iterable"); addClassMapper("ITERABLE", "Iterable");
addClassMapper("SPLIT_ITERATOR", "Splititerator"); addClassMapper("SPLIT_ITERATOR", "Splititerator");
addClassMapper("LIST_ITERATOR", "ListIterator"); addClassMapper("LIST_ITERATOR", "ListIterator");
@@ -1,12 +1,18 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.RequiredType; import speiger.src.builder.RequiredType;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class FunctionModule extends BaseModule public class FunctionModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new FunctionModule(); public static final BaseModule INSTANCE = new FunctionModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(JavaModule.MODULE);
@Override @Override
public String getModuleName() { return "Function"; } public String getModuleName() { return "Function"; }
@@ -19,10 +25,17 @@ public class FunctionModule extends BaseModule
@Override @Override
protected void loadTestClasses() {} protected void loadTestClasses() {}
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) {
return Arrays.asList(MODULE);
}
@Override @Override
protected void loadBlockades() protected void loadBlockades()
{ {
if(keyType.isObject()) addBlockedFiles("Consumer", "Comparator"); if(keyType.isObject()) addBlockedFiles("Consumer", "Comparator");
if(!MODULE.isEnabled()) addBlockedFiles("Consumer", "BiConsumer", "Comparator", "Supplier", "Optional", "Function", "UnaryOperator");
if(!keyType.needsCustomJDKType()) addBlockedFiles("Optional");
} }
@Override @Override
@@ -48,14 +61,15 @@ public class FunctionModule extends BaseModule
} }
else addBiRequirement("Function"); else addBiRequirement("Function");
addRemapper("BiConsumer", "%sConsumer"); addRemapper("BiConsumer", "%sConsumer");
addRemapper("Optional", "Optional%s");
} }
@Override @Override
protected void loadFunctions() protected void loadFunctions()
{ {
addSimpleMapper("APPLY", keyType.getApply(valueType)); addSimpleMapper("APPLY", keyType.getApply(valueType));
addSimpleMapper("SUPPLY_GET", keyType.isObject() ? "get" : "getAs"+keyType.getCustomJDKType().getNonFileType()); addSimpleMapper("SUPPLY_GET", keyType.isObject() ? "get" : "getAs"+keyType.getNonFileType());
addSimpleMapper("VALUE_SUPPLY_GET", valueType.isObject() ? "get" : "getAs"+valueType.getCustomJDKType().getNonFileType()); addSimpleMapper("VALUE_SUPPLY_GET", valueType.isObject() ? "get" : "getAs"+valueType.getNonFileType());
} }
@Override @Override
@@ -82,6 +96,8 @@ public class FunctionModule extends BaseModule
addFunctionMappers("PREDICATE", "%sPredicate"); addFunctionMappers("PREDICATE", "%sPredicate");
addClassMapper("SUPPLIER", "Supplier"); 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"); addAbstractMapper("SINGLE_UNARY_OPERATOR", "%1$s%1$sUnaryOperator");
addBiClassMapper("UNARY_OPERATOR", "UnaryOperator", ""); addBiClassMapper("UNARY_OPERATOR", "UnaryOperator", "");
if(keyType.isObject()) if(keyType.isObject())
@@ -1,11 +1,17 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class JavaModule extends BaseModule public class JavaModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new JavaModule(); public static final BaseModule INSTANCE = new JavaModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false);
@Override @Override
public String getModuleName() { return "Base"; } public String getModuleName() { return "Base"; }
@@ -17,6 +23,11 @@ public class JavaModule extends BaseModule
loadBaseVariables(); loadBaseVariables();
} }
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) {
return Arrays.asList(MODULE);
}
@Override @Override
protected void loadFlags() protected void loadFlags()
{ {
@@ -49,6 +60,8 @@ public class JavaModule extends BaseModule
addSimpleMapper("APPLY_KEY_VALUE", keyType.isObject() ? "apply" : "applyAs"+keyType.getNonFileType()); addSimpleMapper("APPLY_KEY_VALUE", keyType.isObject() ? "apply" : "applyAs"+keyType.getNonFileType());
addSimpleMapper("APPLY_VALUE", valueType.isObject() ? "apply" : "applyAs"+valueType.getNonFileType()); addSimpleMapper("APPLY_VALUE", valueType.isObject() ? "apply" : "applyAs"+valueType.getNonFileType());
addSimpleMapper("APPLY_CAST", "applyAs"+keyType.getCustomJDKType().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. //Shared by Maps and Pairs so moved to java.
addFunctionMappers("ENTRY_KEY", "get%sKey"); addFunctionMappers("ENTRY_KEY", "get%sKey");
@@ -185,6 +198,7 @@ public class JavaModule extends BaseModule
addComment("@Type", "@param <%s> the keyType of elements maintained by this Collection"); 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("@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"); addValueComment("@ValueType", "@param <%s> the keyType of elements maintained by this Collection");
addSimpleMapper("@Java21", getVersion() >= 21 ? "@Override" : "");
addAnnontion("@PrimitiveOverride", "@Override"); addAnnontion("@PrimitiveOverride", "@Override");
addSimpleMapper("@PrimitiveDoc", ""); addSimpleMapper("@PrimitiveDoc", "");
addAnnontion("@Primitive", "@Deprecated"); addAnnontion("@Primitive", "@Deprecated");
@@ -1,55 +1,57 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.List;
import java.util.TreeSet;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class ListModule extends BaseModule public class ListModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new ListModule(); public static final BaseModule INSTANCE = new ListModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(CollectionModule.MODULE).addKeyDependency(CollectionModule.SPLIT_ITERATORS);
public static final FunctionDependency IMPLEMENTATION = MODULE.createDependency("Implementations");
public static final FunctionDependency WRAPPERS = MODULE.createDependency("Wrappers");
public static final FunctionDependency ARRAY_LIST = MODULE.createDependency("ArrayList").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_LIST = MODULE.createDependency("LinkedList").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency IMMUTABLE_LIST = MODULE.createDependency("ImmutableList").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency COPY_ON_WRITE_LIST = MODULE.createDependency("CopyOnWriteList").addKeyDependency(IMPLEMENTATION);
@Override @Override
public String getModuleName() { return "List"; } public String getModuleName() { return "List"; }
@Override @Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, IMPLEMENTATION, WRAPPERS, ARRAY_LIST, LINKED_LIST, IMMUTABLE_LIST, COPY_ON_WRITE_LIST); }
@Override
protected void loadVariables() {} protected void loadVariables() {}
@Override @Override
protected void loadFlags() { protected void loadFlags() {
if(isModuleEnabled()) addKeyFlag("LIST_MODULE"); if(MODULE.isEnabled()) addKeyFlag("LIST_MODULE");
if(isModuleEnabled("Wrappers")) addKeyFlag("LISTS_FEATURE"); if(WRAPPERS.isEnabled()) addKeyFlag("LISTS_FEATURE");
boolean implementations = isModuleEnabled("Implementations"); if(ARRAY_LIST.isEnabled()) addKeyFlag("ARRAY_LIST_FEATURE");
if(implementations && isModuleEnabled("ArrayList")) addKeyFlag("ARRAY_LIST_FEATURE"); if(LINKED_LIST.isEnabled()) addKeyFlag("LINKED_LIST_FEATURE");
if(implementations && isModuleEnabled("LinkedList")) addKeyFlag("LINKED_LIST_FEATURE"); if(IMMUTABLE_LIST.isEnabled()) addKeyFlag("IMMUTABLE_LIST_FEATURE");
if(implementations && isModuleEnabled("ImmutableList")) addKeyFlag("IMMUTABLE_LIST_FEATURE"); if(COPY_ON_WRITE_LIST.isEnabled()) addKeyFlag("COPY_ON_WRITE_LIST_FEATURE");
if(implementations && isModuleEnabled("CopyOnWriteList")) addKeyFlag("COPY_ON_WRITE_LIST_FEATURE");
} }
@Override @Override
protected void loadBlockades() protected void loadBlockades()
{ {
if(!isModuleEnabled("Wrappers")) addBlockedFiles("Lists"); if(!WRAPPERS.isEnabled()) addBlockedFiles("Lists");
boolean implementations = !isModuleEnabled("Implementations"); if(!ARRAY_LIST.isEnabled()) addBlockedFiles("ArrayList");
if(implementations || !isModuleEnabled("ArrayList")) addBlockedFiles("ArrayList"); if(!LINKED_LIST.isEnabled()) addBlockedFiles("LinkedList");
if(implementations || !isModuleEnabled("LinkedList")) addBlockedFiles("LinkedList"); if(!IMMUTABLE_LIST.isEnabled()) addBlockedFiles("ImmutableList");
if(implementations || !isModuleEnabled("ImmutableList")) addBlockedFiles("ImmutableList"); if(!COPY_ON_WRITE_LIST.isEnabled()) addBlockedFiles("CopyOnWriteList");
if(implementations || !isModuleEnabled("CopyOnWriteList")) addBlockedFiles("CopyOnWriteList"); if(!MODULE.isEnabled()) addBlockedFiles("List", "AbstractList");
if(!isModuleEnabled()) addBlockedFiles("List", "AbstractList");
if(keyType.isObject()) addBlockedFiles("ListFillBufferTester"); if(keyType.isObject()) addBlockedFiles("ListFillBufferTester");
if(keyType == ClassType.BOOLEAN) addBlockedFiles("ListFillBufferTester", "ListReplaceAllTester"); if(keyType == ClassType.BOOLEAN) addBlockedFiles("ListFillBufferTester", "ListReplaceAllTester");
} }
@Override
public Set<String> getModuleKeys(ClassType keyType, ClassType valueType) {
return new TreeSet<>(Arrays.asList("Implementations", "Wrappers", "ArrayList", "LinkedList", "ImmutableList", "CopyOnWriteList"));
}
@Override
public boolean areDependenciesLoaded() {
return isDependencyLoaded(CollectionModule.INSTANCE);
}
@Override @Override
protected void loadRemappers() protected void loadRemappers()
@@ -69,7 +71,10 @@ public class ListModule extends BaseModule
protected void loadFunctions() protected void loadFunctions()
{ {
addFunctionMapper("GET_KEY", "get"); addFunctionMapper("GET_KEY", "get");
addFunctionMapper("REMOVE_LAST", "removeLast"); addFunctionMapper("GET_FIRST_KEY", "getFirst");
addFunctionMapper("GET_LAST_KEY", "getLast");
addFunctionMapper("REMOVE_FIRST_KEY", "removeFirst");
addFunctionMapper("REMOVE_LAST_KEY", "removeLast");
addFunctionMapper("REMOVE_SWAP", "swapRemove"); addFunctionMapper("REMOVE_SWAP", "swapRemove");
addFunctionMappers("REPLACE", keyType.isObject() ? "replaceObjects" : "replace%ss"); addFunctionMappers("REPLACE", keyType.isObject() ? "replaceObjects" : "replace%ss");
addFunctionMappers("SORT", "sort%ss"); addFunctionMappers("SORT", "sort%ss");
@@ -1,15 +1,48 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.List;
import java.util.TreeSet;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class MapModule extends BaseModule public class MapModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new MapModule(); public static final BaseModule INSTANCE = new MapModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, true)
.addKeyDependency(SetModule.MODULE)
.addValueDependency(CollectionModule.MODULE)
.addEntryDependency(SetModule.MODULE)
.addTypeDependency(SetModule.MODULE, ClassType.OBJECT);
public static final FunctionDependency IMPLEMENTATION = MODULE.createDependency("Implementations");
public static final FunctionDependency WRAPPERS = MODULE.createDependency("Wrappers").addKeyDependency(SetModule.WRAPPERS).addOptionalTypeDependency(SetModule.WRAPPERS, ClassType.OBJECT, true);
public static final FunctionDependency ORDERED_MAP = MODULE.createDependency("OrderedMap").addKeyDependency(SetModule.ORDERED_SET).addOptionalTypeDependency(SetModule.ORDERED_SET, ClassType.OBJECT, true);
public static final FunctionDependency SORTED_MAP = MODULE.createDependency("SortedMap").addKeyDependency(SetModule.SORTED_SET).addOptionalTypeDependency(SetModule.SORTED_SET, ClassType.OBJECT, true);
public static final FunctionDependency ARRAY_MAP = MODULE.createDependency("ArrayMap").addEntryDependency(ORDERED_MAP).addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency IMMUTABLE_MAP = MODULE.createDependency("ImmutableMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency HASH_MAP = MODULE.createDependency("HashMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_MAP = MODULE.createDependency("LinkedHashMap").addEntryDependency(HASH_MAP).addEntryDependency(ORDERED_MAP);
public static final FunctionDependency CUSTOM_MAP = MODULE.createDependency("CustomHashMap").addEntryDependency(IMPLEMENTATION).addKeyDependency(CollectionModule.STRATEGY);
public static final FunctionDependency LINKED_CUSTOM_MAP = MODULE.createDependency("LinkedCustomHashMap").addEntryDependency(CUSTOM_MAP).addEntryDependency(ORDERED_MAP);
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);
@Override @Override
public String getModuleName() { return "Map"; } public String getModuleName() { return "Map"; }
@@ -20,79 +53,58 @@ public class MapModule extends BaseModule
@Override @Override
public boolean isModuleValid(ClassType keyType, ClassType valueType) { return keyType != ClassType.BOOLEAN; } public boolean isModuleValid(ClassType keyType, ClassType valueType) { return keyType != ClassType.BOOLEAN; }
@Override @Override
public boolean areDependenciesLoaded() { return isDependencyLoaded(SetModule.INSTANCE) && isDependencyLoaded(CollectionModule.INSTANCE, false); } 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));
@Override if(keyType == ClassType.OBJECT) dependencies.addAll(Arrays.asList(ENUM_MAP, LINKED_ENUM_MAP, REF_MAP, LINKED_REF_MAP));
public Set<String> getModuleKeys(ClassType keyType, ClassType valueType) { return dependencies;
Set<String> sets = new TreeSet<>();
sets.addAll(Arrays.asList("Wrappers", "Implementations"));
sets.addAll(Arrays.asList("OrderedMap", "SortedMap"));
sets.addAll(Arrays.asList("ArrayMap", "ConcurrentMap", "ImmutableMap"));
sets.addAll(Arrays.asList("HashMap", "LinkedHashMap"));
sets.addAll(Arrays.asList("CustomHashMap", "LinkedCustomHashMap"));
sets.addAll(Arrays.asList("EnumMap", "LinkedEnumMap"));
sets.addAll(Arrays.asList("AVLTreeMap", "RBTreeMap"));
return sets;
} }
@Override @Override
protected void loadFlags() protected void loadFlags()
{ {
if(isModuleEnabled()) addFlag("MAP_MODULE"); if(MODULE.isEnabled()) addFlag("MAP_MODULE");
if(isModuleEnabled("Wrappers")) addFlag("MAPS_FEATURE"); if(WRAPPERS.isEnabled()) addFlag("MAPS_FEATURE");
boolean implementations = isModuleEnabled("Implementations"); if(ORDERED_MAP.isEnabled()) addFlag("ORDERED_MAP_FEATURE");
boolean hashMap = implementations && isModuleEnabled("HashMap"); if(ARRAY_MAP.isEnabled()) addFlag("ARRAY_MAP_FEATURE");
boolean customHashMap = implementations && isModuleEnabled("CustomHashMap"); if(LINKED_MAP.isEnabled()) addFlag("LINKED_MAP_FEATURE");
boolean enumMap = implementations && isModuleEnabled("EnumMap"); if(LINKED_CUSTOM_MAP.isEnabled()) addFlag("LINKED_CUSTOM_MAP_FEATURE");
if(LINKED_ENUM_MAP.isEnabled()) addFlag("LINKED_ENUM_MAP_FEATURE");
if(isModuleEnabled("OrderedMap")) { if(SORTED_MAP.isEnabled()) addFlag("SORTED_MAP_FEATURE");
addFlag("ORDERED_MAP_FEATURE"); if(AVL_TREE_MAP.isEnabled()) addFlag("AVL_TREE_MAP_FEATURE");
if(isModuleEnabled("ArrayMap")) addFlag("ARRAY_MAP_FEATURE"); if(RB_TREE_MAP.isEnabled()) addFlag("RB_TREE_MAP_FEATURE");
if(hashMap && isModuleEnabled("LinkedHashMap")) addFlag("LINKED_MAP_FEATURE");
if(customHashMap && isModuleEnabled("LinkedCustomHashMap")) addFlag("LINKED_CUSTOM_MAP_FEATURE"); if(REF_MAP.isEnabled()) addFlag("REF_MAP_FEATURE");
if(enumMap && isModuleEnabled("LinkedEnumMap")) addFlag("LINKED_ENUM_MAP_FEATURE"); if(LINKED_REF_MAP.isEnabled()) addFlag("LINKED_REF_MAP_FEATURE");
}
if(isModuleEnabled("SortedMap")) {
addFlag("SORTED_MAP_FEATURE"); if(CONCURRENT_MAP.isEnabled()) addFlag("CONCURRENT_MAP_FEATURE");
if(implementations && isModuleEnabled("AVLTreeMap")) addFlag("AVL_TREE_MAP_FEATURE"); if(IMMUTABLE_MAP.isEnabled()) addFlag("IMMUTABLE_MAP_FEATURE");
if(implementations && isModuleEnabled("RBTreeMap")) addFlag("RB_TREE_MAP_FEATURE"); if(HASH_MAP.isEnabled()) addFlag("MAP_FEATURE");
} if(CUSTOM_MAP.isEnabled()) addFlag("CUSTOM_MAP_FEATURE");
if(implementations && isModuleEnabled("ConcurrentMap")) addFlag("CONCURRENT_MAP_FEATURE"); if(ENUM_MAP.isEnabled()) addFlag("ENUM_MAP_FEATURE");
if(implementations && isModuleEnabled("ImmutableMap")) addFlag("IMMUTABLE_MAP_FEATURE");
if(hashMap) addFlag("MAP_FEATURE");
if(customHashMap) addFlag("CUSTOM_MAP_FEATURE");
if(enumMap) addFlag("ENUM_MAP_FEATURE");
} }
@Override @Override
protected void loadBlockades() protected void loadBlockades()
{ {
if(!isModuleEnabled()) addBlockedFiles("Map", "AbstractMap"); if(!MODULE.isEnabled()) addBlockedFiles("Map", "AbstractMap");
if(!isModuleEnabled("Wrappers")) addBlockedFiles("Maps"); if(!WRAPPERS.isEnabled()) addBlockedFiles("Maps");
boolean implementations = !isModuleEnabled("Implementations"); if(!IMMUTABLE_MAP.isEnabled()) addBlockedFiles("ImmutableOpenHashMap");
if(implementations || !isModuleEnabled("ImmutableMap")) addBlockedFiles("ImmutableOpenHashMap"); if(!CONCURRENT_MAP.isEnabled()) addBlockedFiles("ConcurrentMap", "ConcurrentOpenHashMap");
if(implementations || !isModuleEnabled("ConcurrentMap")) addBlockedFiles("ConcurrentMap", "ConcurrentOpenHashMap"); if(!ORDERED_MAP.isEnabled()) addBlockedFiles("OrderedMap");
if(!REF_MAP.isEnabled()) addBlockedFiles("ReferenceHashMap");
boolean ordered = !isModuleEnabled("OrderedMap"); if(!LINKED_REF_MAP.isEnabled()) addBlockedFiles("LinkedReferenceHashMap");
if(ordered) addBlockedFiles("OrderedMap"); if(!HASH_MAP.isEnabled()) addBlockedFiles("OpenHashMap");
boolean hashMap = implementations || !isModuleEnabled("HashMap"); if(!LINKED_MAP.isEnabled()) addBlockedFiles("LinkedOpenHashMap");
if(hashMap) addBlockedFiles("OpenHashMap"); if(!CUSTOM_MAP.isEnabled()) addBlockedFiles("OpenCustomHashMap");
if(hashMap || ordered || !isModuleEnabled("LinkedHashMap")) addBlockedFiles("LinkedOpenHashMap"); if(!LINKED_CUSTOM_MAP.isEnabled()) addBlockedFiles("LinkedOpenCustomHashMap");
if(!ENUM_MAP.isEnabled()) addBlockedFiles("EnumMap");
boolean customHashMap = implementations || !isModuleEnabled("CustomHashMap"); if(!LINKED_ENUM_MAP.isEnabled()) addBlockedFiles("LinkedEnumMap");
if(customHashMap) addBlockedFiles("OpenCustomHashMap"); if(!ARRAY_MAP.isEnabled()) addBlockedFiles("ArrayMap");
if(customHashMap || ordered || !isModuleEnabled("LinkedCustomHashMap")) addBlockedFiles("LinkedOpenCustomHashMap"); if(!SORTED_MAP.isEnabled()) addBlockedFiles("SortedMap", "NavigableMap");
if(!AVL_TREE_MAP.isEnabled()) addBlockedFiles("AVLTreeMap");
boolean enumMap = implementations || !isModuleEnabled("EnumMap"); if(!RB_TREE_MAP.isEnabled()) addBlockedFiles("RBTreeMap");
if(enumMap) addBlockedFiles("EnumMap");
if(enumMap || ordered || !isModuleEnabled("LinkedEnumMap")) addBlockedFiles("LinkedEnumMap");
if(ordered || !isModuleEnabled("ArrayMap")) addBlockedFiles("ArrayMap");
boolean sorted = !isModuleEnabled("SortedMap");
if(sorted) addBlockedFiles("SortedMap", "NavigableMap");
if(implementations || sorted || !isModuleEnabled("AVLTreeMap")) addBlockedFiles("AVLTreeMap");
if(implementations || sorted || !isModuleEnabled("RBTreeMap")) addBlockedFiles("RBTreeMap");
if(keyType == ClassType.BOOLEAN) if(keyType == ClassType.BOOLEAN)
{ {
@@ -108,6 +120,9 @@ public class MapModule extends BaseModule
addBlockedFiles("TestOrderedMapGenerator"); addBlockedFiles("TestOrderedMapGenerator");
addBlockedFilter(T -> T.endsWith("Tester") && (T.startsWith("Map") || T.startsWith("OrderedMap") || T.startsWith("SortedMap") || T.startsWith("NavigableMap"))); addBlockedFilter(T -> T.endsWith("Tester") && (T.startsWith("Map") || T.startsWith("OrderedMap") || T.startsWith("SortedMap") || T.startsWith("NavigableMap")));
} }
if(valueType == ClassType.OBJECT) {
addBlockedFiles("MapComputeIfAbsentNonDefaultTester", "MapComputeIfPresentNonDefaultTester", "MapComputeNonDefaultTester", "MapSupplyIfAbsentNonDefaultTester");
}
} }
@Override @Override
@@ -122,6 +137,8 @@ public class MapModule extends BaseModule
addBiRequirement("AbstractMap"); addBiRequirement("AbstractMap");
addEnumRequirement("EnumMap"); addEnumRequirement("EnumMap");
addEnumRequirement("LinkedEnumMap"); addEnumRequirement("LinkedEnumMap");
addEnumRequirement("ReferenceHashMap");
addEnumRequirement("LinkedReferenceHashMap");
addBiRequirement("ConcurrentOpenHashMap"); addBiRequirement("ConcurrentOpenHashMap");
addBiRequirement("ImmutableOpenHashMap"); addBiRequirement("ImmutableOpenHashMap");
addBiRequirement("OpenHashMap"); addBiRequirement("OpenHashMap");
@@ -136,6 +153,8 @@ public class MapModule extends BaseModule
addRemapper("AbstractMap", "Abstract%sMap"); addRemapper("AbstractMap", "Abstract%sMap");
addRemapper("EnumMap", "Enum2%sMap"); addRemapper("EnumMap", "Enum2%sMap");
addRemapper("LinkedEnumMap", "LinkedEnum2%sMap"); addRemapper("LinkedEnumMap", "LinkedEnum2%sMap");
addRemapper("ReferenceHashMap", "Reference2%sHashMap");
addRemapper("LinkedReferenceHashMap", "Reference2%sLinkedHashMap");
addRemapper("ImmutableOpenHashMap", "Immutable%sOpenHashMap"); addRemapper("ImmutableOpenHashMap", "Immutable%sOpenHashMap");
//Test Classes //Test Classes
@@ -158,6 +177,9 @@ public class MapModule extends BaseModule
addBiRequirement("MapComputeIfAbsentTester"); addBiRequirement("MapComputeIfAbsentTester");
addBiRequirement("MapComputeIfPresentTester"); addBiRequirement("MapComputeIfPresentTester");
addBiRequirement("MapComputeTester"); addBiRequirement("MapComputeTester");
addBiRequirement("MapComputeIfAbsentNonDefaultTester");
addBiRequirement("MapComputeIfPresentNonDefaultTester");
addBiRequirement("MapComputeNonDefaultTester");
addBiRequirement("MapCopyTester"); addBiRequirement("MapCopyTester");
addBiRequirement("MapContainsTester"); addBiRequirement("MapContainsTester");
addBiRequirement("MapContainsKeyTester"); addBiRequirement("MapContainsKeyTester");
@@ -184,11 +206,13 @@ public class MapModule extends BaseModule
addBiRequirement("MapReplaceTester"); addBiRequirement("MapReplaceTester");
addBiRequirement("MapSizeTester"); addBiRequirement("MapSizeTester");
addBiRequirement("MapSupplyIfAbsentTester"); addBiRequirement("MapSupplyIfAbsentTester");
addBiRequirement("MapSupplyIfAbsentNonDefaultTester");
addBiRequirement("MapToStringTester"); addBiRequirement("MapToStringTester");
addBiRequirement("NavigableMapNavigationTester"); addBiRequirement("NavigableMapNavigationTester");
addBiRequirement("SortedMapNavigationTester"); addBiRequirement("SortedMapNavigationTester");
addBiRequirement("OrderedMapNavigationTester"); addBiRequirement("OrderedMapNavigationTester");
addBiRequirement("OrderedMapMoveTester"); addBiRequirement("OrderedMapMoveTester");
addBiRequirement("OrderedMapPutTester");
addBiRequirement("MapConstructorTester"); addBiRequirement("MapConstructorTester");
addRemapper("TestMapGenerator", "Test%sMapGenerator"); addRemapper("TestMapGenerator", "Test%sMapGenerator");
@@ -239,11 +263,14 @@ public class MapModule extends BaseModule
addBiClassMapper("RB_TREE_MAP", "RBTreeMap", "2"); addBiClassMapper("RB_TREE_MAP", "RBTreeMap", "2");
addFunctionValueMappers("LINKED_ENUM_MAP", valueType.isObject() ? "LinkedEnum2ObjectMap" : "LinkedEnum2%sMap"); addFunctionValueMappers("LINKED_ENUM_MAP", valueType.isObject() ? "LinkedEnum2ObjectMap" : "LinkedEnum2%sMap");
addFunctionValueMappers("ENUM_MAP", valueType.isObject() ? "Enum2ObjectMap" : "Enum2%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("HASH_MAP", "OpenHashMap", "2");
addBiClassMapper("ARRAY_MAP", "ArrayMap", "2"); addBiClassMapper("ARRAY_MAP", "ArrayMap", "2");
//Abstract Classes //Abstract Classes
addAbstractBiMapper("ABSTRACT_MAP", "Abstract%sMap", "2"); addAbstractBiMapper("ABSTRACT_MAP", "Abstract%sMap", "2");
addAbstractBiMapper("REVERSED_ORDERED_MAP", "Reversed%sOrderedMap", "2");
//Helper Classes //Helper Classes
addBiClassMapper("MAPS", "Maps", "2"); addBiClassMapper("MAPS", "Maps", "2");
@@ -1,15 +1,26 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.List;
import java.util.TreeSet;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class PairModule extends BaseModule public class PairModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new PairModule(); public static final BaseModule INSTANCE = new PairModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, true).addKeyDependency(JavaModule.MODULE);
public static final FunctionDependency IMMUTABLE = MODULE.createDependency("Immutable");
public static final FunctionDependency MUTABLE = MODULE.createDependency("Mutable");
// public static final DependencyModule MODULE = new BiTypeModule(INSTANCE);
// public static final DependencyFunction IMMUTABLE = MODULE.createFunction("Immutable");
// public static final DependencyFunction MUTABLE = MODULE.createFunction("Mutable");
@Override @Override
public String getModuleName() { return "Pair"; } public String getModuleName() { return "Pair"; }
@Override @Override
@@ -21,20 +32,20 @@ public class PairModule extends BaseModule
@Override @Override
protected void loadTestClasses() {} protected void loadTestClasses() {}
@Override @Override
public Set<String> getModuleKeys(ClassType keyType, ClassType valueType) { return new TreeSet<>(Arrays.asList("Mutable", "Immutable")); } public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, IMMUTABLE, MUTABLE); }
@Override @Override
protected void loadFlags() { protected void loadFlags() {
if(isModuleEnabled()) addFlag("PAIR_MODULE"); if(MODULE.isEnabled()) addFlag("PAIR_MODULE");
if(isModuleEnabled("Mutable")) addFlag("MUTABLE_PAIR"); if(MUTABLE.isEnabled()) addFlag("MUTABLE_PAIR");
if(isModuleEnabled("Immutable")) addFlag("IMMUTABLE_PAIR"); if(IMMUTABLE.isEnabled()) addFlag("IMMUTABLE_PAIR");
} }
@Override @Override
protected void loadBlockades() { protected void loadBlockades() {
if(!isModuleEnabled()) addBlockedFiles("Pair"); if(!MODULE.isEnabled()) addBlockedFiles("Pair");
if(!isModuleEnabled("Mutable")) addBlockedFiles("MutablePair"); if(!MUTABLE.isEnabled()) addBlockedFiles("MutablePair");
if(!isModuleEnabled("Immutable")) addBlockedFiles("ImmutablePair"); if(!IMMUTABLE.isEnabled()) addBlockedFiles("ImmutablePair");
} }
@Override @Override
@@ -1,15 +1,26 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.List;
import java.util.TreeSet;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class PrioQueueModule extends BaseModule public class PrioQueueModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new PrioQueueModule(); public static final BaseModule INSTANCE = new PrioQueueModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(CollectionModule.MODULE);
public static final FunctionDependency IMPLEMENTATION = MODULE.createDependency("Implementations");
public static final FunctionDependency WRAPPERS = MODULE.createDependency("Wrappers");
public static final FunctionDependency DEQUEUE = MODULE.createDependency("Dequeue");
public static final FunctionDependency FIFO_QUEUE = MODULE.createDependency("FiFoQueue").addKeyDependency(DEQUEUE).addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency HEAP_QUEUE = MODULE.createDependency("HeapQueue").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency ARRAY_PRIO_QUEUE = MODULE.createDependency("ArrayPrioQueue").addKeyDependency(IMPLEMENTATION);
@Override @Override
public String getModuleName() { return "PriorityQueue"; } public String getModuleName() { return "PriorityQueue"; }
@@ -18,36 +29,26 @@ public class PrioQueueModule extends BaseModule
@Override @Override
protected void loadFunctions() {} protected void loadFunctions() {}
@Override @Override
public boolean areDependenciesLoaded() { return isDependencyLoaded(CollectionModule.INSTANCE); } public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, WRAPPERS, IMPLEMENTATION, DEQUEUE, FIFO_QUEUE, HEAP_QUEUE, ARRAY_PRIO_QUEUE); }
@Override
public Set<String> getModuleKeys(ClassType keyType, ClassType valueType) {
return new TreeSet<>(Arrays.asList("Wrappers", "Implementations", "Dequeue", "FiFoQueue", "HeapQueue", "ArrayPrioQueue"));
}
@Override @Override
protected void loadFlags() { protected void loadFlags() {
if(isModuleEnabled()) addFlag("QUEUE_MODULE"); if(MODULE.isEnabled()) addFlag("QUEUE_MODULE");
if(isModuleEnabled("Wrappers")) addKeyFlag("QUEUES_FEATURE"); if(WRAPPERS.isEnabled()) addKeyFlag("QUEUES_FEATURE");
boolean implementations = isModuleEnabled("Implementations"); if(DEQUEUE.isEnabled()) addKeyFlag("DEQUEUE_FEATURE");
if(isModuleEnabled("Dequeue")) { if(FIFO_QUEUE.isEnabled()) addKeyFlag("FIFO_QUEUE_FEATURE");
addKeyFlag("DEQUEUE_FEATURE"); if(HEAP_QUEUE.isEnabled()) addKeyFlag("HEAP_QUEUE_FEATURE");
if(implementations && isModuleEnabled("FiFoQueue")) addKeyFlag("FIFO_QUEUE_FEATURE"); if(ARRAY_PRIO_QUEUE.isEnabled()) addKeyFlag("ARRAY_QUEUE_FEATURE");
}
if(implementations && isModuleEnabled("HeapQueue")) addKeyFlag("HEAP_QUEUE_FEATURE");
if(implementations && isModuleEnabled("ArrayPrioQueue")) addKeyFlag("ARRAY_QUEUE_FEATURE");
} }
@Override @Override
protected void loadBlockades() { protected void loadBlockades() {
if(!isModuleEnabled()) addBlockedFiles("PriorityQueue", "AbstractPriorityQueue"); if(!MODULE.isEnabled()) addBlockedFiles("PriorityQueue", "AbstractPriorityQueue");
if(!isModuleEnabled("Wrappers")) addBlockedFiles("PriorityQueues"); if(!WRAPPERS.isEnabled()) addBlockedFiles("PriorityQueues");
boolean implementations = !isModuleEnabled("Implementations"); if(!DEQUEUE.isEnabled()) addBlockedFiles("PriorityDequeue");
boolean dequeue = !isModuleEnabled("Dequeue"); if(!FIFO_QUEUE.isEnabled()) addBlockedFiles("ArrayFIFOQueue");
if(dequeue) addBlockedFiles("PriorityDequeue"); if(!HEAP_QUEUE.isEnabled()) addBlockedFiles("HeapPriorityQueue");
if(dequeue || implementations || !isModuleEnabled("FiFoQueue")) addBlockedFiles("ArrayFIFOQueue"); if(!ARRAY_PRIO_QUEUE.isEnabled()) addBlockedFiles("ArrayPriorityQueue");
if(implementations || !isModuleEnabled("HeapQueue")) addBlockedFiles("HeapPriorityQueue");
if(implementations || !isModuleEnabled("ArrayPrioQueue")) addBlockedFiles("ArrayPriorityQueue");
if(keyType == ClassType.BOOLEAN) { if(keyType == ClassType.BOOLEAN) {
addBlockedFiles("QueueTests"); addBlockedFiles("QueueTests");
@@ -1,15 +1,30 @@
package speiger.src.builder.modules; package speiger.src.builder.modules;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.List;
import java.util.TreeSet;
import speiger.src.builder.ClassType; import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class SetModule extends BaseModule public class SetModule extends BaseModule
{ {
public static final BaseModule INSTANCE = new SetModule(); public static final BaseModule INSTANCE = new SetModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(CollectionModule.MODULE).addKeyDependency(CollectionModule.SPLIT_ITERATORS);
public static final FunctionDependency IMPLEMENTATION = MODULE.createDependency("Implementations");
public static final FunctionDependency WRAPPERS = MODULE.createDependency("Wrappers");
public static final FunctionDependency ORDERED_SET = MODULE.createDependency("OrderedSet");
public static final FunctionDependency SORTED_SET = MODULE.createDependency("SortedSet");
public static final FunctionDependency ARRAY_SET = MODULE.createDependency("ArraySet").addKeyDependency(ORDERED_SET).addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency IMMUTABLE_SET = MODULE.createDependency("ImmutableSet").addKeyDependency(ORDERED_SET).addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency HASH_SET = MODULE.createDependency("HashSet").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_SET = MODULE.createDependency("LinkedHashSet").addKeyDependency(ORDERED_SET).addKeyDependency(HASH_SET);
public static final FunctionDependency CUSTOM_SET = MODULE.createDependency("CustomHashSet").addKeyDependency(IMPLEMENTATION).addKeyDependency(CollectionModule.STRATEGY);
public static final FunctionDependency LINKED_CUSTOM_SET = MODULE.createDependency("LinkedCustomHashSet").addKeyDependency(ORDERED_SET).addKeyDependency(CUSTOM_SET);
public static final FunctionDependency AVL_TREE_SET = MODULE.createDependency("AVLTreeSet").addKeyDependency(SORTED_SET).addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency RB_TREE_SET = MODULE.createDependency("RBTreeSet").addKeyDependency(SORTED_SET).addKeyDependency(IMPLEMENTATION);
@Override @Override
public String getModuleName() { return "Set"; } public String getModuleName() { return "Set"; }
@@ -19,68 +34,40 @@ public class SetModule extends BaseModule
@Override @Override
public boolean isModuleValid(ClassType keyType, ClassType valueType) { return keyType != ClassType.BOOLEAN; } public boolean isModuleValid(ClassType keyType, ClassType valueType) { return keyType != ClassType.BOOLEAN; }
@Override @Override
public boolean areDependenciesLoaded() { return isDependencyLoaded(CollectionModule.INSTANCE); } public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, WRAPPERS, ORDERED_SET, SORTED_SET, IMPLEMENTATION, ARRAY_SET, IMMUTABLE_SET, HASH_SET, LINKED_SET, CUSTOM_SET, LINKED_CUSTOM_SET, AVL_TREE_SET, RB_TREE_SET); }
@Override
public Set<String> getModuleKeys(ClassType keyType, ClassType valueType) {
Set<String> sets = new TreeSet<>();
sets.addAll(Arrays.asList("Wrappers", "Implementations"));
sets.addAll(Arrays.asList("OrderedSet", "SortedSet"));
sets.addAll(Arrays.asList("ArraySet", "ImmutableSet"));
sets.addAll(Arrays.asList("HashSet", "LinkedHashSet"));
sets.addAll(Arrays.asList("CustomHashSet", "LinkedCustomHashSet"));
sets.addAll(Arrays.asList("AVLTreeSet", "RBTreeSet"));
return sets;
}
@Override @Override
protected void loadFlags() protected void loadFlags()
{ {
if(isModuleEnabled()) addFlag("SET_MODULE"); if(MODULE.isEnabled()) addFlag("SET_MODULE");
if(isModuleEnabled("Wrappers")) addFlag("SETS_FEATURE"); if(WRAPPERS.isEnabled()) addFlag("SETS_FEATURE");
boolean implementations = isModuleEnabled("Implementations"); if(ORDERED_SET.isEnabled()) addFlag("ORDERED_SET_FEATURE");
boolean hashSet = implementations && isModuleEnabled("HashSet"); if(SORTED_SET.isEnabled()) addFlag("SORTED_SET_FEATURE");
boolean customHashSet = implementations && isModuleEnabled("CustomHashSet"); if(IMMUTABLE_SET.isEnabled()) addFlag("IMMUTABLE_SET_FEATURE");
if(ARRAY_SET.isEnabled()) addFlag("ARRAY_SET_FEATURE");
if(isModuleEnabled("OrderedSet")) { if(HASH_SET.isEnabled()) addFlag("HASH_SET_FEATURE");
addFlag("ORDERED_SET_FEATURE"); if(LINKED_SET.isEnabled()) addFlag("LINKED_SET_FEATURE");
if(implementations && isModuleEnabled("ArraySet")) addFlag("ARRAY_SET_FEATURE"); if(CUSTOM_SET.isEnabled()) addFlag("CUSTOM_HASH_SET_FEATURE");
if(hashSet && isModuleEnabled("LinkedHashSet")) addFlag("LINKED_SET_FEATURE"); if(LINKED_CUSTOM_SET.isEnabled()) addFlag("LINKED_CUSTOM_SET_FEATURE");
if(customHashSet && isModuleEnabled("LinkedCustomHashSet")) addFlag("LINKED_CUSTOM_SET_FEATURE"); if(AVL_TREE_SET.isEnabled()) addFlag("AVL_TREE_SET_FEATURE");
} if(RB_TREE_SET.isEnabled()) addFlag("RB_TREE_SET_FEATURE");
if(isModuleEnabled("SortedSet")) {
addFlag("SORTED_SET_FEATURE");
if(implementations && isModuleEnabled("AVLTreeSet")) addFlag("AVL_TREE_SET_FEATURE");
if(implementations && isModuleEnabled("RBTreeSet")) addFlag("RB_TREE_SET_FEATURE");
}
if(implementations && isModuleEnabled("ImmutableSet")) addFlag("IMMUTABLE_SET_FEATURE");
if(hashSet) addFlag("HASH_SET_FEATURE");
if(customHashSet) addFlag("CUSTOM_HASH_SET_FEATURE");
} }
@Override @Override
protected void loadBlockades() protected void loadBlockades()
{ {
if(!isModuleEnabled()) addBlockedFiles("Set", "AbstractSet"); if(!MODULE.isEnabled()) addBlockedFiles("Set", "AbstractSet");
if(!isModuleEnabled("Wrappers")) addBlockedFiles("Sets"); if(!WRAPPERS.isEnabled()) addBlockedFiles("Sets");
boolean implementations = !isModuleEnabled("Implementations"); if(!IMMUTABLE_SET.isEnabled()) addBlockedFiles("ImmutableOpenHashSet");
if(implementations || !isModuleEnabled("ImmutableSet")) addBlockedFiles("ImmutableOpenHashSet"); if(!ORDERED_SET.isEnabled()) addBlockedFiles("OrderedSet");
if(!HASH_SET.isEnabled()) addBlockedFiles("OpenHashSet");
boolean ordered = !isModuleEnabled("OrderedSet"); if(!LINKED_SET.isEnabled()) addBlockedFiles("LinkedOpenHashSet");
if(ordered) addBlockedFiles("OrderedSet"); if(!CUSTOM_SET.isEnabled()) addBlockedFiles("OpenCustomHashSet");
boolean hashSet = implementations || !isModuleEnabled("HashSet"); if(!LINKED_CUSTOM_SET.isEnabled()) addBlockedFiles("LinkedOpenCustomHashSet");
if(hashSet) addBlockedFiles("OpenHashSet"); if(!ARRAY_SET.isEnabled()) addBlockedFiles("ArraySet");
if(hashSet || ordered || !isModuleEnabled("LinkedHashSet")) addBlockedFiles("LinkedOpenHashSet"); if(!SORTED_SET.isEnabled()) addBlockedFiles("SortedSet", "NavigableSet");
if(!AVL_TREE_SET.isEnabled()) addBlockedFiles("AVLTreeSet");
boolean customHashSet = implementations || !isModuleEnabled("CustomHashSet"); if(!RB_TREE_SET.isEnabled()) addBlockedFiles("RBTreeSet");
if(customHashSet) addBlockedFiles("OpenCustomHashSet");
if(customHashSet || ordered || !isModuleEnabled("LinkedCustomHashSet")) addBlockedFiles("LinkedOpenCustomHashSet");
if(implementations || ordered || !isModuleEnabled("ArraySet")) addBlockedFiles("ArraySet");
boolean sorted = !isModuleEnabled("SortedSet");
if(sorted) addBlockedFiles("SortedSet", "NavigableSet");
if(implementations || sorted || !isModuleEnabled("AVLTreeSet")) addBlockedFiles("AVLTreeSet");
if(implementations || sorted || !isModuleEnabled("RBTreeSet")) addBlockedFiles("RBTreeSet");
if(keyType == ClassType.BOOLEAN) if(keyType == ClassType.BOOLEAN)
{ {
@@ -161,6 +148,7 @@ public class SetModule extends BaseModule
//Abstract Classes //Abstract Classes
addAbstractMapper("ABSTRACT_SET", "Abstract%sSet"); addAbstractMapper("ABSTRACT_SET", "Abstract%sSet");
addAbstractMapper("REVERSED_ORDERED_SET", "Reversed%sOrderedSet");
//Helper Classes //Helper Classes
addClassMapper("SETS", "Sets"); addClassMapper("SETS", "Sets");
@@ -1,17 +1,23 @@
package speiger.src.collections.PACKAGE.collections; package speiger.src.collections.PACKAGE.collections;
import java.util.Collection; import java.util.Collection;
#if ORDERED_MAP_FEATURE
import java.util.function.Supplier;
#endif
import java.util.Objects; import java.util.Objects;
import java.util.AbstractCollection; import java.util.AbstractCollection;
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
#endif #endif
#if ORDERED_MAP_FEATURE
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
/** /**
* Abstract Type Specific Collection that reduces boxing/unboxing * Abstract Type Specific Collection that reduces boxing/unboxing
@@ -262,5 +268,79 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
if (a.length > size()) a[size()] = EMPTY_KEY_VALUE; if (a.length > size()) a[size()] = EMPTY_KEY_VALUE;
return a; 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 #endif
} }
@@ -1,19 +1,11 @@
package speiger.src.collections.PACKAGE.collections; package speiger.src.collections.PACKAGE.collections;
#if !TYPE_OBJECT
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
/**
* A Type-Specific {@link ObjectBidirectionalIterator} to reduce (un)boxing
*/
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, ObjectBidirectionalIterator<CLASS_TYPE>
#else
/** /**
* This is a basically a {@link java.util.ListIterator} without the index functions. * This is a basically a {@link java.util.ListIterator} without the index functions.
* Allowing to have a simple Bidirectional Iterator without having to keep track of the Iteration index. * Allowing to have a simple Bidirectional Iterator without having to keep track of the Iteration index.
* @Type(T) * @Type(T)
*/ */
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE
#endif
{ {
/** /**
* Returns true if the Iterator has a Previous element * Returns true if the Iterator has a Previous element
@@ -29,11 +21,11 @@ public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE
public KEY_TYPE PREVIOUS(); public KEY_TYPE PREVIOUS();
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** {@inheritDoc} /**
* <p>This default implementation delegates to the corresponding type-specific function. * <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead. * @deprecated Please use the corresponding type-specific function instead.
* @return the Previous element of the iterator.+
*/ */
@Override
@Deprecated @Deprecated
public default CLASS_TYPE previous() { public default CLASS_TYPE previous() {
return KEY_TO_OBJ(PREVIOUS()); return KEY_TO_OBJ(PREVIOUS());
@@ -179,6 +179,7 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
/** /**
* A Helper function that simplifies the process of creating a new Array. * A Helper function that simplifies the process of creating a new Array.
* @param action the array creation function * @param action the array creation function
* @param <E> the returning arrayType
* @return an array containing all of the elements in this collection * @return an array containing all of the elements in this collection
* @see Collection#toArray(Object[]) * @see Collection#toArray(Object[])
*/ */
@@ -5,6 +5,9 @@ import java.util.function.Consumer;
#if JDK_FUNCTION #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #endif
#if JDK_TYPE
import java.util.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -16,6 +19,22 @@ import java.util.function.BiFunction;
import java.util.function.IntFunction; import java.util.function.IntFunction;
import java.util.Comparator; import java.util.Comparator;
#if BOOLEAN_COLLECTION_MODULE
import speiger.src.collections.booleans.collections.BooleanIterable;
#endif
#iterate
#argument OUTPUT_ITERABLE ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument MAPPER ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument PACKAGE bytes shorts ints longs floats doubles
#argument FILTER_TYPE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
import speiger.src.collections.objects.functions.function.MAPPER;
import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERABLE;
#endif
#enditerate
#endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; 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.ints.functions.consumer.BI_FROM_INT_CONSUMER;
@@ -165,6 +184,25 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
return ITERABLES.map(this, mapper); return ITERABLES.map(this, mapper);
} }
#if TYPE_OBJECT
#iterate
#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument DATA_TYPE Boolean Byte Short Int Long Float Double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
/**
* A Helper function to reduce the usage of Streams and allows to convert a Iterable to something else.
* @param mapper the mapping function
* @return a new Iterable that returns the desired result
*/
default OUTPUT_ITERABLE mapToDATA_TYPE(MAPPER<T> mapper) {
return ITERABLES.mapToDATA_TYPE(this, mapper);
}
#endif
#enditerate
#endif
/** /**
* A Helper function to reduce the usage of Streams and allows to convert a Iterable to something else. * A Helper function to reduce the usage of Streams and allows to convert a Iterable to something else.
* @param mapper the flatMapping function * @param mapper the flatMapping function
@@ -298,6 +336,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
/** /**
* A Helper function that reduces the usage of streams and allows to collect all elements as a Array * A Helper function that reduces the usage of streams and allows to collect all elements as a Array
* @param action is the creator function of said Array to ensure type is kept. * @param action is the creator function of said Array to ensure type is kept.
* @param <E> the returning arrayType
* @return a new Array of all elements * @return a new Array of all elements
*/ */
default <E> E[] TO_ARRAY(IntFunction<E[]> action) { default <E> E[] TO_ARRAY(IntFunction<E[]> action) {
@@ -375,13 +414,13 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
* @param filter that should be applied * @param filter that should be applied
* @return the found value or the null equivalent variant. * @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); Objects.requireNonNull(filter);
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
KEY_TYPE entry = iter.NEXT(); 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 #if !TYPE_OBJECT
@@ -426,7 +465,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
* @param operator the operation that should be applied * @param operator the operation that should be applied
* @return the reduction result, returns null value if nothing was found * @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -438,7 +477,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
} }
state = operator.APPLY_VALUE(state, iter.NEXT()); 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
}
@@ -1,5 +1,7 @@
package speiger.src.collections.PACKAGE.collections; package speiger.src.collections.PACKAGE.collections;
import java.util.NoSuchElementException;
import speiger.src.collections.utils.Stack; import speiger.src.collections.utils.Stack;
/** /**
@@ -14,6 +16,14 @@ public interface STACK
*/ */
public void push(KEY_TYPE e); public void push(KEY_TYPE e);
/**
* Helper function that pushes the top element on top of the stack again.
* @throws NoSuchElementException if the stack is empty
*/
public default void pushTop() {
push(top());
}
/** /**
* Removes the Object on top of the stack. * Removes the Object on top of the stack.
* @return the element that is on top of the stack * @return the element that is on top of the stack
@@ -59,4 +69,19 @@ public interface STACK
public default boolean isEmpty() { public default boolean isEmpty() {
return size() == 0; return size() == 0;
} }
/**
* A method to drop the contents of the Stack without clearing the stack
* @Type(E)
* @return the contents of the stack into a seperate array.
*/
public default GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY() { return TO_ARRAY(NEW_SPECIAL_KEY_ARRAY(size())); }
/**
* A method to drop the contents of the Stack without clearing the stack
* @param input where the elements should be inserted to. If it does not fit then it creates a new appropiatly created array
* @Type(E)
* @return the contents of the stack into a seperate array.
* @note if the Type is generic then a Object Array is created instead of a Type Array
*/
public GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input);
} }
@@ -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";
}
}
@@ -1,16 +1,25 @@
package speiger.src.collections.PACKAGE.lists; package speiger.src.collections.PACKAGE.lists;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.RandomAccess;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#endif
#if INT_LIST_MODULE && !TYPE_INT
import speiger.src.collections.ints.lists.IntList;
#endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
@@ -66,8 +75,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
*/ */
@Override @Override
@Deprecated @Deprecated
public boolean addAll(Collection<? extends CLASS_TYPE> c) public boolean addAll(Collection<? extends CLASS_TYPE> c) {
{
return c instanceof COLLECTION ? addAll((COLLECTION KEY_GENERIC_TYPE)c) : addAll(size(), c); return c instanceof COLLECTION ? addAll((COLLECTION KEY_GENERIC_TYPE)c) : addAll(size(), c);
} }
@@ -221,6 +229,11 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return new SubList(this, 0, fromIndex, toIndex); return new SubList(this, 0, fromIndex, toIndex);
} }
@Override
public LIST KEY_GENERIC_TYPE reversed() {
return new ReversedList(this);
}
@Override @Override
public ITERATOR KEY_GENERIC_TYPE iterator() { public ITERATOR KEY_GENERIC_TYPE iterator() {
return listIterator(0); return listIterator(0);
@@ -237,6 +250,18 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return new LIST_ITER(index); return new LIST_ITER(index);
} }
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) {
return new IndexedIterator(indecies);
}
#if INT_LIST_MODULE
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) {
return new ListIndexedIterator(indecies);
}
#endif
@Override @Override
public void size(int size) { public void size(int size) {
while(size > size()) add(EMPTY_KEY_VALUE); while(size > size()) add(EMPTY_KEY_VALUE);
@@ -245,6 +270,138 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
public ABSTRACT_LIST KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public ABSTRACT_LIST KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
private class ReversedList extends ABSTRACT_LIST KEY_GENERIC_TYPE
{
final ABSTRACT_LIST KEY_GENERIC_TYPE list;
public ReversedList(ABSTRACT_LIST KEY_GENERIC_TYPE list) {
this.list = list;
}
@Override
public void add(int index, KEY_TYPE e) {
list.add(list.size() - index - 1, e);
}
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
return addCollection(index, c);
}
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
if(c instanceof RandomAccess) {
for(int i = 0,m=c.size();i<m;i++) {
list.add(list.size() - index - i - 1, c.GET_KEY(i));
}
return true;
}
return addCollection(index, c);
}
private boolean addCollection(int index, COLLECTION KEY_GENERIC_TYPE c) {
int i = 0;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();i++) {
list.add(list.size() - index - i - 1, iter.NEXT());
}
return true;
}
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
int i = 0;
for(Iterator<? extends CLASS_TYPE> iter = c.iterator();iter.hasNext();i++) {
list.add(list.size() - index - i - 1, iter.next());
}
return true;
}
@Override
public KEY_TYPE GET_KEY(int index) {
return list.GET_KEY(list.size() - index - 1);
}
@Override
public KEY_TYPE set(int index, KEY_TYPE e) {
return list.set(list.size() - index - 1, e);
}
@Override
public KEY_TYPE REMOVE(int index) {
return list.REMOVE(list.size() - index - 1);
}
@Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
for(int i = 0,m=length;i<m;i++) {
list.add(list.size() - from - i - 1, a[i+offset]);
}
}
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
return reverse(list.getElements(list.size() - from - 1, a, offset, length));
}
@Override
public void removeElements(int from, int to) {
list.removeElements(list.size() - to - 1, list.size() - from - 1);
}
@Override
public KEY_TYPE swapRemove(int index) {
return list.swapRemove(list.size() - index - 1);
}
#if TYPE_OBJECT
@Override
public <K> K[] extractElements(int from, int to, Class<K> type) {
return reverse(list.extractElements(list.size() - to - 1, list.size() - from - 1, type));
}
#else
@Override
public KEY_TYPE[] extractElements(int from, int to) {
return reverse(list.extractElements(list.size() - to - 1, list.size() - from - 1));
}
#endif
@Override
public int size() {
return list.size();
}
@Override
public void clear() {
list.clear();
}
@Override
public LIST KEY_GENERIC_TYPE reversed() {
return list;
}
#if TYPE_OBJECT
private <K> K[] reverse(K[] data) {
for (int i = 0, mid = data.length >> 1, j = data.length - 1; i < mid; i++, j--) {
K t = data[i];
data[i] = data[j];
data[j] = t;
}
return data;
}
#else
private KEY_TYPE[] reverse(KEY_TYPE[] data) {
for (int i = 0, mid = data.length >> 1, j = data.length - 1; i < mid; i++, j--) {
KEY_TYPE t = data[i];
data[i] = data[j];
data[j] = t;
}
return data;
}
#endif
}
private class SubList extends ABSTRACT_LIST KEY_GENERIC_TYPE private class SubList extends ABSTRACT_LIST KEY_GENERIC_TYPE
{ {
final ABSTRACT_LIST KEY_GENERIC_TYPE list; final ABSTRACT_LIST KEY_GENERIC_TYPE list;
@@ -379,9 +536,10 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
public int size() { public int size() {
return size; return size;
} }
#if SPLIT_ITERATOR_FEATURE
@Override @Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 16464); } public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 16464); }
#endif
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) { public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
@@ -491,6 +649,154 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
} }
} }
#if INT_LIST_MODULE
private class ListIndexedIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
IntList indecies;
int index;
int lastReturned = -1;
ListIndexedIterator(IntList indecies) {
this.indecies = indecies;
}
@Override
public boolean hasNext() {
return index < indecies.size();
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
int i = index++;
return GET_KEY((lastReturned = indecies.getInt(i)));
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
index--;
return GET_KEY((lastReturned = indecies.getInt(index)));
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index-1;
}
@Override
public void remove() { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void set(KEY_TYPE e) {
if(lastReturned == -1) throw new IllegalStateException();
ABSTRACT_LIST.this.set(lastReturned, e);
}
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, indecies.size() - index);
index += steps;
if(steps > 0) lastReturned = Math.min(index-1, indecies.size()-1);
return steps;
}
@Override
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index);
index -= steps;
if(steps > 0) lastReturned = Math.max(index, 0);
return steps;
}
}
#endif
private class IndexedIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
int[] indecies;
int index;
int lastReturned = -1;
IndexedIterator(int[] indecies) {
this.indecies = indecies;
}
@Override
public boolean hasNext() {
return index < indecies.length;
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
int i = index++;
return GET_KEY((lastReturned = indecies[i]));
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
index--;
return GET_KEY((lastReturned = indecies[index]));
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index-1;
}
@Override
public void remove() { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void set(KEY_TYPE e) {
if(lastReturned == -1) throw new IllegalStateException();
ABSTRACT_LIST.this.set(lastReturned, e);
}
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, indecies.length - index);
index += steps;
if(steps > 0) lastReturned = Math.min(index-1, indecies.length-1);
return steps;
}
@Override
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index);
index -= steps;
if(steps > 0) lastReturned = Math.max(index, 0);
return steps;
}
}
private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE { private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index; int index;
int lastReturned = -1; int lastReturned = -1;
@@ -568,7 +874,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index); int steps = Math.min(amount, index);
index -= steps; index -= steps;
if(steps > 0) lastReturned = Math.min(index, size()-1); if(steps > 0) lastReturned = Math.max(index, 0);
return steps; return steps;
} }
} }
@@ -7,12 +7,23 @@ import java.util.Comparator;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects; 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 TYPE_OBJECT
#if IARRAY_FEATURE || TYPE_OBJECT #if IARRAY_FEATURE || TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
#endif #endif
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.IntFunction;
#endif #endif
#if !TYPE_OBJECT && JDK_FUNCTION #if !TYPE_OBJECT && JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
@@ -32,6 +43,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.STACK; import speiger.src.collections.PACKAGE.collections.STACK;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -41,7 +55,9 @@ import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUME
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
import speiger.src.collections.objects.utils.ObjectArrays; import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -216,6 +232,42 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return list; 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 #endif
/** /**
* Appends the specified element to the end of this list. * Appends the specified element to the end of this list.
@@ -679,12 +731,12 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { 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 #if !TYPE_OBJECT
@@ -711,7 +763,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -723,7 +775,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
state = operator.APPLY_VALUE(state, data[i]); state = operator.APPLY_VALUE(state, data[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
@@ -1078,6 +1130,12 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return a; return a;
} }
#else
@Override
public <E> E[] toArray(IntFunction<E[]> action) {
return super.toArray(action);
}
#endif #endif
/** /**
* A function to return the size of the list * A function to return the size of the list
@@ -8,11 +8,21 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; 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.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.IntFunction;
#endif #endif
#if !TYPE_OBJECT && JDK_FUNCTION #if !TYPE_OBJECT && JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
@@ -32,6 +42,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.STACK; import speiger.src.collections.PACKAGE.collections.STACK;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -41,7 +54,9 @@ import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUME
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
import speiger.src.collections.objects.utils.ObjectArrays; import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -163,7 +178,42 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
} }
#endif #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) { private void setArray(KEY_TYPE[] data) {
this.data = data; this.data = data;
} }
@@ -532,7 +582,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
* @return if the element was found. * @return if the element was found.
*/ */
@Override @Override
@Deprecated @Primitive
public boolean contains(Object o) { public boolean contains(Object o) {
return indexOf(o) != -1; return indexOf(o) != -1;
} }
@@ -543,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) * @return the index of the element if found. (if not found then -1)
*/ */
@Override @Override
@Deprecated @Primitive
public int indexOf(Object o) { public int indexOf(Object o) {
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -567,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) * @return the last index of the element if found. (if not found then -1)
*/ */
@Override @Override
@Deprecated @Primitive
public int lastIndexOf(Object o) { public int lastIndexOf(Object o) {
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -807,13 +857,13 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
for(int i = 0,m=data.length;i<m;i++) { 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 #if !TYPE_OBJECT
@@ -842,7 +892,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
@@ -855,7 +905,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
} }
state = operator.APPLY_VALUE(state, data[i]); state = operator.APPLY_VALUE(state, data[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
@@ -1329,6 +1379,11 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
if (a.length > size) a[size] = EMPTY_KEY_VALUE; if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a; return a;
} }
#else
@Override
public <E> E[] toArray(IntFunction<E[]> action) {
return super.toArray(action);
}
#endif #endif
@@ -3,10 +3,26 @@ package speiger.src.collections.PACKAGE.lists;
import java.util.Arrays; import java.util.Arrays;
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.Comparator; import java.util.Comparator;
#else if !TYPE_BOOLEAN
import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport;
#endif #endif
import java.util.Collection; import java.util.Collection;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; 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 #if TYPE_OBJECT
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -20,6 +36,7 @@ import java.util.function.PREDICATE;
#if !JDK_FUNCTION #if !JDK_FUNCTION
import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_PREDICATE;
#endif #endif
import java.util.function.JAVA_UNARY_OPERATOR; import java.util.function.JAVA_UNARY_OPERATOR;
#endif #endif
@@ -27,6 +44,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; 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; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif #endif
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; 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.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.objects.utils.ObjectArrays; import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.utils.ITERATORS; 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 #if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; 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); 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 @Override
public boolean add(KEY_TYPE e) { throw new UnsupportedOperationException(); } public boolean add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -335,12 +387,12 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0,m=data.length;i<m;i++) { 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 #if !TYPE_OBJECT
@@ -367,7 +419,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; 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]); state = operator.APPLY_VALUE(state, data[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
@@ -4,7 +4,6 @@ package speiger.src.collections.PACKAGE.lists;
#if DEQUEUE_FEATURE #if DEQUEUE_FEATURE
import java.util.Comparator; import java.util.Comparator;
#endif #endif
import java.util.function.BiFunction; import java.util.function.BiFunction;
#else if PRIMITIVES #else if PRIMITIVES
import java.nio.JAVA_BUFFER; import java.nio.JAVA_BUFFER;
@@ -12,12 +11,23 @@ import java.nio.JAVA_BUFFER;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects; 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; import java.util.NoSuchElementException;
#if SPLIT_ITERATOR_FEATURE
import java.util.Spliterator; import java.util.Spliterator;
#if PRIMITIVES #if PRIMITIVES
import java.util.Spliterator.JAVA_SPLIT_ITERATOR; import java.util.Spliterator.JAVA_SPLIT_ITERATOR;
#endif #endif
import java.util.function.Consumer; import java.util.function.Consumer;
#endif
import java.util.function.Predicate; import java.util.function.Predicate;
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.function.IntFunction; import java.util.function.IntFunction;
@@ -32,6 +42,9 @@ import java.util.function.JAVA_PREDICATE;
#endif #endif
import java.util.function.JAVA_UNARY_OPERATOR; import java.util.function.JAVA_UNARY_OPERATOR;
#endif #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.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION #if !JDK_FUNCTION
@@ -53,17 +66,21 @@ import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
import speiger.src.collections.objects.utils.ObjectArrays; import speiger.src.collections.objects.utils.ObjectArrays;
#if TYPE_OBJECT #if TYPE_OBJECT
import speiger.src.collections.utils.Stack; import speiger.src.collections.utils.Stack;
#endif #endif
#if SPLIT_ITERATOR_FEATURE
#if PRIMITIVES #if PRIMITIVES
import java.util.stream.JAVA_STREAM; import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
#endif #endif
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
@@ -149,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++])); 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 @Override
public boolean add(KEY_TYPE e) { public boolean add(KEY_TYPE e) {
add(size(), e); add(size(), e);
@@ -312,21 +365,43 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#if DEQUEUE_FEATURE #if DEQUEUE_FEATURE
@Override @Override
public KEY_TYPE first() { public KEY_TYPE first() {
return GET_FIRST_KEY();
}
@Override
public KEY_TYPE last() {
return GET_LAST_KEY();
}
#endif
@Override
public KEY_TYPE GET_FIRST_KEY() {
if(first == null) throw new NoSuchElementException(); if(first == null) throw new NoSuchElementException();
return first.value; return first.value;
} }
@Override @Override
public KEY_TYPE last() { public KEY_TYPE GET_LAST_KEY() {
if(last == null) throw new NoSuchElementException(); if(last == null) throw new NoSuchElementException();
return last.value; return last.value;
} }
#endif @Override
public KEY_TYPE REMOVE_FIRST_KEY() {
if(first == null) throw new NoSuchElementException();
return unlinkFirst(first);
}
@Override
public KEY_TYPE REMOVE_LAST_KEY() {
return pop();
}
@Override @Override
public KEY_TYPE peek(int index) { public KEY_TYPE peek(int index) {
return GET_KEY((size() - 1) - index); return GET_KEY((size() - 1) - index);
} }
@Override @Override
public KEY_TYPE GET_KEY(int index) { public KEY_TYPE GET_KEY(int index) {
checkRange(index); checkRange(index);
@@ -392,6 +467,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return new ListIter(getNode(index), index); return new ListIter(getNode(index), index);
} }
#if SPLIT_ITERATOR_FEATURE
#if PRIMITIVES #if PRIMITIVES
/** /**
* Returns a Java-Type-Specific Stream to reduce boxing/unboxing. * Returns a Java-Type-Specific Stream to reduce boxing/unboxing.
@@ -412,6 +488,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override @Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return new TypeSplitIteratorBRACES(this, first, 0); } public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return new TypeSplitIteratorBRACES(this, first, 0); }
#endif
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -463,12 +540,12 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) { 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 #if !TYPE_OBJECT
@@ -495,7 +572,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -507,7 +584,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
state = operator.APPLY_VALUE(state, entry.value); state = operator.APPLY_VALUE(state, entry.value);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
@@ -1144,8 +1221,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
Entry KEY_GENERIC_TYPE prev; Entry KEY_GENERIC_TYPE prev;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
public Entry(KEY_TYPE value, Entry KEY_GENERIC_TYPE prev, Entry KEY_GENERIC_TYPE next) public Entry(KEY_TYPE value, Entry KEY_GENERIC_TYPE prev, Entry KEY_GENERIC_TYPE next) {
{
this.value = value; this.value = value;
this.prev = prev; this.prev = prev;
this.next = next; this.next = next;
@@ -1230,6 +1306,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
} }
#if SPLIT_ITERATOR_FEATURE
private static class TypeSplitIterator KEY_GENERIC_TYPE implements SPLIT_ITERATOR KEY_GENERIC_TYPE private static class TypeSplitIterator KEY_GENERIC_TYPE implements SPLIT_ITERATOR KEY_GENERIC_TYPE
{ {
static final int BATCH_UNIT = 1 << 10; static final int BATCH_UNIT = 1 << 10;
@@ -1374,4 +1451,5 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
} }
#endif #endif
#endif
} }
@@ -15,7 +15,10 @@ import java.util.function.UnaryOperator;
#endif #endif
import speiger.src.collections.PACKAGE.collections.COLLECTION; 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; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
@@ -24,7 +27,12 @@ import speiger.src.collections.PACKAGE.utils.ARRAYS;
#if LISTS_FEATURE #if LISTS_FEATURE
import speiger.src.collections.PACKAGE.utils.LISTS; import speiger.src.collections.PACKAGE.utils.LISTS;
#endif #endif
#if INT_LIST_MODULE && !TYPE_INT
import speiger.src.collections.ints.lists.IntList;
#endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT #if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
#endif #endif
@@ -33,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 * A Type Specific List interface that reduces boxing/unboxing and adds a couple extra quality of life features
* @Type(T) * @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 #if !TYPE_OBJECT
/** /**
@@ -98,6 +106,64 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
*/ */
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c); 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.
* This simplifies this process a bit.
* @return first element of the list
*/
public default KEY_TYPE GET_FIRST_KEY() {
return GET_KEY(0);
}
/**
* Helper method that returns the last element of a List.
* This function was introduced due to how annoying it is to get/remove the last element of a list.
* This simplifies this process a bit.
* @return last element of the list
*/
public default KEY_TYPE GET_LAST_KEY() {
return GET_KEY(size() - 1);
}
/**
* Helper method that removes and 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.
* This simplifies this process a bit.
* @return first element of the list and removes it
*/
public default KEY_TYPE REMOVE_FIRST_KEY() {
return REMOVE(0);
}
/**
* Helper method that removes and returns the last element of a List.
* This function was introduced due to how annoying it is to get/remove the last element of a list.
* This simplifies this process a bit.
* @return last element of the list and removes it
*/
public default KEY_TYPE REMOVE_LAST_KEY() {
return REMOVE(size() - 1);
}
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** /**
* A Type-Specific get function to reduce (un)boxing * A Type-Specific get function to reduce (un)boxing
@@ -385,6 +451,26 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index); public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index);
/**
* Creates a Iterator that follows the indecies provided.<br>
* For example if the Lists Contents is:<br> -1, 0 1 <br>and the indecies are: <br>0, 1, 2, 2, 1, 0<br>
* then the iterator will return the following values: <br>-1, 0, 1, 1, 0, -1
* @param indecies that should be used for the iteration.
* @return a custom indexed iterator
*/
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies);
#if INT_LIST_MODULE
/**
* Creates a Iterator that follows the indecies provided.<br>
* For example if the Lists Contents is:<br> -1, 0 1 <br>and the indecies are: <br>0, 1, 2, 2, 1, 0<br>
* then the iterator will return the following values: <br>-1, 0, 1, 1, 0, -1
* @param indecies that should be used for the iteration.
* @return a custom indexed iterator
*/
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies);
#endif
/** /**
* A Type-Specific List of subList * A Type-Specific List of subList
* @see java.util.List#subList(int, int) * @see java.util.List#subList(int, int)
@@ -392,6 +478,12 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
@Override @Override
public LIST KEY_GENERIC_TYPE subList(int from, int to); public LIST KEY_GENERIC_TYPE subList(int from, int to);
/**
* A Type-Specific List Helper that shows all elements in reverse.
* @return a list wrapper that has all elements reversed!
*/
public LIST KEY_GENERIC_TYPE reversed();
#if LISTS_FEATURE #if LISTS_FEATURE
/** /**
* Creates a Wrapped List that is Synchronized * Creates a Wrapped List that is Synchronized
@@ -435,9 +527,56 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
@Override @Override
@Deprecated @Deprecated
public default boolean add(CLASS_TYPE e) { 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} /** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function. * <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead. * @deprecated Please use the corresponding type-specific function instead.
@@ -485,7 +624,7 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
@Override @Override
@Deprecated @Deprecated
public default boolean contains(Object o) { public default boolean contains(Object o) {
return COLLECTION.super.contains(o); return ORDERED_COLLECTION.super.contains(o);
} }
/** {@inheritDoc} /** {@inheritDoc}
@@ -495,7 +634,7 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
@Override @Override
@Deprecated @Deprecated
public default boolean remove(Object o) { public default boolean remove(Object o) {
return COLLECTION.super.remove(o); return ORDERED_COLLECTION.super.remove(o);
} }
/** {@inheritDoc} /** {@inheritDoc}
@@ -525,10 +664,12 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
} }
#endif #endif
#endif #endif
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
*/ */
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
} }
@@ -14,6 +14,15 @@ import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; 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.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SET;
#if MAPS_FEATURE #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 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 @Override
public VALUE_TYPE getDefaultReturnValue() { 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) { public void putAll(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, int offset, int size) {
SanityChecks.checkArrayCapacity(keys.length, offset, size); SanityChecks.checkArrayCapacity(keys.length, offset, size);
SanityChecks.checkArrayCapacity(values.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 #endif
@@ -201,6 +210,96 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
@Override @Override
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
#if !VALUE_OBJECT
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, GET_VALUE(key));
#else
VALUE_TYPE value = GET_VALUE(key);
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(VALUE_EQUALS_NOT(value, getDefaultReturnValue()) || containsKey(key)) {
remove(key);
return getDefaultReturnValue();
}
return getDefaultReturnValue();
}
#endif
put(key, newValue);
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if VALUE_OBJECT
VALUE_TYPE value;
if((value = GET_VALUE(key)) == getDefaultReturnValue() || !containsKey(key)) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) {
put(key, newValue);
return newValue;
}
}
return value;
#else
if(!containsKey(key)) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
put(key, newValue);
return newValue;
}
return get(key);
#endif
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
#if VALUE_OBJECT
VALUE_TYPE value;
if((value = GET_VALUE(key)) == getDefaultReturnValue() || !containsKey(key)) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) {
put(key, newValue);
return newValue;
}
}
return value;
#else
if(!containsKey(key)) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
put(key, newValue);
return newValue;
}
return get(key);
#endif
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if VALUE_OBJECT
VALUE_TYPE value;
if(VALUE_EQUALS_NOT((value = GET_VALUE(key)), getDefaultReturnValue()) || containsKey(key)) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, value);
if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) {
put(key, newValue);
return newValue;
}
remove(key);
}
#else
if(containsKey(key)) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, GET_VALUE(key));
put(key, newValue);
return newValue;
}
#endif
return getDefaultReturnValue();
}
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
VALUE_TYPE value = GET_VALUE(key); VALUE_TYPE value = GET_VALUE(key);
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, value); VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
@@ -215,7 +314,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
VALUE_TYPE value; VALUE_TYPE value;
if((value = GET_VALUE(key)) == getDefaultReturnValue() || !containsKey(key)) { if((value = GET_VALUE(key)) == getDefaultReturnValue() || !containsKey(key)) {
@@ -229,7 +328,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
} }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider); Objects.requireNonNull(valueProvider);
VALUE_TYPE value; VALUE_TYPE value;
if((value = GET_VALUE(key)) == getDefaultReturnValue() || !containsKey(key)) { if((value = GET_VALUE(key)) == getDefaultReturnValue() || !containsKey(key)) {
@@ -243,7 +342,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
VALUE_TYPE value; VALUE_TYPE value;
if(VALUE_EQUALS_NOT((value = GET_VALUE(key)), getDefaultReturnValue()) || containsKey(key)) { if(VALUE_EQUALS_NOT((value = GET_VALUE(key)), getDefaultReturnValue()) || containsKey(key)) {
@@ -257,6 +356,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
return getDefaultReturnValue(); return getDefaultReturnValue();
} }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -452,6 +552,132 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
return hash; 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 * A Simple Type Specific Entry class to reduce boxing/unboxing
* @Type(T) * @Type(T)
@@ -4,15 +4,18 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.locks.StampedLock; import java.util.concurrent.locks.StampedLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -27,10 +30,12 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE #if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif #endif
@@ -38,9 +43,12 @@ import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif #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; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; 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;
import speiger.src.collections.PACKAGE.maps.interfaces.CONCURRENT_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.CONCURRENT_MAP;
@@ -76,6 +84,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif #endif
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
#if VALUE_OBJECT #if VALUE_OBJECT
@@ -537,6 +546,36 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
return getSegment(hash).computeIfPresent(hash, key, mappingFunction); return getSegment(hash).computeIfPresent(hash, key, mappingFunction);
} }
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int hash = getHashCode(key);
return getSegment(hash).computeNonDefault(hash, key, mappingFunction);
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int hash = getHashCode(key);
return getSegment(hash).computeIfAbsentNonDefault(hash, key, mappingFunction);
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
int hash = getHashCode(key);
return getSegment(hash).supplyIfAbsentNonDefault(hash, key, valueProvider);
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int hash = getHashCode(key);
return getSegment(hash).computeIfPresentNonDefault(hash, key, mappingFunction);
}
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -650,7 +689,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
action.accept(new BasicEntryKV_BRACES(seg.keys[index], seg.values[index])); action.accept(new ValueMapEntry(index, i));
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -662,14 +701,14 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
@Override @Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0,m=segments.length;i<m;i++) { for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i]; Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock(); long stamp = seg.readLock();
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
entry.set(seg.keys[index], seg.values[index]); entry.set(index, i);
action.accept(entry); action.accept(entry);
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
@@ -690,7 +729,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
action.accept(count++, new BasicEntryKV_BRACES(seg.keys[index], seg.values[index])); action.accept(count++, new ValueMapEntry(index, i));
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -709,7 +748,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
action.accept(input, new BasicEntryKV_BRACES(seg.keys[index], seg.values[index])); action.accept(input, new ValueMapEntry(index, i));
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -722,14 +761,14 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
@Override @Override
public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0,m=segments.length;i<m;i++) { for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i]; Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock(); long stamp = seg.readLock();
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
entry.set(seg.keys[index], seg.values[index]); entry.set(index, i);
if(filter.test(entry)) return true; if(filter.test(entry)) return true;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
@@ -744,14 +783,14 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
@Override @Override
public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0,m=segments.length;i<m;i++) { for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i]; Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock(); long stamp = seg.readLock();
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
entry.set(seg.keys[index], seg.values[index]); entry.set(index, i);
if(filter.test(entry)) return false; if(filter.test(entry)) return false;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
@@ -766,14 +805,14 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
@Override @Override
public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0,m=segments.length;i<m;i++) { for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i]; Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock(); long stamp = seg.readLock();
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
entry.set(seg.keys[index], seg.values[index]); entry.set(index, i);
if(!filter.test(entry)) return false; if(!filter.test(entry)) return false;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
@@ -795,7 +834,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
state = operator.apply(state, new BasicEntryKV_BRACES(seg.keys[index], seg.values[index])); state = operator.apply(state, new ValueMapEntry(index, i));
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -807,7 +846,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
@@ -819,11 +858,11 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
while(index != -1) { while(index != -1) {
if(empty) { if(empty) {
empty = false; empty = false;
state = new BasicEntryKV_BRACES(seg.keys[index], seg.values[index]); state = new ValueMapEntry(index, i);
index = (int)seg.links[index]; index = (int)seg.links[index];
continue; continue;
} }
state = operator.apply(state, new BasicEntryKV_BRACES(seg.keys[index], seg.values[index])); state = operator.apply(state, new ValueMapEntry(index, i));
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -831,21 +870,21 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp); seg.unlockRead(stamp);
} }
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0,m=segments.length;i<m;i++) { for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i]; Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
int index = seg.firstIndex; int index = seg.firstIndex;
long stamp = seg.readLock(); long stamp = seg.readLock();
try { try {
while(index != -1) { while(index != -1) {
entry.set(seg.keys[index], seg.values[index]); entry.set(index, i);
if(filter.test(entry)) return entry; if(filter.test(entry)) return Optional.ofNullable(entry);
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -853,21 +892,21 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp); seg.unlockRead(stamp);
} }
} }
return null; return Optional.empty();
} }
@Override @Override
public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0,m=segments.length;i<m;i++) { for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i]; Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock(); long stamp = seg.readLock();
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
entry.set(seg.keys[index], seg.values[index]); entry.set(index, i);
if(filter.test(entry)) result++; if(filter.test(entry)) result++;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
@@ -1154,7 +1193,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1178,11 +1217,11 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp); seg.unlockRead(stamp);
} }
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0,m=segments.length;i<m;i++) { for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i]; Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
@@ -1190,7 +1229,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ 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]; index = (int)seg.links[index];
} }
} }
@@ -1198,7 +1237,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp); seg.unlockRead(stamp);
} }
} }
return EMPTY_KEY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -1422,7 +1461,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1446,20 +1485,20 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp); seg.unlockRead(stamp);
} }
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); 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++) { for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i]; Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock(); long stamp = seg.readLock();
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ 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]; index = (int)seg.links[index];
} }
} }
@@ -1467,7 +1506,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
seg.unlockRead(stamp); seg.unlockRead(stamp);
} }
} }
return EMPTY_VALUE; return VALUE_OPTIONAL.empty();
} }
@Override @Override
@@ -1517,12 +1556,12 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry(), currentSegment()); return entry = new ValueMapEntry(nextEntry(), currentSegment());
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() { public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
return entry = new MapEntry(previousEntry(), currentSegment()); return entry = new ValueMapEntry(previousEntry(), currentSegment());
} }
@Override @Override
@@ -1707,6 +1746,33 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
protected class ValueMapEntry extends MapEntry {
protected KEY_TYPE key;
protected VALUE_TYPE value;
public ValueMapEntry(int index, int segmentIndex) {
super(index, segmentIndex);
key = segments[segmentIndex].keys[index];
value = segments[segmentIndex].values[index];
}
@Override
public KEY_TYPE ENTRY_KEY() {
return key;
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return value;
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
this.value = value;
return super.setValue(value);
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> { protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
int index = -1; int index = -1;
int segmentIndex = -1; int segmentIndex = -1;
@@ -1742,7 +1808,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
long stamp = seg.writeLock(); long stamp = seg.writeLock();
try try
{ {
VALUE_TYPE oldValue = ENTRY_VALUE(); VALUE_TYPE oldValue = seg.values[index];
seg.values[index] = value; seg.values[index] = value;
return oldValue; return oldValue;
} }
@@ -2191,6 +2257,110 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
int index = findIndex(hash, key); int index = findIndex(hash, key);
if(index < 0) { if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue()); VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
finally {
unlockWrite(stamp);
}
}
protected VALUE_TYPE computeIfAbsent(int hash, KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
long stamp = writeLock();
try {
int index = findIndex(hash, key);
if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
finally {
unlockWrite(stamp);
}
}
protected VALUE_TYPE supplyIfAbsent(int hash, KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
long stamp = writeLock();
try {
int index = findIndex(hash, key);
if(index < 0) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
finally {
unlockWrite(stamp);
}
}
protected VALUE_TYPE computeIfPresent(int hash, KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
long stamp = writeLock();
try {
int index = findIndex(hash, key);
#if !VALUE_OBJECT
if(index < 0) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#else
if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
finally {
unlockWrite(stamp);
}
}
protected VALUE_TYPE computeNonDefault(int hash, KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
long stamp = writeLock();
try {
int index = findIndex(hash, key);
if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
insert(-index-1, key, newValue); insert(-index-1, key, newValue);
return newValue; return newValue;
@@ -2208,7 +2378,8 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
protected VALUE_TYPE computeIfAbsent(int hash, KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { #if !VALUE_OBJECT
protected VALUE_TYPE computeIfAbsentNonDefault(int hash, KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
long stamp = writeLock(); long stamp = writeLock();
try { try {
int index = findIndex(hash, key); int index = findIndex(hash, key);
@@ -2231,7 +2402,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
protected VALUE_TYPE supplyIfAbsent(int hash, KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { protected VALUE_TYPE supplyIfAbsentNonDefault(int hash, KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
long stamp = writeLock(); long stamp = writeLock();
try { try {
int index = findIndex(hash, key); int index = findIndex(hash, key);
@@ -2254,7 +2425,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
protected VALUE_TYPE computeIfPresent(int hash, KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { protected VALUE_TYPE computeIfPresentNonDefault(int hash, KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
long stamp = writeLock(); long stamp = writeLock();
try { try {
int index = findIndex(hash, key); int index = findIndex(hash, key);
@@ -2272,6 +2443,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
#endif
protected VALUE_TYPE merge(int hash, KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { protected VALUE_TYPE merge(int hash, KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
long stamp = writeLock(); long stamp = writeLock();
try { try {
@@ -4,14 +4,17 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -23,13 +26,16 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #endif
#if !TYPE_OBJECT && !JDK_TYPE #if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
@@ -38,7 +44,7 @@ import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET; import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.PACKAGE.utils.STRATEGY; 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_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.collections.VALUE_ITERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
@@ -57,6 +63,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif #endif
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -231,13 +238,13 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(containsNull) { if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex]; VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value; values[nullIndex] = value;
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex, false);
return lastValue; return lastValue;
} }
values[nullIndex] = value; values[nullIndex] = value;
containsNull = true; containsNull = true;
onNodeAdded(nullIndex); onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex, true);
} }
else { else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask; int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
@@ -245,7 +252,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(strategy.equals(keys[pos], key)) { if(strategy.equals(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos]; VALUE_TYPE lastValue = values[pos];
values[pos] = value; values[pos] = value;
moveToFirstIndex(pos); moveToFirstIndex(pos, false);
return lastValue; return lastValue;
} }
pos = ++pos & mask; pos = ++pos & mask;
@@ -253,7 +260,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
keys[pos] = key; keys[pos] = key;
values[pos] = value; values[pos] = value;
onNodeAdded(pos); onNodeAdded(pos);
moveToFirstIndex(pos); moveToFirstIndex(pos, true);
} }
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor)); if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue(); return getDefaultReturnValue();
@@ -265,13 +272,13 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(containsNull) { if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex]; VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value; values[nullIndex] = value;
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex, false);
return lastValue; return lastValue;
} }
values[nullIndex] = value; values[nullIndex] = value;
containsNull = true; containsNull = true;
onNodeAdded(nullIndex); onNodeAdded(nullIndex);
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex, true);
} }
else { else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask; int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
@@ -279,7 +286,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(strategy.equals(keys[pos], key)) { if(strategy.equals(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos]; VALUE_TYPE lastValue = values[pos];
values[pos] = value; values[pos] = value;
moveToLastIndex(pos); moveToLastIndex(pos, false);
return lastValue; return lastValue;
} }
pos = ++pos & mask; pos = ++pos & mask;
@@ -287,7 +294,55 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
keys[pos] = key; keys[pos] = key;
values[pos] = value; values[pos] = value;
onNodeAdded(pos); 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)); if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue(); return getDefaultReturnValue();
@@ -298,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(isEmpty() || strategy.equals(FIRST_ENTRY_KEY(), key)) return false;
if(strategy.equals(key, EMPTY_KEY_VALUE)) { if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex, false);
return true; return true;
} }
} }
@@ -306,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; int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) { while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) { if(strategy.equals(keys[pos], key)) {
moveToFirstIndex(pos); moveToFirstIndex(pos, false);
return true; return true;
} }
pos = ++pos & mask; pos = ++pos & mask;
@@ -320,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(isEmpty() || strategy.equals(LAST_ENTRY_KEY(), key)) return false;
if(strategy.equals(key, EMPTY_KEY_VALUE)) { if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex, false);
return true; return true;
} }
} }
@@ -328,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; int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) { while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) { if(strategy.equals(keys[pos], key)) {
moveToLastIndex(pos); moveToLastIndex(pos, false);
return true; return true;
} }
pos = ++pos & mask; pos = ++pos & mask;
@@ -341,7 +396,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) { public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) {
int index = findIndex(key); int index = findIndex(key);
if(index < 0) return getDefaultReturnValue(); if(index < 0) return getDefaultReturnValue();
moveToFirstIndex(index); moveToFirstIndex(index, false);
return values[index]; return values[index];
} }
@@ -349,7 +404,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) { public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) {
int index = findIndex(key); int index = findIndex(key);
if(index < 0) return getDefaultReturnValue(); if(index < 0) return getDefaultReturnValue();
moveToLastIndex(index); moveToLastIndex(index, false);
return values[index]; return values[index];
} }
@@ -428,6 +483,52 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
return values[lastIndex]; 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 @Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet(); if(entrySet == null) entrySet = new MapEntrySet();
@@ -441,9 +542,9 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
} }
@Override @Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values(); if(valuesC == null) valuesC = new Values();
return valuesC; return (VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE)valuesC;
} }
@Override @Override
@@ -479,8 +580,8 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
containsNull = false; containsNull = false;
} }
protected void moveToFirstIndex(int startPos) { protected void moveToFirstIndex(int startPos, boolean adding) {
if(size == 1 || firstIndex == startPos) return; if(size == (adding ? 0 : 1) || firstIndex == startPos) return;
if(lastIndex == startPos) { if(lastIndex == startPos) {
lastIndex = (int)(links[startPos] >>> 32); lastIndex = (int)(links[startPos] >>> 32);
links[lastIndex] |= 0xFFFFFFFFL; links[lastIndex] |= 0xFFFFFFFFL;
@@ -497,8 +598,8 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
firstIndex = startPos; firstIndex = startPos;
} }
protected void moveToLastIndex(int startPos) { protected void moveToLastIndex(int startPos, boolean adding) {
if(size == 1 || lastIndex == startPos) return; if(size == (adding ? 0 : 1) || lastIndex == startPos) return;
if(firstIndex == startPos) { if(firstIndex == startPos) {
firstIndex = (int)links[startPos]; firstIndex = (int)links[startPos];
links[lastIndex] |= 0xFFFFFFFF00000000L; links[lastIndex] |= 0xFFFFFFFF00000000L;
@@ -612,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 { 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 @Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -628,24 +733,24 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
} }
@Override @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()); return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
} }
@Override @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()); return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
} }
@Override @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()); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY(); POLL_FIRST_ENTRY_KEY();
return entry; return entry;
} }
@Override @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()); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY(); POLL_LAST_ENTRY_KEY();
return entry; return entry;
@@ -653,7 +758,12 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { 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 @Override
@@ -663,7 +773,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator(); return new FastEntryIterator(true);
} }
@Override @Override
@@ -678,17 +788,17 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
action.accept(new BasicEntryKV_BRACES(keys[index], values[index])); action.accept(new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
} }
@Override @Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
action.accept(entry); action.accept(entry);
index = (int)links[index]; index = (int)links[index];
} }
@@ -701,7 +811,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
int count = 0; int count = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
action.accept(count++, new BasicEntryKV_BRACES(keys[index], values[index])); action.accept(count++, new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
} }
@@ -712,7 +822,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return; if(size() <= 0) return;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
action.accept(input, new BasicEntryKV_BRACES(keys[index], values[index])); action.accept(input, new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
} }
@@ -721,10 +831,10 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(filter.test(entry)) return true; if(filter.test(entry)) return true;
index = (int)links[index]; index = (int)links[index];
} }
@@ -735,10 +845,10 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(filter.test(entry)) return false; if(filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
@@ -749,10 +859,10 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(!filter.test(entry)) return false; if(!filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
@@ -765,14 +875,14 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
E state = identity; E state = identity;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
state = operator.apply(state, new BasicEntryKV_BRACES(keys[index], values[index])); state = operator.apply(state, new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
return state; return state;
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
@@ -780,39 +890,39 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
while(index != -1) { while(index != -1) {
if(empty) { if(empty) {
empty = false; empty = false;
state = new BasicEntryKV_BRACES(keys[index], values[index]); state = new ValueMapEntry(index);
index = (int)links[index]; index = (int)links[index];
continue; continue;
} }
state = operator.apply(state, new BasicEntryKV_BRACES(keys[index], values[index])); state = operator.apply(state, new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(filter.test(entry)) return entry; if(filter.test(entry)) return Optional.ofNullable(entry);
index = (int)links[index]; index = (int)links[index];
} }
return null; return Optional.empty();
} }
@Override @Override
public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(filter.test(entry)) result++; if(filter.test(entry)) result++;
index = (int)links[index]; index = (int)links[index];
} }
@@ -899,9 +1009,12 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -917,7 +1030,12 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { 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 @Override
@@ -939,22 +1057,22 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
} }
@Override @Override
public KEY_TYPE FIRST_KEY() { public KEY_TYPE GET_FIRST_KEY() {
return FIRST_ENTRY_KEY(); return FIRST_ENTRY_KEY();
} }
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { public KEY_TYPE REMOVE_FIRST_KEY() {
return POLL_FIRST_ENTRY_KEY(); return POLL_FIRST_ENTRY_KEY();
} }
@Override @Override
public KEY_TYPE LAST_KEY() { public KEY_TYPE GET_LAST_KEY() {
return LAST_ENTRY_KEY(); return LAST_ENTRY_KEY();
} }
@Override @Override
public KEY_TYPE POLL_LAST_KEY() { public KEY_TYPE REMOVE_LAST_KEY() {
return POLL_LAST_ENTRY_KEY(); return POLL_LAST_ENTRY_KEY();
} }
@@ -1054,7 +1172,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1069,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]); state = operator.APPLY_KEY_VALUE(state, keys[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return OPTIONAL.empty();
int index = firstIndex; int index = firstIndex;
while(index != -1){ 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]; index = (int)links[index];
} }
return EMPTY_KEY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -1098,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 #if VALUE_OBJECT
@Override @Override
@Deprecated @Deprecated
public boolean contains(Object e) { public boolean contains(Object e) { return containsValue(e); }
return containsValue(e);
}
#else #else
@Override @Override
public boolean contains(VALUE_TYPE e) { public boolean contains(VALUE_TYPE e) { return containsValue(e); }
return containsValue(e);
}
#endif #endif
@Override @Override
public boolean add(VALUE_TYPE o) { public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
throw new UnsupportedOperationException();
}
@Override @Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
return new ValueIterator();
}
@Override @Override
public int size() { public int size() { return LINKED_CUSTOM_HASH_MAP.this.size(); }
return LINKED_CUSTOM_HASH_MAP.this.size();
}
@Override @Override
public void clear() { public void clear() { LINKED_CUSTOM_HASH_MAP.this.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 @Override
@@ -1229,7 +1355,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1244,19 +1370,19 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
state = operator.APPLY_VALUE(state, values[index]); state = operator.APPLY_VALUE(state, values[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return VALUE_OPTIONAL.empty();
int index = firstIndex; int index = firstIndex;
while(index != -1){ 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]; index = (int)links[index];
} }
return EMPTY_VALUE; return VALUE_OPTIONAL.empty();
} }
@Override @Override
@@ -1276,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> { private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry(); MapEntry entry = new MapEntry();
public FastEntryIterator() {} public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(KEY_TYPE from) { public FastEntryIterator(KEY_TYPE from) {
super(from); super(from);
} }
@@ -1303,19 +1429,19 @@ 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> { private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry; MapEntry entry;
public EntryIterator() {} public EntryIterator(boolean start) { super(start); }
public EntryIterator(KEY_TYPE from) { public EntryIterator(KEY_TYPE from) {
super(from); super(from);
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry()); return entry = new ValueMapEntry(nextEntry());
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() { public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
return entry = new MapEntry(previousEntry()); return entry = new ValueMapEntry(previousEntry());
} }
@Override @Override
@@ -1333,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 { private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {} public KeyIterator(boolean start) { super(start); }
public KeyIterator(KEY_TYPE from) { public KeyIterator(KEY_TYPE from) {
super(from); super(from);
} }
@@ -1355,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 { private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {} public ValueIterator(boolean start) { super(start); }
@Override @Override
public VALUE_TYPE VALUE_PREVIOUS() { public VALUE_TYPE VALUE_PREVIOUS() {
@@ -1376,16 +1502,20 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
} }
private class MapIterator { private class MapIterator {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = 0;
MapIterator() { MapIterator(boolean start) {
next = firstIndex; this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
} }
MapIterator(KEY_TYPE from) { MapIterator(KEY_TYPE from) {
this.forward = true;
if(strategy.equals(from, EMPTY_KEY_VALUE)) { if(strategy.equals(from, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
next = (int) links[nullIndex]; next = (int) links[nullIndex];
@@ -1413,11 +1543,11 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
} }
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
public int nextIndex() { public int nextIndex() {
@@ -1477,20 +1607,30 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public int previousEntry() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return current; return current;
} }
public int nextEntry() { public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException(); 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; current = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current; previous = current;
if(index >= 0) index++;
return current;
} }
private void ensureIndexKnown() { private void ensureIndexKnown() {
@@ -5,14 +5,17 @@ import java.util.ConcurrentModificationException;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -24,10 +27,12 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE #if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif #endif
@@ -35,9 +40,12 @@ import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif #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; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; 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;
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -73,6 +81,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif #endif
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
@@ -535,6 +544,95 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
int index = findIndex(key); int index = findIndex(key);
if(index < 0) { if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue()); VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
int index = findIndex(key);
if(index < 0) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
#if !VALUE_OBJECT
if(index < 0) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#else
if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
insert(-index-1, key, newValue); insert(-index-1, key, newValue);
return newValue; return newValue;
@@ -549,7 +647,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int index = findIndex(key); int index = findIndex(key);
if(index < 0) { if(index < 0) {
@@ -568,7 +666,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
} }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider); Objects.requireNonNull(valueProvider);
int index = findIndex(key); int index = findIndex(key);
if(index < 0) { if(index < 0) {
@@ -587,7 +685,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int index = findIndex(key); int index = findIndex(key);
if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue(); if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
@@ -600,6 +698,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
return newValue; return newValue;
} }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -788,6 +887,33 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
} }
} }
protected class ValueMapEntry extends MapEntry {
protected KEY_TYPE key;
protected VALUE_TYPE value;
public ValueMapEntry(int index) {
super(index);
key = keys[index];
value = values[index];
}
@Override
public KEY_TYPE ENTRY_KEY() {
return key;
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return value;
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
this.value = value;
return super.setValue(value);
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> { protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
public int index = -1; public int index = -1;
@@ -796,6 +922,10 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -818,19 +948,19 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
if(obj instanceof Map.Entry) { if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) { if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj; MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE()); return KEY_EQUALS(ENTRY_KEY(), entry.ENTRY_KEY()) && VALUE_EQUALS(ENTRY_VALUE(), entry.ENTRY_VALUE());
} }
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj; Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey(); Object key = entry.getKey();
Object value = entry.getValue(); Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT #if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value); return KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else if TYPE_OBJECT #else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#else if VALUE_OBJECT #else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value); return key instanceof CLASS_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else #else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#endif #endif
} }
return false; return false;
@@ -838,12 +968,12 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
@Override @Override
public int hashCode() { public int hashCode() {
return strategy.hashCode(keys[index]) ^ VALUE_TO_HASH(values[index]); return strategy.hashCode(ENTRY_KEY()) ^ VALUE_TO_HASH(ENTRY_VALUE());
} }
@Override @Override
public String toString() { public String toString() {
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]); return KEY_TO_STRING(ENTRY_KEY()) + "=" + VALUE_TO_STRING(ENTRY_VALUE());
} }
} }
@@ -860,21 +990,21 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
@Override @Override
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
if(containsNull) action.accept(new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex])); if(containsNull) action.accept(new ValueMapEntry(nullIndex));
for(int i = nullIndex-1;i>=0;i--) for(int i = nullIndex-1;i>=0;i--)
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(new BasicEntryKV_BRACES(keys[i], values[i])); if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(new ValueMapEntry(i));
} }
@Override @Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
action.accept(entry); action.accept(entry);
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) { if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) {
entry.set(keys[i], values[i]); entry.set(i);
action.accept(entry); action.accept(entry);
} }
} }
@@ -884,9 +1014,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
if(size() <= 0) return; if(size() <= 0) return;
if(containsNull) action.accept(0, new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex])); if(containsNull) action.accept(0, new ValueMapEntry(nullIndex));
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) { for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(index++, new BasicEntryKV_BRACES(keys[i], values[i])); if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(index++, new ValueMapEntry(i));
} }
} }
@@ -894,9 +1024,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public <E> void forEach(E input, ObjectObjectConsumer<E, MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public <E> void forEach(E input, ObjectObjectConsumer<E, MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
if(size() <= 0) return; if(size() <= 0) return;
if(containsNull) action.accept(input, new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex])); if(containsNull) action.accept(input, new ValueMapEntry(nullIndex));
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(input, new BasicEntryKV_BRACES(keys[i], values[i])); if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(input, new ValueMapEntry(i));
} }
} }
@@ -904,14 +1034,14 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
if(filter.test(entry)) return true; if(filter.test(entry)) return true;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) { if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return true; if(filter.test(entry)) return true;
} }
} }
@@ -922,14 +1052,14 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
if(filter.test(entry)) return false; if(filter.test(entry)) return false;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) { if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return false; if(filter.test(entry)) return false;
} }
} }
@@ -940,14 +1070,14 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
if(!filter.test(entry)) return false; if(!filter.test(entry)) return false;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) { if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) {
entry.set(keys[i], values[i]); entry.set(i);
if(!filter.test(entry)) return false; if(!filter.test(entry)) return false;
} }
} }
@@ -958,66 +1088,66 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public <E> E reduce(E identity, BiFunction<E, MAP.Entry KEY_VALUE_GENERIC_TYPE, E> operator) { public <E> E reduce(E identity, BiFunction<E, MAP.Entry KEY_VALUE_GENERIC_TYPE, E> operator) {
Objects.requireNonNull(operator); Objects.requireNonNull(operator);
E state = identity; E state = identity;
if(containsNull) state = operator.apply(state, new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex])); if(containsNull) state = operator.apply(state, new ValueMapEntry(nullIndex));
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) continue; if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) continue;
state = operator.apply(state, new BasicEntryKV_BRACES(keys[i], values[i])); state = operator.apply(state, new ValueMapEntry(i));
} }
return state; return state;
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
if(containsNull) { if(containsNull) {
state = new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex]); state = new ValueMapEntry(nullIndex);
empty = false; empty = false;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) continue; if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) continue;
if(empty) { if(empty) {
empty = false; empty = false;
state = new BasicEntryKV_BRACES(keys[i], values[i]); state = new ValueMapEntry(i);
continue; continue;
} }
state = operator.apply(state, new BasicEntryKV_BRACES(keys[i], values[i])); state = operator.apply(state, new ValueMapEntry(i));
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); 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--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) { if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return entry; if(filter.test(entry)) return Optional.ofNullable(entry);
} }
} }
return null; return Optional.empty();
} }
@Override @Override
public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int result = 0; int result = 0;
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
if(filter.test(entry)) result++; if(filter.test(entry)) result++;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) { if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) result++; if(filter.test(entry)) result++;
} }
} }
@@ -1208,7 +1338,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1225,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]); state = operator.APPLY_KEY_VALUE(state, keys[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return OPTIONAL.empty();
if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex]; if(containsNull && filter.test(keys[nullIndex])) return OPTIONAL.GET_OPTIONAL(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) { 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 @Override
@@ -1374,7 +1504,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1391,18 +1521,18 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
} }
state = operator.APPLY_VALUE(state, values[i]); state = operator.APPLY_VALUE(state, values[i]);
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return VALUE_OPTIONAL.empty();
if(containsNull && filter.test(values[nullIndex])) return values[nullIndex]; if(containsNull && filter.test(values[nullIndex])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) { 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 @Override
@@ -1431,7 +1561,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
MapEntry entry; MapEntry entry;
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry()); return entry = new ValueMapEntry(nextEntry());
} }
@Override @Override
@@ -4,14 +4,17 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -23,13 +26,16 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #endif
#if !TYPE_OBJECT && !JDK_TYPE #if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
@@ -37,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.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_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_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.collections.VALUE_ITERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
@@ -56,6 +62,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif #endif
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -208,13 +215,13 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(containsNull) { if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex]; VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value; values[nullIndex] = value;
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex, false);
return lastValue; return lastValue;
} }
values[nullIndex] = value; values[nullIndex] = value;
containsNull = true; containsNull = true;
onNodeAdded(nullIndex); onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex, true);
} }
else { else {
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask; int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
@@ -222,7 +229,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(KEY_EQUALS(keys[pos], key)) { if(KEY_EQUALS(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos]; VALUE_TYPE lastValue = values[pos];
values[pos] = value; values[pos] = value;
moveToFirstIndex(pos); moveToFirstIndex(pos, false);
return lastValue; return lastValue;
} }
pos = ++pos & mask; pos = ++pos & mask;
@@ -230,7 +237,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
keys[pos] = key; keys[pos] = key;
values[pos] = value; values[pos] = value;
onNodeAdded(pos); onNodeAdded(pos);
moveToFirstIndex(pos); moveToFirstIndex(pos, true);
} }
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor)); if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue(); return getDefaultReturnValue();
@@ -242,13 +249,13 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(containsNull) { if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex]; VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value; values[nullIndex] = value;
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex, false);
return lastValue; return lastValue;
} }
values[nullIndex] = value; values[nullIndex] = value;
containsNull = true; containsNull = true;
onNodeAdded(nullIndex); onNodeAdded(nullIndex);
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex, true);
} }
else { else {
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask; int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
@@ -256,7 +263,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(KEY_EQUALS(keys[pos], key)) { if(KEY_EQUALS(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos]; VALUE_TYPE lastValue = values[pos];
values[pos] = value; values[pos] = value;
moveToLastIndex(pos); moveToLastIndex(pos, false);
return lastValue; return lastValue;
} }
pos = ++pos & mask; pos = ++pos & mask;
@@ -264,7 +271,55 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
keys[pos] = key; keys[pos] = key;
values[pos] = value; values[pos] = value;
onNodeAdded(pos); 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)); if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue(); return getDefaultReturnValue();
@@ -275,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(isEmpty() || KEY_EQUALS(FIRST_ENTRY_KEY(), key)) return false;
if(KEY_EQUALS_NULL(key)) { if(KEY_EQUALS_NULL(key)) {
if(containsNull) { if(containsNull) {
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex, false);
return true; return true;
} }
} }
@@ -283,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; int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) { while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], key)) { if(KEY_EQUALS(keys[pos], key)) {
moveToFirstIndex(pos); moveToFirstIndex(pos, false);
return true; return true;
} }
pos = ++pos & mask; pos = ++pos & mask;
@@ -297,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(isEmpty() || KEY_EQUALS(LAST_ENTRY_KEY(), key)) return false;
if(KEY_EQUALS_NULL(key)) { if(KEY_EQUALS_NULL(key)) {
if(containsNull) { if(containsNull) {
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex, false);
return true; return true;
} }
} }
@@ -305,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; int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) { while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], key)) { if(KEY_EQUALS(keys[pos], key)) {
moveToLastIndex(pos); moveToLastIndex(pos, false);
return true; return true;
} }
pos = ++pos & mask; pos = ++pos & mask;
@@ -318,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) { public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) {
int index = findIndex(key); int index = findIndex(key);
if(index < 0) return getDefaultReturnValue(); if(index < 0) return getDefaultReturnValue();
moveToFirstIndex(index); moveToFirstIndex(index, false);
return values[index]; return values[index];
} }
@@ -326,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) { public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) {
int index = findIndex(key); int index = findIndex(key);
if(index < 0) return getDefaultReturnValue(); if(index < 0) return getDefaultReturnValue();
moveToLastIndex(index); moveToLastIndex(index, false);
return values[index]; return values[index];
} }
@@ -432,6 +487,52 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
return values[lastIndex]; 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 @Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet(); if(entrySet == null) entrySet = new MapEntrySet();
@@ -445,9 +546,9 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
} }
@Override @Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values(); if(valuesC == null) valuesC = new Values();
return valuesC; return (VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE)valuesC;
} }
@Override @Override
@@ -483,8 +584,8 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
containsNull = false; containsNull = false;
} }
protected void moveToFirstIndex(int startPos) { protected void moveToFirstIndex(int startPos, boolean adding) {
if(size == 1 || firstIndex == startPos) return; if(size == (adding ? 0 : 1) || firstIndex == startPos) return;
if(lastIndex == startPos) { if(lastIndex == startPos) {
lastIndex = (int)(links[startPos] >>> 32); lastIndex = (int)(links[startPos] >>> 32);
links[lastIndex] |= 0xFFFFFFFFL; links[lastIndex] |= 0xFFFFFFFFL;
@@ -501,8 +602,8 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
firstIndex = startPos; firstIndex = startPos;
} }
protected void moveToLastIndex(int startPos) { protected void moveToLastIndex(int startPos, boolean adding) {
if(size == 1 || lastIndex == startPos) return; if(size == (adding ? 0 : 1) || lastIndex == startPos) return;
if(firstIndex == startPos) { if(firstIndex == startPos) {
firstIndex = (int)links[startPos]; firstIndex = (int)links[startPos];
links[lastIndex] |= 0xFFFFFFFF00000000L; links[lastIndex] |= 0xFFFFFFFF00000000L;
@@ -616,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 { 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 @Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -632,24 +737,24 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
} }
@Override @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()); return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
} }
@Override @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()); return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
} }
@Override @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()); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY(); POLL_FIRST_ENTRY_KEY();
return entry; return entry;
} }
@Override @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()); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY(); POLL_LAST_ENTRY_KEY();
return entry; return entry;
@@ -657,7 +762,12 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { 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 @Override
@@ -667,7 +777,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator(); return new FastEntryIterator(true);
} }
@Override @Override
@@ -682,17 +792,17 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
action.accept(new BasicEntryKV_BRACES(keys[index], values[index])); action.accept(new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
} }
@Override @Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
entry.set(keys[index], values[index]); entry.set(index);
action.accept(entry); action.accept(entry);
index = (int)links[index]; index = (int)links[index];
} }
@@ -705,7 +815,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
int count = 0; int count = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
action.accept(count++, new BasicEntryKV_BRACES(keys[index], values[index])); action.accept(count++, new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
} }
@@ -716,7 +826,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return; if(size() <= 0) return;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
action.accept(input, new BasicEntryKV_BRACES(keys[index], values[index])); action.accept(input, new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
} }
@@ -725,10 +835,10 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(filter.test(entry)) return true; if(filter.test(entry)) return true;
index = (int)links[index]; index = (int)links[index];
} }
@@ -739,10 +849,10 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(filter.test(entry)) return false; if(filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
@@ -753,10 +863,10 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(!filter.test(entry)) return false; if(!filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
@@ -769,14 +879,14 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
E state = identity; E state = identity;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
state = operator.apply(state, new BasicEntryKV_BRACES(keys[index], values[index])); state = operator.apply(state, new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
return state; return state;
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
@@ -784,28 +894,28 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
while(index != -1) { while(index != -1) {
if(empty) { if(empty) {
empty = false; empty = false;
state = new BasicEntryKV_BRACES(keys[index], values[index]); state = new ValueMapEntry(index);
index = (int)links[index]; index = (int)links[index];
continue; continue;
} }
state = operator.apply(state, new BasicEntryKV_BRACES(keys[index], values[index])); state = operator.apply(state, new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(filter.test(entry)) return entry; if(filter.test(entry)) return Optional.ofNullable(entry);
index = (int)links[index]; index = (int)links[index];
} }
return null; return Optional.empty();
} }
@Override @Override
@@ -813,10 +923,10 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
int result = 0; int result = 0;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(index);
if(filter.test(entry)) result++; if(filter.test(entry)) result++;
index = (int)links[index]; index = (int)links[index];
} }
@@ -898,6 +1008,12 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); } 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 @Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -916,7 +1032,12 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { 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 @Override
@@ -938,22 +1059,22 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
} }
@Override @Override
public KEY_TYPE FIRST_KEY() { public KEY_TYPE GET_FIRST_KEY() {
return FIRST_ENTRY_KEY(); return FIRST_ENTRY_KEY();
} }
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { public KEY_TYPE REMOVE_FIRST_KEY() {
return POLL_FIRST_ENTRY_KEY(); return POLL_FIRST_ENTRY_KEY();
} }
@Override @Override
public KEY_TYPE LAST_KEY() { public KEY_TYPE GET_LAST_KEY() {
return LAST_ENTRY_KEY(); return LAST_ENTRY_KEY();
} }
@Override @Override
public KEY_TYPE POLL_LAST_KEY() { public KEY_TYPE REMOVE_LAST_KEY() {
return POLL_LAST_ENTRY_KEY(); return POLL_LAST_ENTRY_KEY();
} }
@@ -1053,7 +1174,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1068,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]); state = operator.APPLY_KEY_VALUE(state, keys[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return OPTIONAL.empty();
int index = firstIndex; int index = firstIndex;
while(index != -1){ 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]; index = (int)links[index];
} }
return EMPTY_KEY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -1097,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 #if VALUE_OBJECT
@Override @Override
@Deprecated @Deprecated
public boolean contains(Object e) { public boolean contains(Object e) { return containsValue(e); }
return containsValue(e);
}
#else #else
@Override @Override
public boolean contains(VALUE_TYPE e) { public boolean contains(VALUE_TYPE e) { return containsValue(e); }
return containsValue(e);
}
#endif #endif
@Override @Override
public boolean add(VALUE_TYPE o) { public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
throw new UnsupportedOperationException();
}
@Override @Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
return new ValueIterator();
}
@Override @Override
public int size() { public int size() { return LINKED_HASH_MAP.this.size(); }
return LINKED_HASH_MAP.this.size();
}
@Override @Override
public void clear() { public void clear() { LINKED_HASH_MAP.this.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 @Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) { public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1229,7 +1359,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1244,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]); state = operator.APPLY_VALUE(state, values[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return VALUE_OPTIONAL.empty();
int index = firstIndex; int index = firstIndex;
while(index != -1){ 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]; index = (int)links[index];
} }
return EMPTY_VALUE; return VALUE_OPTIONAL.empty();
} }
@Override @Override
@@ -1276,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> { private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry(); MapEntry entry = new MapEntry();
public FastEntryIterator() {} public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(KEY_TYPE from) { public FastEntryIterator(KEY_TYPE from) {
super(from); super(from);
} }
@@ -1303,19 +1433,19 @@ 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> { private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry; MapEntry entry;
public EntryIterator() {} public EntryIterator(boolean start) { super(start); }
public EntryIterator(KEY_TYPE from) { public EntryIterator(KEY_TYPE from) {
super(from); super(from);
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry()); return entry = new ValueMapEntry(nextEntry());
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() { public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
return entry = new MapEntry(previousEntry()); return entry = new ValueMapEntry(previousEntry());
} }
@Override @Override
@@ -1333,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 { private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {} public KeyIterator(boolean start) { super(start); }
public KeyIterator(KEY_TYPE from) { public KeyIterator(KEY_TYPE from) {
super(from); super(from);
} }
@@ -1355,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 { private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {} public ValueIterator(boolean start) { super(start); }
@Override @Override
public VALUE_TYPE VALUE_PREVIOUS() { public VALUE_TYPE VALUE_PREVIOUS() {
@@ -1375,13 +1505,16 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
} }
private class MapIterator { private class MapIterator {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = 0;
MapIterator() { MapIterator(boolean start) {
next = firstIndex; this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
} }
MapIterator(KEY_TYPE from) { MapIterator(KEY_TYPE from) {
@@ -1412,11 +1545,11 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
} }
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
public int nextIndex() { public int nextIndex() {
@@ -1476,20 +1609,30 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public int previousEntry() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return current; return current;
} }
public int nextEntry() { public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException(); 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; current = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current; previous = current;
if(index >= 0) index++;
return current;
} }
private void ensureIndexKnown() { private void ensureIndexKnown() {
@@ -5,14 +5,17 @@ import java.util.ConcurrentModificationException;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -24,10 +27,12 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE #if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif #endif
@@ -35,9 +40,12 @@ import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif #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; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; 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;
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -71,6 +79,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
@@ -495,6 +504,95 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
int index = findIndex(key); int index = findIndex(key);
if(index < 0) { if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue()); VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
int index = findIndex(key);
if(index < 0) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insert(-index-1, key, newValue);
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
#if !VALUE_OBJECT
if(index < 0) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#else
if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index < 0) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
insert(-index-1, key, newValue); insert(-index-1, key, newValue);
return newValue; return newValue;
@@ -509,7 +607,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int index = findIndex(key); int index = findIndex(key);
if(index < 0) { if(index < 0) {
@@ -528,7 +626,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
} }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider); Objects.requireNonNull(valueProvider);
int index = findIndex(key); int index = findIndex(key);
if(index < 0) { if(index < 0) {
@@ -547,7 +645,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int index = findIndex(key); int index = findIndex(key);
if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue(); if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
@@ -560,6 +658,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
return newValue; return newValue;
} }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -747,6 +846,33 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
} }
} }
protected class ValueMapEntry extends MapEntry {
protected KEY_TYPE key;
protected VALUE_TYPE value;
public ValueMapEntry(int index) {
super(index);
key = keys[index];
value = values[index];
}
@Override
public KEY_TYPE ENTRY_KEY() {
return key;
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return value;
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
this.value = value;
return super.setValue(value);
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> { protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
public int index = -1; public int index = -1;
@@ -755,6 +881,10 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -777,19 +907,19 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
if(obj instanceof Map.Entry) { if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) { if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj; MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE()); return KEY_EQUALS(ENTRY_KEY(), entry.ENTRY_KEY()) && VALUE_EQUALS(ENTRY_VALUE(), entry.ENTRY_VALUE());
} }
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj; Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey(); Object key = entry.getKey();
Object value = entry.getValue(); Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT #if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value); return KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else if TYPE_OBJECT #else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#else if VALUE_OBJECT #else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value); return key instanceof CLASS_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else #else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#endif #endif
} }
return false; return false;
@@ -797,12 +927,12 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
@Override @Override
public int hashCode() { public int hashCode() {
return KEY_TO_HASH(keys[index]) ^ VALUE_TO_HASH(values[index]); return KEY_TO_HASH(ENTRY_KEY()) ^ VALUE_TO_HASH(ENTRY_VALUE());
} }
@Override @Override
public String toString() { public String toString() {
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]); return KEY_TO_STRING(ENTRY_KEY()) + "=" + VALUE_TO_STRING(ENTRY_VALUE());
} }
} }
@@ -819,21 +949,21 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
@Override @Override
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
if(containsNull) action.accept(new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex])); if(containsNull) action.accept(new ValueMapEntry(nullIndex));
for(int i = nullIndex-1;i>=0;i--) for(int i = nullIndex-1;i>=0;i--)
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(new BasicEntryKV_BRACES(keys[i], values[i])); if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(new ValueMapEntry(i));
} }
@Override @Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
action.accept(entry); action.accept(entry);
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) { if(KEY_EQUALS_NOT_NULL(keys[i])) {
entry.set(keys[i], values[i]); entry.set(i);
action.accept(entry); action.accept(entry);
} }
} }
@@ -843,9 +973,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
if(size() <= 0) return; if(size() <= 0) return;
if(containsNull) action.accept(0, new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex])); if(containsNull) action.accept(0, new ValueMapEntry(nullIndex));
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) { for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(index++, new BasicEntryKV_BRACES(keys[i], values[i])); if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(index++, new ValueMapEntry(i));
} }
} }
@@ -853,9 +983,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public <E> void forEach(E input, ObjectObjectConsumer<E, MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public <E> void forEach(E input, ObjectObjectConsumer<E, MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
if(size() <= 0) return; if(size() <= 0) return;
if(containsNull) action.accept(input, new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex])); if(containsNull) action.accept(input, new ValueMapEntry(nullIndex));
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(input, new BasicEntryKV_BRACES(keys[i], values[i])); if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(input, new ValueMapEntry(i));
} }
} }
@@ -863,14 +993,14 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
if(filter.test(entry)) return true; if(filter.test(entry)) return true;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) { if(KEY_EQUALS_NOT_NULL(keys[i])) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return true; if(filter.test(entry)) return true;
} }
} }
@@ -881,14 +1011,14 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
if(filter.test(entry)) return false; if(filter.test(entry)) return false;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) { if(KEY_EQUALS_NOT_NULL(keys[i])) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return false; if(filter.test(entry)) return false;
} }
} }
@@ -899,14 +1029,14 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
if(!filter.test(entry)) return false; if(!filter.test(entry)) return false;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) { if(KEY_EQUALS_NOT_NULL(keys[i])) {
entry.set(keys[i], values[i]); entry.set(i);
if(!filter.test(entry)) return false; if(!filter.test(entry)) return false;
} }
} }
@@ -917,66 +1047,66 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public <E> E reduce(E identity, BiFunction<E, MAP.Entry KEY_VALUE_GENERIC_TYPE, E> operator) { public <E> E reduce(E identity, BiFunction<E, MAP.Entry KEY_VALUE_GENERIC_TYPE, E> operator) {
Objects.requireNonNull(operator); Objects.requireNonNull(operator);
E state = identity; E state = identity;
if(containsNull) state = operator.apply(state, new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex])); if(containsNull) state = operator.apply(state, new ValueMapEntry(nullIndex));
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NULL(keys[i])) continue; if(KEY_EQUALS_NULL(keys[i])) continue;
state = operator.apply(state, new BasicEntryKV_BRACES(keys[i], values[i])); state = operator.apply(state, new ValueMapEntry(i));
} }
return state; return state;
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
if(containsNull) { if(containsNull) {
state = new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex]); state = new ValueMapEntry(nullIndex);
empty = false; empty = false;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NULL(keys[i])) continue; if(KEY_EQUALS_NULL(keys[i])) continue;
if(empty) { if(empty) {
empty = false; empty = false;
state = new BasicEntryKV_BRACES(keys[i], values[i]); state = new ValueMapEntry(i);
continue; continue;
} }
state = operator.apply(state, new BasicEntryKV_BRACES(keys[i], values[i])); state = operator.apply(state, new ValueMapEntry(i));
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); 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--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) { if(KEY_EQUALS_NOT_NULL(keys[i])) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return entry; if(filter.test(entry)) return Optional.ofNullable(entry);
} }
} }
return null; return Optional.empty();
} }
@Override @Override
public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int result = 0; int result = 0;
if(containsNull) { if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]); entry.set(nullIndex);
if(filter.test(entry)) result++; if(filter.test(entry)) result++;
} }
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) { if(KEY_EQUALS_NOT_NULL(keys[i])) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) result++; if(filter.test(entry)) result++;
} }
} }
@@ -1163,7 +1293,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1180,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]); state = operator.APPLY_KEY_VALUE(state, keys[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return OPTIONAL.empty();
if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex]; if(containsNull && filter.test(keys[nullIndex])) return OPTIONAL.GET_OPTIONAL(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) { 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 @Override
@@ -1329,7 +1459,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1346,18 +1476,18 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
} }
state = operator.APPLY_VALUE(state, values[i]); state = operator.APPLY_VALUE(state, values[i]);
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return VALUE_OPTIONAL.empty();
if(containsNull && filter.test(values[nullIndex])) return values[nullIndex]; if(containsNull && filter.test(values[nullIndex])) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) { 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 @Override
@@ -1386,7 +1516,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
MapEntry entry; MapEntry entry;
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry()); return entry = new ValueMapEntry(nextEntry());
} }
@Override @Override
@@ -4,14 +4,17 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -23,13 +26,18 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #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; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE #if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif #endif
@@ -57,13 +65,14 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif #endif
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
#endif #endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; 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.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER; import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER;
#if !SAME_TYPE #if !SAME_TYPE
@@ -117,7 +126,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
/** KeySet cache */ /** KeySet cache */
protected transient ORDERED_SET KEY_GENERIC_TYPE keySet; protected transient ORDERED_SET KEY_GENERIC_TYPE keySet;
/** Values cache */ /** 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 */ /** Amount of Elements stored in the HashMap */
protected int size; protected int size;
@@ -318,6 +327,10 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override @Override
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
@Override @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(); } public boolean moveToFirst(KEY_TYPE key) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean moveToLast(KEY_TYPE key) { throw new UnsupportedOperationException(); } public boolean moveToLast(KEY_TYPE key) { throw new UnsupportedOperationException(); }
@@ -441,6 +454,23 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
return values[lastIndex]; 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 @Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet(); if(entrySet == null) entrySet = new MapEntrySet();
@@ -454,7 +484,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
@Override @Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values(); if(valuesC == null) valuesC = new Values();
return valuesC; return valuesC;
} }
@@ -491,16 +521,22 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override @Override
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@@ -601,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 { 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 @Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -613,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(); } public boolean moveToLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override @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()); return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
} }
@Override @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()); return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() { throw new UnsupportedOperationException(); } public MAP.Entry KEY_VALUE_GENERIC_TYPE removeFirst() { throw new UnsupportedOperationException(); }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() { throw new UnsupportedOperationException(); } public MAP.Entry KEY_VALUE_GENERIC_TYPE removeLast() { throw new UnsupportedOperationException(); }
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { 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 @Override
@@ -640,7 +685,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator(); return new FastEntryIterator(true);
} }
@Override @Override
@@ -749,7 +794,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
@@ -764,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])); state = operator.apply(state, new BasicEntryKV_BRACES(keys[index], values[index]));
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(keys[index], values[index]);
if(filter.test(entry)) return entry; if(filter.test(entry)) return Optional.ofNullable(entry);
index = (int)links[index]; index = (int)links[index];
} }
return null; return Optional.empty();
} }
@Override @Override
@@ -853,6 +898,12 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -867,7 +918,12 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { 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 @Override
@@ -887,20 +943,20 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
public void clear() { throw new UnsupportedOperationException(); } public void clear() { throw new UnsupportedOperationException(); }
@Override @Override
public KEY_TYPE FIRST_KEY() { public KEY_TYPE GET_FIRST_KEY() {
return FIRST_ENTRY_KEY(); return FIRST_ENTRY_KEY();
} }
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE REMOVE_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public KEY_TYPE LAST_KEY() { public KEY_TYPE GET_LAST_KEY() {
return LAST_ENTRY_KEY(); return LAST_ENTRY_KEY();
} }
@Override @Override
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE REMOVE_LAST_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
@@ -998,7 +1054,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1013,19 +1069,19 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
state = operator.APPLY_KEY_VALUE(state, keys[index]); state = operator.APPLY_KEY_VALUE(state, keys[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return OPTIONAL.empty();
int index = firstIndex; int index = firstIndex;
while(index != -1){ 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]; index = (int)links[index];
} }
return EMPTY_KEY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -1042,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 #if VALUE_OBJECT
@Override @Override
@Deprecated @Deprecated
public boolean contains(Object e) { public boolean contains(Object e) { return containsValue(e); }
return containsValue(e);
}
#else #else
@Override @Override
public boolean contains(VALUE_TYPE e) { public boolean contains(VALUE_TYPE e) { return containsValue(e); }
return containsValue(e);
}
#endif #endif
@Override @Override
public boolean add(VALUE_TYPE o) { public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
throw new UnsupportedOperationException();
}
@Override @Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
return new ValueIterator();
}
@Override @Override
public int size() { public int size() { return IMMUTABLE_HASH_MAP.this.size(); }
return IMMUTABLE_HASH_MAP.this.size();
}
@Override @Override
public void clear() { throw new UnsupportedOperationException(); } 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 @Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) { public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
int index = firstIndex; int index = firstIndex;
@@ -1171,7 +1230,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1186,19 +1245,19 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
state = operator.APPLY_VALUE(state, values[index]); state = operator.APPLY_VALUE(state, values[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return VALUE_OPTIONAL.empty();
int index = firstIndex; int index = firstIndex;
while(index != -1){ 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]; index = (int)links[index];
} }
return EMPTY_VALUE; return VALUE_OPTIONAL.empty();
} }
@Override @Override
@@ -1218,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> { private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry(); MapEntry entry = new MapEntry();
public FastEntryIterator() {} public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(KEY_TYPE from) { public FastEntryIterator(KEY_TYPE from) {
super(from); super(from);
} }
@@ -1244,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> { 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) { public EntryIterator(KEY_TYPE from) {
super(from); super(from);
} }
@@ -1271,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 { private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {} public KeyIterator(boolean start) { super(start); }
public KeyIterator(KEY_TYPE from) { public KeyIterator(KEY_TYPE from) {
super(from); super(from);
} }
@@ -1293,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 { private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {} public ValueIterator(boolean start) { super(start); }
@Override @Override
public VALUE_TYPE VALUE_PREVIOUS() { public VALUE_TYPE VALUE_PREVIOUS() {
@@ -1314,13 +1373,16 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
private class MapIterator { private class MapIterator {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = 0;
MapIterator() { MapIterator(boolean start) {
next = firstIndex; this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
} }
MapIterator(KEY_TYPE from) { MapIterator(KEY_TYPE from) {
@@ -1351,11 +1413,11 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
public int nextIndex() { public int nextIndex() {
@@ -1372,20 +1434,30 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
public int previousEntry() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return current; return current;
} }
public int nextEntry() { public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException(); 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; current = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current; previous = current;
if(index >= 0) index++;
return current;
} }
private void ensureIndexKnown() { private void ensureIndexKnown() {
@@ -4,14 +4,17 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -23,13 +26,18 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #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; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE #if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif #endif
@@ -44,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.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_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_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.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER; import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER;
#if !SAME_TYPE #if !SAME_TYPE
@@ -64,6 +72,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif #endif
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
#if !VALUE_OBJECT #if !VALUE_OBJECT
@@ -103,7 +112,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
/** KeySet cache */ /** KeySet cache */
protected ORDERED_SET KEY_GENERIC_TYPE keySet; protected ORDERED_SET KEY_GENERIC_TYPE keySet;
/** Values cache */ /** Values cache */
protected VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC; protected VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE valuesC;
/** EntrySet cache */ /** EntrySet cache */
protected FastOrderedSet KEY_VALUE_GENERIC_TYPE entrySet; protected FastOrderedSet KEY_VALUE_GENERIC_TYPE entrySet;
@@ -273,6 +282,27 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
return lastValue; 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 @Override
public boolean moveToFirst(KEY_TYPE key) { public boolean moveToFirst(KEY_TYPE key) {
int index = findIndex(key); int index = findIndex(key);
@@ -400,6 +430,34 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
return result; 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 @Override
public VALUE_TYPE REMOVE_VALUE(KEY_TYPE key) { public VALUE_TYPE REMOVE_VALUE(KEY_TYPE key) {
int index = findIndex(key); int index = findIndex(key);
@@ -459,7 +517,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
@Override @Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values(); if(valuesC == null) valuesC = new Values();
return valuesC; return valuesC;
} }
@@ -493,6 +551,95 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
int index = findIndex(key); int index = findIndex(key);
if(index == -1) { if(index == -1) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue()); VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insertIndex(size++, key, newValue);
return newValue;
}
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insertIndex(size++, key, newValue);
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
insertIndex(size++, key, newValue);
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
#if !VALUE_OBJECT
if(index == -1) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#else
if(index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
insertIndex(size++, key, newValue); insertIndex(size++, key, newValue);
return newValue; return newValue;
@@ -507,7 +654,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int index = findIndex(key); int index = findIndex(key);
if(index == -1) { if(index == -1) {
@@ -526,7 +673,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider); Objects.requireNonNull(valueProvider);
int index = findIndex(key); int index = findIndex(key);
if(index == -1) { if(index == -1) {
@@ -545,7 +692,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int index = findIndex(key); int index = findIndex(key);
if(index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue(); if(index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
@@ -558,6 +705,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
return newValue; return newValue;
} }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -720,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 { 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 @Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -736,24 +888,24 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
@Override @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()); return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
} }
@Override @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()); return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
} }
@Override @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()); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY(); POLL_FIRST_ENTRY_KEY();
return entry; return entry;
} }
@Override @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()); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY(); POLL_LAST_ENTRY_KEY();
return entry; return entry;
@@ -761,7 +913,12 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { 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 @Override
@@ -771,7 +928,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator(); return new FastEntryIterator(true);
} }
@Override @Override
@@ -786,16 +943,16 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
action.accept(new BasicEntryKV_BRACES(keys[i], values[i])); action.accept(new ValueMapEntry(i));
} }
@Override @Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
if(size() <= 0) return; if(size() <= 0) return;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
entry.set(keys[i], values[i]); entry.set(i);
action.accept(entry); action.accept(entry);
} }
} }
@@ -804,7 +961,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
action.accept(i, new BasicEntryKV_BRACES(keys[i], values[i])); action.accept(i, new ValueMapEntry(i));
} }
} }
@@ -812,7 +969,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public <E> void forEach(E input, ObjectObjectConsumer<E, MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public <E> void forEach(E input, ObjectObjectConsumer<E, MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
action.accept(input, new BasicEntryKV_BRACES(keys[i], values[i])); action.accept(input, new ValueMapEntry(i));
} }
} }
@@ -820,9 +977,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return true; if(filter.test(entry)) return true;
} }
return false; return false;
@@ -832,9 +989,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return false; if(filter.test(entry)) return false;
} }
return true; return true;
@@ -844,9 +1001,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
entry.set(keys[i], values[i]); entry.set(i);
if(!filter.test(entry)) return false; if(!filter.test(entry)) return false;
} }
return true; return true;
@@ -857,37 +1014,37 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
Objects.requireNonNull(operator); Objects.requireNonNull(operator);
E state = identity; E state = identity;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
state = operator.apply(state, new BasicEntryKV_BRACES(keys[i], values[i])); state = operator.apply(state, new ValueMapEntry(i));
} }
return state; return state;
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(empty) { if(empty) {
empty = false; empty = false;
state = new BasicEntryKV_BRACES(keys[i], values[i]); state = new ValueMapEntry(i);
continue; continue;
} }
state = operator.apply(state, new BasicEntryKV_BRACES(keys[i], values[i])); state = operator.apply(state, new ValueMapEntry(i));
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) return entry; if(filter.test(entry)) return Optional.ofNullable(entry);
} }
return null; return Optional.empty();
} }
@Override @Override
@@ -895,9 +1052,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
int result = 0; int result = 0;
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
entry.set(keys[i], values[i]); entry.set(i);
if(filter.test(entry)) result++; if(filter.test(entry)) result++;
} }
return result; return result;
@@ -973,6 +1130,10 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override @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(); } public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -981,7 +1142,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public boolean moveToLast(KEY_TYPE o) { return ARRAY_MAP.this.moveToLast(o); } public boolean moveToLast(KEY_TYPE o) { return ARRAY_MAP.this.moveToLast(o); }
@Override @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 @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return new KeyIterator(fromElement); } public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return new KeyIterator(fromElement); }
@Override @Override
@@ -989,13 +1152,13 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public void clear() { ARRAY_MAP.this.clear(); } public void clear() { ARRAY_MAP.this.clear(); }
@Override @Override
public KEY_TYPE FIRST_KEY() { return FIRST_ENTRY_KEY(); } public KEY_TYPE GET_FIRST_KEY() { return FIRST_ENTRY_KEY(); }
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { return POLL_FIRST_ENTRY_KEY(); } public KEY_TYPE REMOVE_FIRST_KEY() { return POLL_FIRST_ENTRY_KEY(); }
@Override @Override
public KEY_TYPE LAST_KEY() { return LAST_ENTRY_KEY(); } public KEY_TYPE GET_LAST_KEY() { return LAST_ENTRY_KEY(); }
@Override @Override
public KEY_TYPE POLL_LAST_KEY() { return POLL_LAST_ENTRY_KEY(); } public KEY_TYPE REMOVE_LAST_KEY() { return POLL_LAST_ENTRY_KEY(); }
@Override @Override
public KeySet copy() { throw new UnsupportedOperationException(); } public KeySet copy() { throw new UnsupportedOperationException(); }
@@ -1070,7 +1233,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1082,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]); state = operator.APPLY_KEY_VALUE(state, keys[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { 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 @Override
@@ -1105,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 #if VALUE_OBJECT
@Override @Override
public boolean contains(Object e) { public boolean contains(Object e) { return containsValue(e); }
return containsValue(e);
}
#else #else
@Override @Override
public boolean contains(VALUE_TYPE e) { public boolean contains(VALUE_TYPE e) { return containsValue(e); }
return containsValue(e);
}
#endif #endif
@Override @Override
public boolean add(VALUE_TYPE o) { public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
throw new UnsupportedOperationException();
}
@Override @Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
return new ValueIterator();
}
@Override @Override
public int size() { public int size() { return ARRAY_MAP.this.size(); }
return ARRAY_MAP.this.size();
}
@Override @Override
public void clear() { public void clear() { ARRAY_MAP.this.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 @Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) { public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1202,7 +1374,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1214,16 +1386,16 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
state = operator.APPLY_VALUE(state, values[i]); state = operator.APPLY_VALUE(state, values[i]);
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { 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 @Override
@@ -1240,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> { private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry(); MapEntry entry = new MapEntry();
public FastEntryIterator() {} public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(KEY_TYPE from) { public FastEntryIterator(KEY_TYPE element) { super(element); }
index = findIndex(from);
}
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
@@ -1266,20 +1436,17 @@ 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> { private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = null; MapEntry entry = null;
public EntryIterator() {} public EntryIterator(boolean start) { super(start); }
public EntryIterator(KEY_TYPE from) { public EntryIterator(KEY_TYPE element) { super(element); }
index = findIndex(from);
if(index == -1) throw new NoSuchElementException();
}
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry()); return entry = new ValueMapEntry(nextEntry());
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() { public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
return entry = new MapEntry(previousEntry()); return entry = new ValueMapEntry(previousEntry());
} }
@Override @Override
@@ -1297,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 { private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {} public KeyIterator(boolean start) { super(start); }
public KeyIterator(KEY_TYPE element) { public KeyIterator(KEY_TYPE element) { super(element); }
index = findIndex(element);
if(index == -1) throw new NoSuchElementException();
}
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
@@ -1321,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 { 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 @Override
public VALUE_TYPE VALUE_PREVIOUS() { public VALUE_TYPE VALUE_PREVIOUS() {
return values[previousEntry()]; return values[previousEntry()];
@@ -1339,23 +1506,37 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
private class MapIterator { private class MapIterator {
boolean forward;
int index; int index;
int lastReturned = -1; 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() { public boolean hasNext() {
return index < size; return forward ? index < size : index > 0;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return index > 0; return forward ? index > 0 : index < size;
} }
public int nextIndex() { public int nextIndex() {
return index; if(forward) return index;
return size - index;
} }
public int previousIndex() { public int previousIndex() {
return index-1; if(forward) return index-1;
return (size - index)-1;
} }
public void remove() { public void remove() {
@@ -1368,26 +1549,42 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public int previousEntry() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
if(forward) {
index--; index--;
return (lastReturned = index); return (lastReturned = index);
} }
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
lastReturned = index; lastReturned = index;
return 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) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); 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); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1); if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps; return steps;
} }
public int back(int amount) { private int moveBackwards(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index); int steps = Math.min(amount, index);
index -= steps; index -= steps;
if(steps > 0) lastReturned = Math.min(index, size()-1); if(steps > 0) lastReturned = Math.min(index, size()-1);
@@ -1395,6 +1592,33 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
} }
protected class ValueMapEntry extends MapEntry {
protected KEY_TYPE key;
protected VALUE_TYPE value;
public ValueMapEntry(int index) {
super(index);
key = keys[index];
value = values[index];
}
@Override
public KEY_TYPE ENTRY_KEY() {
return key;
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return value;
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
this.value = value;
return super.setValue(value);
}
}
private class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> { private class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
int index = -1; int index = -1;
@@ -1403,6 +1627,10 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -1425,19 +1653,19 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
if(obj instanceof Map.Entry) { if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) { if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj; MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE()); return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(ENTRY_VALUE(), entry.ENTRY_VALUE());
} }
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj; Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey(); Object key = entry.getKey();
Object value = entry.getValue(); Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT #if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value); return KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else if TYPE_OBJECT #else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#else if VALUE_OBJECT #else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value); return key instanceof CLASS_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else #else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#endif #endif
} }
return false; return false;
@@ -1445,12 +1673,12 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public int hashCode() { public int hashCode() {
return KEY_TO_HASH(keys[index]) ^ VALUE_TO_HASH(values[index]); return KEY_TO_HASH(ENTRY_KEY()) ^ VALUE_TO_HASH(ENTRY_VALUE());
} }
@Override @Override
public String toString() { public String toString() {
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]); return KEY_TO_STRING(ENTRY_KEY()) + "=" + VALUE_TO_STRING(ENTRY_VALUE());
} }
} }
} }
@@ -363,6 +363,96 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
int index = key.ordinal(); int index = key.ordinal();
if(!isSet(index)) { if(!isSet(index)) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue()); VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
set(index);
values[index] = newValue;
return newValue;
}
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
clear(index);
values[index] = EMPTY_VALUE;
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(T key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal();
if(!isSet(index)) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
set(index);
values[index] = newValue;
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(T key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
int index = key.ordinal();
if(!isSet(index)) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
set(index);
values[index] = newValue;
return newValue;
}
VALUE_TYPE newValue = values[index];
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
#endif
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(T key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal();
#if !VALUE_OBJECT
if(!isSet(index)) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
#else
if(!isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
clear(index);
values[index] = EMPTY_VALUE;
return newValue;
}
#endif
values[index] = newValue;
return newValue;
}
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(T key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal();
if(!isSet(index)) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
set(index); set(index);
values[index] = newValue; values[index] = newValue;
@@ -379,7 +469,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_ABSENT(T key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(T key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal(); int index = key.ordinal();
if(!isSet(index)) { if(!isSet(index)) {
VALUE_TYPE newValue = mappingFunction.APPLY(key); VALUE_TYPE newValue = mappingFunction.APPLY(key);
@@ -398,7 +488,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
} }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(T key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(T key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
int index = key.ordinal(); int index = key.ordinal();
if(!isSet(index)) { if(!isSet(index)) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET(); VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
@@ -417,7 +507,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(T key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(T key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal(); int index = key.ordinal();
if(!isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue(); if(!isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]); VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
@@ -430,6 +520,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
return newValue; return newValue;
} }
#endif
@Override @Override
public VALUE_TYPE MERGE(T key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(T key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal(); int index = key.ordinal();
@@ -547,7 +638,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
if(size() <= 0) return; if(size() <= 0) return;
for(int i = 0,m=keys.length;i<m;i++) { for(int i = 0,m=keys.length;i<m;i++) {
if(isSet(i)) action.accept(new BasicEntryKV_BRACES(keys[i], values[i])); if(isSet(i)) action.accept(new ValueMapEntry(i));
} }
} }
@@ -630,7 +721,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
class EntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> { class EntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return new MapEntry(nextEntry()); return new ValueMapEntry(nextEntry());
} }
} }
@@ -677,6 +768,33 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
} }
} }
protected class ValueMapEntry extends MapEntry {
protected KEY_TYPE key;
protected VALUE_TYPE value;
public ValueMapEntry(int index) {
super(index);
key = keys[index];
value = values[index];
}
@Override
public KEY_TYPE ENTRY_KEY() {
return key;
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return value;
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
this.value = value;
return super.setValue(value);
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> { protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
public int index = -1; public int index = -1;
@@ -685,6 +803,10 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -707,19 +829,19 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
if(obj instanceof Map.Entry) { if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) { if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj; MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE()); return KEY_EQUALS(ENTRY_KEY(), entry.ENTRY_KEY()) && VALUE_EQUALS(ENTRY_VALUE(), entry.ENTRY_VALUE());
} }
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj; Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey(); Object key = entry.getKey();
Object value = entry.getValue(); Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT #if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value); return KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else if TYPE_OBJECT #else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#else if VALUE_OBJECT #else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value); return key instanceof CLASS_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else #else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#endif #endif
} }
return false; return false;
@@ -727,12 +849,12 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override @Override
public int hashCode() { public int hashCode() {
return KEY_TO_HASH(keys[index]) ^ VALUE_TO_HASH(values[index]); return KEY_TO_HASH(ENTRY_KEY()) ^ VALUE_TO_HASH(ENTRY_VALUE());
} }
@Override @Override
public String toString() { public String toString() {
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]); return KEY_TO_STRING(ENTRY_KEY()) + "=" + VALUE_TO_STRING(ENTRY_VALUE());
} }
} }
} }
@@ -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.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_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_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.collections.VALUE_ITERATOR;
#if !VALUE_OBJECT && !SAME_TYPE #if !VALUE_OBJECT && !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER; 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(); 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 @Override
public boolean moveToFirst(T key) { public boolean moveToFirst(T key) {
int index = key.ordinal(); 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]; 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 @Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet(); 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 @Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values(); if(valuesC == null) valuesC = new Values();
return valuesC; return (VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE)valuesC;
} }
@Override @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 { 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 @Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -431,24 +493,24 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
} }
@Override @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()); return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
} }
@Override @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()); return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
} }
@Override @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()); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY(); POLL_FIRST_ENTRY_KEY();
return entry; return entry;
} }
@Override @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()); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY(); POLL_LAST_ENTRY_KEY();
return entry; return entry;
@@ -456,7 +518,12 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { 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 @Override
@@ -466,7 +533,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() { public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator(); return new FastEntryIterator(true);
} }
@Override @Override
@@ -480,17 +547,17 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
action.accept(new BasicEntryKV_BRACES(keys[index], values[index])); action.accept(new ValueMapEntry(index));
index = (int)links[index]; index = (int)links[index];
} }
} }
@Override @Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(); MapEntry entry = new MapEntry();
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
entry.set(keys[index], values[index]); entry.set(index);
action.accept(entry); action.accept(entry);
index = (int)links[index]; index = (int)links[index];
} }
@@ -574,7 +641,10 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
public boolean add(T o) { public boolean add(T o) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void addFirst(T o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(T o) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean addAndMoveToFirst(T o) { throw new UnsupportedOperationException(); } 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 @Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { 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 @Override
@@ -614,22 +689,22 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
} }
@Override @Override
public T FIRST_KEY() { public T GET_FIRST_KEY() {
return FIRST_ENTRY_KEY(); return FIRST_ENTRY_KEY();
} }
@Override @Override
public T POLL_FIRST_KEY() { public T REMOVE_FIRST_KEY() {
return POLL_FIRST_ENTRY_KEY(); return POLL_FIRST_ENTRY_KEY();
} }
@Override @Override
public T LAST_KEY() { public T GET_LAST_KEY() {
return LAST_ENTRY_KEY(); return LAST_ENTRY_KEY();
} }
@Override @Override
public T POLL_LAST_KEY() { public T REMOVE_LAST_KEY() {
return POLL_LAST_ENTRY_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 #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 #if VALUE_OBJECT
@Override @Override
@Deprecated @Deprecated
public boolean contains(Object e) { public boolean contains(Object e) { return containsValue(e); }
return containsValue(e);
}
#else #else
@Override @Override
public boolean contains(VALUE_TYPE e) { public boolean contains(VALUE_TYPE e) { return containsValue(e); }
return containsValue(e);
}
#endif #endif
@Override @Override
public boolean add(VALUE_TYPE o) { public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
throw new UnsupportedOperationException();
}
@Override @Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return new ValueIterator(true); }
return new ValueIterator();
}
@Override @Override
public int size() { public int size() { return LINKED_ENUM_MAP.this.size(); }
return LINKED_ENUM_MAP.this.size();
}
@Override @Override
public void clear() { public void clear() { LINKED_ENUM_MAP.this.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 #if VALUE_OBJECT
@Override @Override
public void forEach(Consumer VALUE_SUPER_GENERIC_TYPE action) { 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> { private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry(); MapEntry entry = new MapEntry();
public FastEntryIterator() {} public FastEntryIterator(boolean start) { super(start); }
public FastEntryIterator(T from) { public FastEntryIterator(T from) {
super(from); super(from);
} }
@@ -742,19 +826,19 @@ 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> { private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry; MapEntry entry;
public EntryIterator() {} public EntryIterator(boolean start) { super(start); }
public EntryIterator(T from) { public EntryIterator(T from) {
super(from); super(from);
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry()); return entry = new ValueMapEntry(nextEntry());
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() { public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
return entry = new MapEntry(previousEntry()); return entry = new ValueMapEntry(previousEntry());
} }
@Override @Override
@@ -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 { private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {} public KeyIterator(boolean start) { super(start); }
public KeyIterator(T from) { public KeyIterator(T from) {
super(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 { private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {} public ValueIterator(boolean start) { super(start); }
@Override @Override
public VALUE_TYPE VALUE_PREVIOUS() { 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 { private class MapIterator {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = 0;
MapIterator() { MapIterator(boolean start) {
next = firstIndex; this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
} }
MapIterator(T from) { MapIterator(T from) {
this.forward = true;
previous = from.ordinal() - 1; previous = from.ordinal() - 1;
index = from.ordinal(); index = from.ordinal();
next = 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() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
public int nextIndex() { 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() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return current; return current;
} }
public int nextEntry() { public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException(); 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; current = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current; previous = current;
if(index >= 0) index++;
return current;
} }
private void ensureIndexKnown() { private void ensureIndexKnown() {
@@ -903,6 +1001,33 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
} }
} }
protected class ValueMapEntry extends MapEntry {
protected KEY_TYPE key;
protected VALUE_TYPE value;
public ValueMapEntry(int index) {
super(index);
key = keys[index];
value = values[index];
}
@Override
public KEY_TYPE ENTRY_KEY() {
return key;
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return value;
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
this.value = value;
return super.setValue(value);
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> { protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
public int index = -1; public int index = -1;
@@ -911,6 +1036,10 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -933,19 +1062,19 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
if(obj instanceof Map.Entry) { if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) { if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj; MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE()); return KEY_EQUALS(ENTRY_KEY(), entry.ENTRY_KEY()) && VALUE_EQUALS(ENTRY_VALUE(), entry.ENTRY_VALUE());
} }
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj; Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey(); Object key = entry.getKey();
Object value = entry.getValue(); Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT #if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value); return KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else if TYPE_OBJECT #else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), key) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#else if VALUE_OBJECT #else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value); return key instanceof CLASS_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), value);
#else #else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value)); return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(ENTRY_KEY(), CLASS_TO_KEY(key)) && VALUE_EQUALS(ENTRY_VALUE(), CLASS_TO_VALUE(value));
#endif #endif
} }
return false; return false;
@@ -953,12 +1082,12 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override @Override
public int hashCode() { public int hashCode() {
return KEY_TO_HASH(keys[index]) ^ VALUE_TO_HASH(values[index]); return KEY_TO_HASH(ENTRY_KEY()) ^ VALUE_TO_HASH(ENTRY_VALUE());
} }
@Override @Override
public String toString() { public String toString() {
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]); return KEY_TO_STRING(ENTRY_KEY()) + "=" + VALUE_TO_STRING(ENTRY_VALUE());
} }
} }
} }
@@ -6,15 +6,18 @@ import java.util.Map;
import java.util.Comparator; import java.util.Comparator;
#endif #endif
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
@@ -28,16 +31,21 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #endif
#if !VALUE_BOOLEAN || !JDK_TYPE #if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE #endif
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if!VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
@@ -71,6 +79,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif #endif
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
@@ -544,6 +553,105 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT #if TYPE_OBJECT
validate(key); validate(key);
#endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
put(key, newValue);
return newValue;
}
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeNode(entry);
return newValue;
}
#endif
entry.value = newValue;
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
validate(key);
#endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
put(key, newValue);
return newValue;
}
#if VALUE_OBJECT
if(Objects.equals(entry.value, getDefaultReturnValue())) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
entry.value = newValue;
}
#endif
return entry.value;
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
#if TYPE_OBJECT
validate(key);
#endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
put(key, newValue);
return newValue;
}
#if VALUE_OBJECT
if(VALUE_EQUALS(entry.value, getDefaultReturnValue())) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
entry.value = newValue;
}
#endif
return entry.value;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
validate(key);
#endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
#if !VALUE_OBJECT
if(entry == null) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
#else
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeNode(entry);
return newValue;
}
#endif
entry.value = newValue;
return newValue;
}
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
validate(key);
#endif #endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key); Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) { if(entry == null) {
@@ -562,7 +670,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT #if TYPE_OBJECT
validate(key); validate(key);
@@ -583,7 +691,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
} }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider); Objects.requireNonNull(valueProvider);
#if TYPE_OBJECT #if TYPE_OBJECT
validate(key); validate(key);
@@ -604,7 +712,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT #if TYPE_OBJECT
validate(key); validate(key);
@@ -620,6 +728,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
return newValue; return newValue;
} }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -1221,7 +1330,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1233,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); state = operator.APPLY_KEY_VALUE(state, entry.key);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry)) 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; if(filter.test(entry.key)) return OPTIONAL.GET_OPTIONAL(entry.key);
return EMPTY_KEY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -1669,6 +1778,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
#endif #endif
if(!inRange(key)) return getDefaultReturnValue(); if(!inRange(key)) return getDefaultReturnValue();
Node KEY_VALUE_GENERIC_TYPE entry = map.findNode(key); Node KEY_VALUE_GENERIC_TYPE entry = map.findNode(key);
#if VALUE_OBJECT
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue(); if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.apply(key, entry.value); VALUE_TYPE newValue = mappingFunction.apply(key, entry.value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
@@ -1677,6 +1787,11 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
} }
entry.value = newValue; entry.value = newValue;
return newValue; return newValue;
#else
if(entry == null) return getDefaultReturnValue();
entry.value = mappingFunction.apply(key, entry.value);
return entry.value;
#endif
} }
@Override @Override
@@ -1918,7 +2033,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
@@ -1930,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)); state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES(); 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)) { 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); 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 @Override
@@ -2057,7 +2172,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -2069,15 +2184,15 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
} }
state = operator.APPLY_VALUE(state, entry.value); state = operator.APPLY_VALUE(state, entry.value);
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) 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; if(filter.test(entry.value)) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(entry.value);
return EMPTY_VALUE; return VALUE_OPTIONAL.empty();
} }
@Override @Override
@@ -2413,7 +2528,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -2425,15 +2540,15 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
} }
state = operator.APPLY_VALUE(state, entry.value); state = operator.APPLY_VALUE(state, entry.value);
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
if(filter.test(entry.value)) return entry.value; if(filter.test(entry.value)) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(entry.value);
return EMPTY_VALUE; return VALUE_OPTIONAL.empty();
} }
@Override @Override
@@ -2579,7 +2694,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
@@ -2591,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)); state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES(); BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
subEntry.set(entry.key, entry.value); 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 @Override
@@ -6,15 +6,18 @@ import java.util.Map;
import java.util.Comparator; import java.util.Comparator;
#endif #endif
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE #if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
import java.util.OPTIONAL;
#endif #endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT #if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE; import java.util.function.VALUE_PREDICATE;
import java.util.VALUE_OPTIONAL;
#endif #endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -27,16 +30,21 @@ import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer; import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif #endif
#if !SAME_TYPE #if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER; import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif #endif
#if !VALUE_BOOLEAN || !JDK_TYPE #if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE #endif
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#if!VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
@@ -70,6 +78,7 @@ import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_C
#endif #endif
#if !JDK_VALUE #if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_OPTIONAL;
#endif #endif
#endif #endif
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
@@ -546,6 +555,105 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT #if TYPE_OBJECT
validate(key); validate(key);
#endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
put(key, newValue);
return newValue;
}
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeNode(entry);
return newValue;
}
#endif
entry.value = newValue;
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
validate(key);
#endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
put(key, newValue);
return newValue;
}
#if VALUE_OBJECT
if(Objects.equals(entry.value, getDefaultReturnValue())) {
VALUE_TYPE newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
entry.value = newValue;
}
#endif
return entry.value;
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
#if TYPE_OBJECT
validate(key);
#endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
#if VALUE_OBJECT
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
#endif
put(key, newValue);
return newValue;
}
#if VALUE_OBJECT
if(VALUE_EQUALS(entry.value, getDefaultReturnValue())) {
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
entry.value = newValue;
}
#endif
return entry.value;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
validate(key);
#endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
#if !VALUE_OBJECT
if(entry == null) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
#else
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeNode(entry);
return newValue;
}
#endif
entry.value = newValue;
return newValue;
}
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
validate(key);
#endif #endif
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key); Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) { if(entry == null) {
@@ -564,7 +672,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT #if TYPE_OBJECT
validate(key); validate(key);
@@ -585,7 +693,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
} }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider); Objects.requireNonNull(valueProvider);
#if TYPE_OBJECT #if TYPE_OBJECT
validate(key); validate(key);
@@ -606,7 +714,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT #if TYPE_OBJECT
validate(key); validate(key);
@@ -622,6 +730,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
return newValue; return newValue;
} }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -1277,7 +1386,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_KEY_VALUE; KEY_TYPE state = EMPTY_KEY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1289,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); state = operator.APPLY_KEY_VALUE(state, entry.key);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry)) 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; if(filter.test(entry.key)) return OPTIONAL.GET_OPTIONAL(entry.key);
return EMPTY_KEY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -1735,6 +1844,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
#endif #endif
if(!inRange(key)) return getDefaultReturnValue(); if(!inRange(key)) return getDefaultReturnValue();
Node KEY_VALUE_GENERIC_TYPE entry = map.findNode(key); Node KEY_VALUE_GENERIC_TYPE entry = map.findNode(key);
#if VALUE_OBJECT
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue(); if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.apply(key, entry.value); VALUE_TYPE newValue = mappingFunction.apply(key, entry.value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
@@ -1743,6 +1853,11 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
} }
entry.value = newValue; entry.value = newValue;
return newValue; return newValue;
#else
if(entry == null) return getDefaultReturnValue();
entry.value = mappingFunction.apply(key, entry.value);
return entry.value;
#endif
} }
@Override @Override
@@ -1984,7 +2099,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
@@ -1996,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)); state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES(); 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)) { 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); 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 @Override
@@ -2123,7 +2238,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -2135,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); state = operator.APPLY_VALUE(state, entry.value);
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) 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; if(filter.test(entry.value)) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(entry.value);
return EMPTY_VALUE; return VALUE_OPTIONAL.empty();
} }
@Override @Override
@@ -2479,7 +2594,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
#endif #endif
@Override @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); Objects.requireNonNull(operator);
VALUE_TYPE state = EMPTY_VALUE; VALUE_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -2491,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); state = operator.APPLY_VALUE(state, entry.value);
} }
return state; return empty ? VALUE_OPTIONAL.empty() : VALUE_OPTIONAL.GET_OPTIONAL_VALUE(state);
} }
@Override @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); Objects.requireNonNull(filter);
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
if(filter.test(entry.value)) return entry.value; if(filter.test(entry.value)) return VALUE_OPTIONAL.GET_OPTIONAL_VALUE(entry.value);
return EMPTY_VALUE; return VALUE_OPTIONAL.empty();
} }
@Override @Override
@@ -2645,7 +2760,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
} }
@Override @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); Objects.requireNonNull(operator);
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null; MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
boolean empty = true; boolean empty = true;
@@ -2657,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)); state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
} }
return state; return empty ? Optional.empty() : Optional.ofNullable(state);
} }
@Override @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); Objects.requireNonNull(filter);
if(size() <= 0) return null; if(size() <= 0) return Optional.empty();
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES(); BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
subEntry.set(entry.key, entry.value); 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 @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. * @return the last present value or default return value.
*/ */
public default CLASS_VALUE_TYPE put(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) { 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 #endif
@@ -382,21 +382,26 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction); public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
/** /**
* A Type Specific compute method to reduce boxing/unboxing * A Type Specific compute method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed * @param key the key that should be computed
* @param mappingFunction the operator that should generate the value * @param mappingFunction the operator that should generate the value
* @return the result of the computation * @return the result of the computation
*/ */
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction); public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
/** /**
* A Type Specific compute method to reduce boxing/unboxing * A Type Specific computeIfAbsent method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed * @param key the key that should be computed
* @param mappingFunction the operator that should generate the value if not present * @param mappingFunction the operator that should generate the value if not present
* @return the result of the computed value or present value * @return the result of the computed value or present value
*/ */
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction); public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction);
/** /**
* A Supplier based computeIfAbsent function to fill the most used usecase of this function * A Supplier based computeIfAbsent function to fill the most used usecase of this function
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed * @param key the key that should be computed
* @param valueProvider the value if not present * @param valueProvider the value if not present
* @return the result of the computed value or present value * @return the result of the computed value or present value
@@ -404,14 +409,57 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider); public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider);
/** /**
* A Type Specific compute method to reduce boxing/unboxing * A Type Specific compute method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed * @param key the key that should be computed
* @param mappingFunction the operator that should generate the value if present * @param mappingFunction the operator that should generate the value if present
* @return the result of the default return value or present value * @return the result of the default return value or present value
* @note if not present then compute is not executed * @note if not present then compute is not executed
*/ */
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction); public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
#if !VALUE_OBJECT
/**
* A Type Specific compute method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed
* @param mappingFunction the operator that should generate the value
* @return the result of the computation
*/
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
/**
* A Type Specific computeIfAbsent method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed
* @param mappingFunction the operator that should generate the value if not present
* @return the result of the computed value or present value
*/
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction);
/**
* A Supplier based computeIfAbsent function to fill the most used usecase of this function
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed
* @param valueProvider the value if not present
* @return the result of the computed value or present value
*/
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider);
/**
* A Type Specific compute method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed
* @param mappingFunction the operator that should generate the value if present
* @return the result of the default return value or present value
* @note if not present then compute is not executed
*/
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
#endif
/** /**
* A Type Specific merge method to reduce boxing/unboxing * A Type Specific merge method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be be searched for * @param key the key that should be be searched for
* @param value the value that should be merged with * @param value the value that should be merged with
* @param mappingFunction the operator that should generate the new Value * @param mappingFunction the operator that should generate the new Value
@@ -421,6 +469,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction); public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction);
/** /**
* A Bulk method for merging Maps. * A Bulk method for merging Maps.
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param m the entries that should be bulk added * @param m the entries that should be bulk added
* @param mappingFunction the operator that should generate the new Value * @param mappingFunction the operator that should generate the new Value
* @note if the result matches the default return value then the key is removed from the map * @note if the result matches the default return value then the key is removed from the map
@@ -1,8 +1,15 @@
package speiger.src.collections.PACKAGE.maps.interfaces; package speiger.src.collections.PACKAGE.maps.interfaces;
#if JAVA_VERSION>=21
import java.util.Map;
import java.util.SequencedMap;
#endif
#if MAPS_FEATURE #if MAPS_FEATURE
import speiger.src.collections.PACKAGE.utils.maps.MAPS; import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#endif #endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ORDERED_COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ORDERED_SET; import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
#endif #endif
@@ -17,7 +24,11 @@ import speiger.src.collections.objects.sets.ObjectOrderedSet;
* @Type(T) * @Type(T)
* @ValueType(V) * @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 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. * 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); 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. * A specific move method to move a given key/value to the first index.
* @param key that should be moved 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(); 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 @Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy(); public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy();
@Override @Override
public ORDERED_SET KEY_GENERIC_TYPE keySet(); public ORDERED_SET KEY_GENERIC_TYPE keySet();
@Override @Override
public VALUE_ORDERED_COLLECTION VALUE_GENERIC_TYPE values();
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET(); 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 #if MAPS_FEATURE
/** /**
* Creates a Wrapped SortedMap that is Synchronized * 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 @Override
public default ORDERED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); } 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 #endif
/** /**
* Fast Ordered Entry Set that allows for a faster Entry Iterator by recycling the Entry Object and just exchanging 1 internal value * 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; import java.util.function.BiFunction;
#endif #endif
import java.util.Objects; 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; import java.util.NoSuchElementException;
#if JDK_FUNCTION #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; 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); 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 @Override
public ITERATOR KEY_GENERIC_TYPE iterator() { public ITERATOR KEY_GENERIC_TYPE iterator() {
return new Iter(); return new Iter();
@@ -168,6 +223,15 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
return index >= array.length ? array[index-array.length] : array[index]; return index >= array.length ? array[index-array.length] : array[index];
} }
@Override
public boolean contains(KEY_TYPE e) {
if(first == last) return false;
for(int i = 0,m=size();i<m;i++) {
if(e == array[(first + i) % array.length]) return true;
}
return false;
}
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
if(first == last) return false; if(first == last) return false;
@@ -309,17 +373,17 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) { for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length; int index = (first + i) % array.length;
if(filter.test(array[index])) { if(filter.test(array[index])) {
KEY_TYPE data = array[index]; KEY_TYPE data = array[index];
removeIndex(index); removeIndex(index);
return data; return OPTIONAL.GET_OPTIONAL(data);
} }
} }
return EMPTY_VALUE; return OPTIONAL.empty();
} }
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -346,7 +410,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -358,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]); state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
@@ -8,12 +8,26 @@ import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#endif #endif
import java.util.Objects; 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 #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; 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; queue.size = size;
return queue; 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 @Override
public void enqueue(KEY_TYPE e) { 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)); 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));
@@ -228,6 +282,13 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
return array[index]; return array[index];
} }
@Override
public boolean contains(KEY_TYPE e) {
for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return true;
return false;
}
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
@@ -339,7 +400,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -351,20 +412,20 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
} }
state = operator.APPLY_VALUE(state, array[i]); state = operator.APPLY_VALUE(state, array[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.test(array[i])) { if(filter.test(array[i])) {
KEY_TYPE data = array[i]; KEY_TYPE data = array[i];
removeIndex(i); removeIndex(i);
return data; return OPTIONAL.GET_OPTIONAL(data);
} }
} }
return EMPTY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -8,12 +8,26 @@ import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#endif #endif
import java.util.Objects; 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 #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; 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; 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 @Override
public int size() { public int size() {
return size; return size;
@@ -236,6 +291,13 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
return array[index]; return array[index];
} }
@Override
public boolean contains(KEY_TYPE e) {
for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return true;
return false;
}
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
@@ -319,7 +381,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -331,20 +393,20 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
} }
state = operator.APPLY_VALUE(state, array[i]); state = operator.APPLY_VALUE(state, array[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.test(array[i])) { if(filter.test(array[i])) {
KEY_TYPE data = array[i]; KEY_TYPE data = array[i];
removeIndex(i); removeIndex(i);
return data; return OPTIONAL.GET_OPTIONAL(data);
} }
} }
return EMPTY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -111,6 +111,13 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY
*/ */
public default KEY_TYPE first() { return peek(0); } public default KEY_TYPE first() { return peek(0); }
/**
* Method to find out if a element is part of the queue
* @param e the element that is searched for
* @return true if the element is in the queue
*/
public boolean contains(KEY_TYPE e);
/** /**
* Removes the first found element in the queue * Removes the first found element in the queue
* @param e the element that should be removed * @param e the element that should be removed
@@ -185,6 +192,7 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY
/** /**
* A Helper function that simplifies the process of creating a new Array. * A Helper function that simplifies the process of creating a new Array.
* @param action the array creation function * @param action the array creation function
* @param <E> the returning arrayType
* @return an array containing all of the elements in this collection * @return an array containing all of the elements in this collection
* @see Collection#toArray(Object[]) * @see Collection#toArray(Object[])
*/ */
@@ -10,6 +10,15 @@ import java.util.function.BiFunction;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; 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 #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #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.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #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.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION #if !JDK_FUNCTION
@@ -27,6 +39,7 @@ import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
@@ -207,6 +220,42 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
while(iterator.hasNext()) add(iterator.NEXT()); 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 #if !TYPE_OBJECT
@Override @Override
public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; } public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; }
@@ -404,12 +453,12 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { 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 #if !TYPE_OBJECT
@@ -436,7 +485,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -448,7 +497,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
state = operator.APPLY_VALUE(state, entry.key); state = operator.APPLY_VALUE(state, entry.key);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
@@ -651,6 +700,44 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
tree = null; tree = null;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
a[index++] = entry.key;
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
obj[index++] = KEY_TO_OBJ(entry.key);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
a[index++] = (E)KEY_TO_OBJ(entry.key);
}
if (a.length > size) a[size] = null;
return a;
}
public AVL_TREE_SET KEY_GENERIC_TYPE copy() { public AVL_TREE_SET KEY_GENERIC_TYPE copy() {
AVL_TREE_SET KEY_GENERIC_TYPE set = new AVL_TREE_SETBRACES(); AVL_TREE_SET KEY_GENERIC_TYPE set = new AVL_TREE_SETBRACES();
set.size = size; set.size = size;
@@ -1275,7 +1362,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1287,16 +1374,16 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
state = operator.APPLY_VALUE(state, entry.key); state = operator.APPLY_VALUE(state, entry.key);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { 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 @Override
@@ -6,6 +6,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.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; 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 #endif
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; 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; import java.util.Set;
#if JDK_FUNCTION #if JDK_FUNCTION
import java.util.function.PREDICATE; 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.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; 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.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION #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. * @param array the array that should be used for set.
*/ */
public ARRAY_SET(KEY_TYPE[] array) { 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); 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. * 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. * @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()); 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 @Override
public boolean add(KEY_TYPE o) { public boolean add(KEY_TYPE o) {
int index = findIndex(o); int index = findIndex(o);
@@ -148,6 +207,25 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
} }
#endif #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 @Override
public boolean addAndMoveToFirst(KEY_TYPE o) { public boolean addAndMoveToFirst(KEY_TYPE o) {
int index = findIndex(o); int index = findIndex(o);
@@ -219,13 +297,13 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
#endif #endif
@Override @Override
public KEY_TYPE FIRST_KEY() { public KEY_TYPE GET_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
return data[0]; return data[0];
} }
@Override @Override
public KEY_TYPE LAST_KEY() { public KEY_TYPE GET_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
return data[size - 1]; return data[size - 1];
} }
@@ -354,7 +432,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
#endif #endif
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { public KEY_TYPE REMOVE_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
KEY_TYPE result = data[0]; KEY_TYPE result = data[0];
System.arraycopy(data, 1, data, 0, --size); 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 @Override
public KEY_TYPE POLL_LAST_KEY() { public KEY_TYPE REMOVE_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
size--; size--;
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -438,12 +516,12 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { 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 #if !TYPE_OBJECT
@@ -470,7 +548,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; 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]); state = operator.APPLY_VALUE(state, data[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
@@ -511,13 +589,18 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { 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 @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
int index = findIndex(fromElement); int index = findIndex(fromElement);
if(index != -1) return new SetIterator(index); if(index != -1) return new SetIterator(true, index);
throw new NoSuchElementException(); 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 { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int index; int index;
int lastReturned = -1; int lastReturned = -1;
public SetIterator(int index) { public SetIterator(boolean forward, int index) {
this.forward = forward;
this.index = index; this.index = index;
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return index < size(); return forward ? index < size() : index > 0;
} }
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
if(forward) {
lastReturned = index; lastReturned = index;
return data[index++]; return data[index++];
} }
index--;
return data[(lastReturned = index)];
}
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return index > 0; return forward ? index > 0 : index < size();
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
--index; if(forward) {
index--;
return data[(lastReturned = index)]; return data[(lastReturned = index)];
} }
lastReturned = index;
return data[index++];
}
@Override @Override
public int nextIndex() { public int nextIndex() {
return index; if(forward) return index;
return size - index;
} }
@Override @Override
public int previousIndex() { public int previousIndex() {
return index-1; if(forward) return index-1;
return (size - index)-1;
} }
@Override @Override
@@ -637,15 +732,23 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override @Override
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); 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); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1); if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps; return steps;
} }
@Override private int moveBackwards(int amount) {
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index); int steps = Math.min(amount, index);
index -= steps; index -= steps;
if(steps > 0) lastReturned = Math.min(index, size()-1); if(steps > 0) lastReturned = Math.min(index, size()-1);
@@ -9,6 +9,9 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#endif
#if JDK_FUNCTION #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #endif
@@ -19,6 +22,9 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #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.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION #if !JDK_FUNCTION
@@ -27,6 +33,9 @@ import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#if !TYPE_OBJECT
import speiger.src.collections.objects.utils.ObjectArrays;
#endif
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
@@ -255,6 +264,10 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override @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(); } public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@@ -282,22 +295,22 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
} }
@Override @Override
public KEY_TYPE FIRST_KEY() { public KEY_TYPE GET_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
return keys[firstIndex]; return keys[firstIndex];
} }
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE REMOVE_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public KEY_TYPE LAST_KEY() { public KEY_TYPE GET_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
return keys[lastIndex]; return keys[lastIndex];
} }
@Override @Override
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE REMOVE_LAST_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public boolean remove(Object o) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { throw new UnsupportedOperationException(); }
@@ -411,7 +424,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -424,18 +437,18 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
else state = operator.APPLY_VALUE(state, keys[index]); else state = operator.APPLY_VALUE(state, keys[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { 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]; index = (int)links[index];
} }
return EMPTY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -452,7 +465,12 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { 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 @Override
@@ -460,6 +478,41 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
return new SetIterator(fromElement); return new SetIterator(fromElement);
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = keys[index];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
obj[i] = KEY_TO_OBJ(keys[index]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = (E)KEY_TO_OBJ(keys[index]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public IMMUTABLE_HASH_SET KEY_GENERIC_TYPE copy() { public IMMUTABLE_HASH_SET KEY_GENERIC_TYPE copy() {
IMMUTABLE_HASH_SET KEY_GENERIC_TYPE set = new IMMUTABLE_HASH_SETBRACES(); IMMUTABLE_HASH_SET KEY_GENERIC_TYPE set = new IMMUTABLE_HASH_SETBRACES();
@@ -483,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 { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = -1;
SetIterator() { SetIterator(boolean start) {
next = firstIndex; this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
} }
SetIterator(KEY_TYPE from) { SetIterator(KEY_TYPE from) {
this.forward = true;
if(KEY_EQUALS_NULL(from)) { if(KEY_EQUALS_NULL(from)) {
if(containsNull) { if(containsNull) {
next = (int) links[nullIndex]; next = (int) links[nullIndex];
@@ -521,48 +578,60 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public int skip(int amount) { public int skip(int amount) {
int result = 0; int result = forward ? moveForward(amount) : moveBackwards(amount);
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result; if(index >= 0) index+=result;
return result; return result;
} }
@Override @Override
public int back(int amount) { 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; int result = 0;
while(previous != -1 && result != amount) { while(previous != -1 && result != amount) {
current = next = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
result++; result++;
} }
if(index >= 0) index-=result;
return result; return result;
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
@Override @Override
public int nextIndex() { public int nextIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index; if(forward) return index;
return size - index;
} }
@Override @Override
public int previousIndex() { public int previousIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index - 1; if(forward) return index-1;
return (size - index)-1;
} }
@Override @Override
@@ -571,8 +640,8 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@@ -580,12 +649,22 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = previous = next; if(forward) moveForwards();
next = (int)(links[current]); else moveBackwards();
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; 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() { private void ensureIndexKnown() {
if(index == -1) { if(index == -1) {
if(previous == -1) { if(previous == -1) {
@@ -9,6 +9,15 @@ import java.util.Objects;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; 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 #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #endif
@@ -18,6 +27,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#endif #endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; 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; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
@@ -28,6 +40,7 @@ import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUME
#if !JDK_FUNCTION #if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.utils.STRATEGY; import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
@@ -234,6 +247,82 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
} }
#endif #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 @Override
public boolean addAndMoveToFirst(KEY_TYPE o) { public boolean addAndMoveToFirst(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) { if(strategy.equals(o, EMPTY_KEY_VALUE)) {
@@ -290,7 +379,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public boolean moveToFirst(KEY_TYPE o) { 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(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex);
@@ -312,7 +401,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public boolean moveToLast(KEY_TYPE o) { 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(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex);
@@ -369,13 +458,13 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
} }
@Override @Override
public KEY_TYPE FIRST_KEY() { public KEY_TYPE GET_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
return keys[firstIndex]; return keys[firstIndex];
} }
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { public KEY_TYPE REMOVE_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = firstIndex; int pos = firstIndex;
onNodeRemoved(pos); onNodeRemoved(pos);
@@ -391,13 +480,13 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
} }
@Override @Override
public KEY_TYPE LAST_KEY() { public KEY_TYPE GET_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
return keys[lastIndex]; return keys[lastIndex];
} }
@Override @Override
public KEY_TYPE POLL_LAST_KEY() { public KEY_TYPE REMOVE_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = lastIndex; int pos = lastIndex;
onNodeRemoved(pos); onNodeRemoved(pos);
@@ -528,6 +617,41 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
containsNull = false; containsNull = false;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = keys[index];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
obj[i] = KEY_TO_OBJ(keys[index]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = (E)KEY_TO_OBJ(keys[index]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -620,7 +744,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -633,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]); else state = operator.APPLY_VALUE(state, keys[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { 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]; index = (int)links[index];
} }
return EMPTY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -661,7 +785,12 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { 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 @Override
@@ -686,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 { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = -1;
SetIterator() { SetIterator(boolean start) {
next = firstIndex; this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
} }
SetIterator(KEY_TYPE from) { SetIterator(KEY_TYPE from) {
this.forward = true;
if(strategy.equals(from, EMPTY_KEY_VALUE)) { if(strategy.equals(from, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
next = (int) links[nullIndex]; next = (int) links[nullIndex];
@@ -724,48 +857,60 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
@Override @Override
public int skip(int amount) { public int skip(int amount) {
int result = 0; int result = forward ? moveForward(amount) : moveBackwards(amount);
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result; if(index >= 0) index+=result;
return result; return result;
} }
@Override @Override
public int back(int amount) { 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; int result = 0;
while(previous != -1 && result != amount) { while(previous != -1 && result != amount) {
current = next = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
result++; result++;
} }
if(index >= 0) index-=result;
return result; return result;
} }
@Override @Override
public int nextIndex() { public int nextIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index; if(forward) return index;
return size - index;
} }
@Override @Override
public int previousIndex() { public int previousIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index - 1; if(forward) return index-1;
return (size - index)-1;
} }
@Override @Override
@@ -814,8 +959,8 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@@ -823,12 +968,22 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = previous = next; if(forward) moveForwards();
next = (int)(links[current]); else moveBackwards();
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; 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() { private void ensureIndexKnown() {
if(index == -1) { if(index == -1) {
if(previous == -1) { if(previous == -1) {
@@ -5,6 +5,15 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; 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 #if TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@@ -21,6 +30,9 @@ import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #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.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION #if !JDK_FUNCTION
@@ -31,6 +43,7 @@ import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@@ -205,6 +218,82 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
} }
#endif #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 @Override
public boolean addAndMoveToFirst(KEY_TYPE o) { public boolean addAndMoveToFirst(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) { if(KEY_EQUALS_NULL(o)) {
@@ -261,7 +350,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public boolean moveToFirst(KEY_TYPE o) { 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(KEY_EQUALS_NULL(o)) {
if(containsNull) { if(containsNull) {
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex);
@@ -283,7 +372,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public boolean moveToLast(KEY_TYPE o) { 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(KEY_EQUALS_NULL(o)) {
if(containsNull) { if(containsNull) {
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex);
@@ -340,13 +429,13 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
} }
@Override @Override
public KEY_TYPE FIRST_KEY() { public KEY_TYPE GET_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
return keys[firstIndex]; return keys[firstIndex];
} }
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { public KEY_TYPE REMOVE_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = firstIndex; int pos = firstIndex;
onNodeRemoved(pos); onNodeRemoved(pos);
@@ -362,13 +451,13 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
} }
@Override @Override
public KEY_TYPE LAST_KEY() { public KEY_TYPE GET_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
return keys[lastIndex]; return keys[lastIndex];
} }
@Override @Override
public KEY_TYPE POLL_LAST_KEY() { public KEY_TYPE REMOVE_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = lastIndex; int pos = lastIndex;
onNodeRemoved(pos); onNodeRemoved(pos);
@@ -383,6 +472,41 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
return result; return result;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = keys[index];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
obj[i] = KEY_TO_OBJ(keys[index]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = (E)KEY_TO_OBJ(keys[index]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -475,7 +599,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -488,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]); else state = operator.APPLY_VALUE(state, keys[index]);
index = (int)links[index]; index = (int)links[index];
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { 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]; index = (int)links[index];
} }
return EMPTY_VALUE; return OPTIONAL.empty();
} }
@Override @Override
@@ -632,7 +756,12 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() { 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 @Override
@@ -657,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 { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
boolean forward;
int previous = -1; int previous = -1;
int next = -1; int next = -1;
int current = -1; int current = -1;
int index = 0; int index = -1;
SetIterator() { SetIterator(boolean start) {
next = firstIndex; this.forward = start;
if(start) next = firstIndex;
else previous = lastIndex;
} }
SetIterator(KEY_TYPE from) { SetIterator(KEY_TYPE from) {
this.forward = true;
if(KEY_EQUALS_NULL(from)) { if(KEY_EQUALS_NULL(from)) {
if(containsNull) { if(containsNull) {
next = (int) links[nullIndex]; next = (int) links[nullIndex];
@@ -695,48 +828,60 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public int skip(int amount) { public int skip(int amount) {
int result = 0; int result = forward ? moveForward(amount) : moveBackwards(amount);
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result; if(index >= 0) index+=result;
return result; return result;
} }
@Override @Override
public int back(int amount) { 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; int result = 0;
while(previous != -1 && result != amount) { while(previous != -1 && result != amount) {
current = next = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
result++; result++;
} }
if(index >= 0) index-=result;
return result; return result;
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != -1; return (forward ? next : previous) != -1;
} }
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return previous != -1; return (forward ? previous : next) != -1;
} }
@Override @Override
public int nextIndex() { public int nextIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index; if(forward) return index;
return size - index;
} }
@Override @Override
public int previousIndex() { public int previousIndex() {
ensureIndexKnown(); ensureIndexKnown();
return index - 1; if(forward) return index-1;
return (size - index)-1;
} }
@Override @Override
@@ -785,8 +930,8 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous; if(forward) moveBackwards();
previous = (int)(links[current] >> 32); else moveForwards();
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@@ -794,12 +939,22 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = previous = next; if(forward) moveForwards();
next = (int)(links[current]); else moveBackwards();
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; 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() { private void ensureIndexKnown() {
if(index == -1) { if(index == -1) {
if(previous == -1) { if(previous == -1) {
@@ -3,11 +3,13 @@ package speiger.src.collections.PACKAGE.sets;
import java.util.NavigableSet; import java.util.NavigableSet;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
#if SETS_FEATURE #if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS; import speiger.src.collections.PACKAGE.utils.SETS;
#endif #endif
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
/** /**
* A Type Specific Navigable Set interface with a couple helper methods * A Type Specific Navigable Set interface with a couple helper methods
@@ -145,6 +147,7 @@ public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>
public default NAVIGABLE_SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); } public default NAVIGABLE_SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); }
#endif #endif
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
@@ -152,6 +155,7 @@ public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
@Deprecated @Deprecated
@@ -6,6 +6,15 @@ import java.util.ConcurrentModificationException;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; 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 #if TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; 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.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -27,6 +39,7 @@ import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.utils.STRATEGY; import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
@@ -250,6 +263,42 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
while(iterator.hasNext()) add(iterator.NEXT()); 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 #endif
/** /**
* Helper getter function to get the current strategy * Helper getter function to get the current strategy
@@ -479,6 +528,44 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
return new SetIterator(); return new SetIterator();
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
if(containsNull) a[0] = EMPTY_KEY_VALUE;
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) a[index++] = keys[i];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
if(containsNull) obj[0] = KEY_TO_OBJ(EMPTY_KEY_VALUE);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) obj[index++] = KEY_TO_OBJ(keys[i]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
if(containsNull) a[0] = (E)KEY_TO_OBJ(EMPTY_KEY_VALUE);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) a[index++] = (E)KEY_TO_OBJ(keys[i]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public CUSTOM_HASH_SET KEY_GENERIC_TYPE copy() { public CUSTOM_HASH_SET KEY_GENERIC_TYPE copy() {
CUSTOM_HASH_SET KEY_GENERIC_TYPE set = new CUSTOM_HASH_SETBRACES(0, loadFactor, strategy); CUSTOM_HASH_SET KEY_GENERIC_TYPE set = new CUSTOM_HASH_SETBRACES(0, loadFactor, strategy);
@@ -596,7 +683,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -613,18 +700,18 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
} }
state = operator.APPLY_VALUE(state, keys[i]); state = operator.APPLY_VALUE(state, keys[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return OPTIONAL.empty();
if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex]; if(containsNull && filter.test(keys[nullIndex])) return OPTIONAL.GET_OPTIONAL(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) { 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 @Override
@@ -6,6 +6,15 @@ import java.util.ConcurrentModificationException;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; 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 #if TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@@ -20,12 +29,17 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #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.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION #if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@@ -216,6 +230,42 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
while(iterator.hasNext()) add(iterator.NEXT()); 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 #endif
@Override @Override
public boolean add(KEY_TYPE o) { public boolean add(KEY_TYPE o) {
@@ -368,6 +418,44 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
containsNull = false; containsNull = false;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
if(containsNull) a[0] = EMPTY_KEY_VALUE;
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) a[index++] = keys[i];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
if(containsNull) obj[0] = KEY_TO_OBJ(EMPTY_KEY_VALUE);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) obj[index++] = KEY_TO_OBJ(keys[i]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
if(containsNull) a[0] = (E)KEY_TO_OBJ(EMPTY_KEY_VALUE);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) a[index++] = (E)KEY_TO_OBJ(keys[i]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
if(size() <= 0) return; if(size() <= 0) return;
@@ -458,7 +546,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -475,18 +563,18 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
} }
state = operator.APPLY_VALUE(state, keys[i]); state = operator.APPLY_VALUE(state, keys[i]);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return OPTIONAL.empty();
if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex]; if(containsNull && filter.test(keys[nullIndex])) return OPTIONAL.GET_OPTIONAL(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) { 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 @Override
@@ -1,11 +1,19 @@
package speiger.src.collections.PACKAGE.sets; 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.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.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 #if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS; import speiger.src.collections.PACKAGE.utils.SETS;
#endif #endif
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
/** /**
* A Special Set Interface giving Access to some really usefull functions * A Special Set Interface giving Access to some really usefull functions
@@ -15,7 +23,11 @@ import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
* *
* @Type(T) * @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. * A customized add method that allows you to insert into the first index.
@@ -52,6 +64,7 @@ public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(); public BI_ITERATOR KEY_GENERIC_TYPE iterator();
public BI_ITERATOR KEY_GENERIC_TYPE reverseIterator();
/** /**
* A type Specific Iterator starting from a given key * A type Specific Iterator starting from a given key
@@ -61,6 +74,7 @@ public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
*/ */
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement); public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement);
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
@@ -68,26 +82,80 @@ public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
/** /**
* A method to get the first element in the set * A method to get the first element in the set
* @return 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 * A method to get and remove the first element in the set
* @return 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 * A method to get the last element in the set
* @return 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 * A method to get and remove the last element in the set
* @return 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 #if SETS_FEATURE
/** /**
@@ -2,6 +2,15 @@ package speiger.src.collections.PACKAGE.sets;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; 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 #if TYPE_OBJECT
import java.util.Comparator; import java.util.Comparator;
import java.util.function.Consumer; 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.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #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.ints.functions.consumer.BI_FROM_INT_CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION #if !JDK_FUNCTION
@@ -27,6 +39,7 @@ import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
@@ -207,6 +220,42 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
while(iterator.hasNext()) add(iterator.NEXT()); 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 #if !TYPE_OBJECT
@Override @Override
public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; } public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; }
@@ -426,7 +475,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -438,16 +487,16 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
state = operator.APPLY_VALUE(state, entry.key); state = operator.APPLY_VALUE(state, entry.key);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { 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 @Override
@@ -652,6 +701,44 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
tree = null; tree = null;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
a[index++] = entry.key;
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
obj[index++] = KEY_TO_OBJ(entry.key);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
a[index++] = (E)KEY_TO_OBJ(entry.key);
}
if (a.length > size) a[size] = null;
return a;
}
public RB_TREE_SET KEY_GENERIC_TYPE copy() { public RB_TREE_SET KEY_GENERIC_TYPE copy() {
RB_TREE_SET KEY_GENERIC_TYPE set = new RB_TREE_SETBRACES(); RB_TREE_SET KEY_GENERIC_TYPE set = new RB_TREE_SETBRACES();
set.size = size; set.size = size;
@@ -1335,7 +1422,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif #endif
@Override @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); Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE; KEY_TYPE state = EMPTY_VALUE;
boolean empty = true; boolean empty = true;
@@ -1347,16 +1434,16 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
state = operator.APPLY_VALUE(state, entry.key); state = operator.APPLY_VALUE(state, entry.key);
} }
return state; return empty ? OPTIONAL.empty() : OPTIONAL.GET_OPTIONAL(state);
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public OPTIONAL KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { 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 @Override
@@ -4,11 +4,13 @@ import java.util.Set;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
#if SETS_FEATURE #if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS; import speiger.src.collections.PACKAGE.utils.SETS;
#endif #endif
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
/** /**
@@ -88,10 +90,12 @@ public interface SET KEY_GENERIC_TYPE extends Set<CLASS_TYPE>, COLLECTION KEY_GE
public default SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); } public default SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); }
#endif #endif
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
*/ */
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
} }
@@ -3,7 +3,9 @@ package speiger.src.collections.PACKAGE.sets;
import java.util.SortedSet; import java.util.SortedSet;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#endif
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.Comparator; import java.util.Comparator;
#else #else
@@ -12,7 +14,9 @@ import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#if SETS_FEATURE #if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS; import speiger.src.collections.PACKAGE.utils.SETS;
#endif #endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
/** /**
* A Type Specific SortedSet implementation to reduce boxing/unboxing * A Type Specific SortedSet implementation to reduce boxing/unboxing
@@ -67,6 +71,7 @@ public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, Sorte
public default SORTED_SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); } public default SORTED_SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); }
#endif #endif
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
@@ -74,6 +79,7 @@ public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, Sorte
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** /**
* A Type Specific SubSet method to reduce boxing/unboxing * A Type Specific SubSet method to reduce boxing/unboxing
@@ -16,9 +16,8 @@ import java.util.function.IntFunction;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
import speiger.src.collections.utils.Swapper;
/** /**
* A Helper class for Arrays * A Helper class for Arrays
@@ -147,6 +146,7 @@ public class ARRAYS
* A Helper function that pours all elements of a iterator into a Array * A Helper function that pours all elements of a iterator into a Array
* @param iter the elements that should be gathered. * @param iter the elements that should be gathered.
* @ArrayType(T) * @ArrayType(T)
* @ArrayType(E)
* @param action that is creating the Array to be poured into * @param action that is creating the Array to be poured into
* @return array with all elements of the iterator * @return array with all elements of the iterator
*/ */
@@ -160,6 +160,7 @@ public class ARRAYS
* @param max how many elements should be added * @param max how many elements should be added
* @param action that is creating the Array to be poured into * @param action that is creating the Array to be poured into
* @ArrayType(T) * @ArrayType(T)
* @ArrayType(E)
* @return array with all requested elements of the iterator * @return array with all requested elements of the iterator
*/ */
public static <T, E> E[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max, IntFunction<E[]> action) { public static <T, E> E[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max, IntFunction<E[]> action) {
@@ -337,6 +338,69 @@ public class ARRAYS
return array; 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 * Simple Array Reversal method
* @param array the Array that should flip * @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, * Sorts an array according to the natural ascending order using InsertionSort,
* @param array the array that needs to be sorted * @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, * Sorts an array according to the natural ascending order using Selection Sort,
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
@@ -690,7 +857,7 @@ public class ARRAYS
* @ArrayType(T) * @ArrayType(T)
*/ */
public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, int from, int to) { public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, int from, int to) {
for (int i = from; i < to; i++) { for (int i = from,m=to-1; i < m; i++) {
KEY_TYPE min = array[i]; KEY_TYPE min = array[i];
int minId = i; int minId = i;
for(int j = i+1; j < to; j++) { for(int j = i+1; j < to; j++) {
@@ -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, * 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 * 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); 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, * 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 * 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); 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, * 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, * 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); 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, * 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, * 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++)); 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) { 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); 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 from;
int to; int to;
QuickSortAction(KEY_TYPE[] array, int from, int to) QuickSortAction(KEY_TYPE[] array, int from, int to) {
{
this.array = array; this.array = array;
this.from = from; this.from = from;
this.to = to; this.to = to;
} }
@Override @Override
protected void compute() protected void compute() {
{
int length = to - from; int length = to - from;
if(length <= 0) return; if(length <= 0) return;
if(length < BASE_THRESHOLD) { if(length < BASE_THRESHOLD) {
@@ -1431,8 +1843,7 @@ public class ARRAYS
int to; int to;
COMPARATOR KEY_GENERIC_TYPE comp; 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.array = array;
this.from = from; this.from = from;
this.to = to; this.to = to;
@@ -1440,8 +1851,7 @@ public class ARRAYS
} }
@Override @Override
protected void compute() protected void compute() {
{
int length = to - from; int length = to - from;
if(length <= 0) return; if(length <= 0) return;
if(length < BASE_THRESHOLD) { 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 { static class MergeSortAction KEY_GENERIC_TYPE extends RecursiveAction {
private static final long serialVersionUID = 0L; private static final long serialVersionUID = 0L;
KEY_TYPE[] array; KEY_TYPE[] array;
@@ -1474,8 +1927,7 @@ public class ARRAYS
int from; int from;
int to; 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.array = array;
this.supp = supp; this.supp = supp;
this.from = from; this.from = from;
@@ -1483,8 +1935,7 @@ public class ARRAYS
} }
@Override @Override
protected void compute() protected void compute() {
{
if(to - from < BASE_THRESHOLD) { if(to - from < BASE_THRESHOLD) {
insertionSort(array, from, to); insertionSort(array, from, to);
return; return;
@@ -1512,8 +1963,7 @@ public class ARRAYS
int to; int to;
COMPARATOR KEY_GENERIC_TYPE comp; 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.array = array;
this.supp = supp; this.supp = supp;
this.from = from; this.from = from;
@@ -1522,8 +1972,7 @@ public class ARRAYS
} }
@Override @Override
protected void compute() protected void compute() {
{
if(to - from < BASE_THRESHOLD) { if(to - from < BASE_THRESHOLD) {
insertionSort(array, from, to, comp); insertionSort(array, from, to, comp);
return; 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 { static class MemFreeMergeSortAction KEY_GENERIC_TYPE extends RecursiveAction {
private static final long serialVersionUID = 0L; private static final long serialVersionUID = 0L;
KEY_TYPE[] array; KEY_TYPE[] array;
int from; int from;
int to; int to;
MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to) MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to) {
{
this.array = array; this.array = array;
this.from = from; this.from = from;
this.to = to; this.to = to;
} }
@Override @Override
protected void compute() protected void compute() {
{
if(to - from < BASE_THRESHOLD) { if(to - from < BASE_THRESHOLD) {
insertionSort(array, from, to); insertionSort(array, from, to);
return; return;
@@ -1604,8 +2095,7 @@ public class ARRAYS
int to; int to;
COMPARATOR KEY_GENERIC_TYPE comp; 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.array = array;
this.from = from; this.from = from;
this.to = to; this.to = to;
@@ -1613,8 +2103,7 @@ public class ARRAYS
} }
@Override @Override
protected void compute() protected void compute() {
{
if(to - from < BASE_THRESHOLD) { if(to - from < BASE_THRESHOLD) {
insertionSort(array, from, to, comp); insertionSort(array, from, to, comp);
return; return;
@@ -7,6 +7,11 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.LockSupport;
import java.util.function.Consumer; import java.util.function.Consumer;
#if JDK_TYPE
import java.util.OPTIONAL;
#else
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -16,6 +21,16 @@ import java.util.function.IntFunction;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.Comparator; import java.util.Comparator;
#iterate
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument BUILDER BooleanAsyncBuilder ByteAsyncBuilder ShortAsyncBuilder IntAsyncBuilder LongAsyncBuilder FloatAsyncBuilder DoubleAsyncBuilder
#argument PACKAGE booleans bytes shorts ints longs floats doubles
#argument CHECK BOOLEAN_ASYNC_MODULE BYTE_ASYNC_MODULE SHORT_ASYNC_MODULE INT_ASYNC_MODULE LONG_ASYNC_MODULE FLOAT_ASYNC_MODULE DOUBLE_ASYNC_MODULE
#if CHECK
import speiger.src.collections.objects.functions.function.MAPPER;
import speiger.src.collections.PACKAGE.utils.BUILDER;
#endif
#enditerate
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERABLE; import speiger.src.collections.PACKAGE.collections.ITERABLE;
#if OBJECT_ASYNC_MODULE #if OBJECT_ASYNC_MODULE
@@ -23,7 +38,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.TASK; import speiger.src.collections.PACKAGE.functions.TASK;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
#if OBJECT_ASYNC_MODULE #if OBJECT_ASYNC_MODULE
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
#endif #endif
@@ -59,7 +76,9 @@ import speiger.src.collections.PACKAGE.sets.ARRAY_SET;
#endif #endif
#endif #endif
#if !TYPE_BOOLEAN && BOOLEAN_ASYNC_MODULE #if !TYPE_BOOLEAN && BOOLEAN_ASYNC_MODULE
#if !TYPE_OBJECT
import speiger.src.collections.booleans.utils.BooleanAsyncBuilder; import speiger.src.collections.booleans.utils.BooleanAsyncBuilder;
#endif
import speiger.src.collections.booleans.utils.BooleanAsyncBuilder.BaseBooleanTask; import speiger.src.collections.booleans.utils.BooleanAsyncBuilder.BaseBooleanTask;
#endif #endif
#if !TYPE_OBJECT && OBJECT_ASYNC_MODULE #if !TYPE_OBJECT && OBJECT_ASYNC_MODULE
@@ -67,7 +86,9 @@ import speiger.src.collections.objects.utils.ObjectAsyncBuilder;
import speiger.src.collections.objects.utils.ObjectAsyncBuilder.BaseObjectTask; import speiger.src.collections.objects.utils.ObjectAsyncBuilder.BaseObjectTask;
#endif #endif
#if !TYPE_INT && INT_ASYNC_MODULE #if !TYPE_INT && INT_ASYNC_MODULE
#if !TYPE_OBJECT
import speiger.src.collections.ints.utils.IntAsyncBuilder; import speiger.src.collections.ints.utils.IntAsyncBuilder;
#endif
import speiger.src.collections.ints.utils.IntAsyncBuilder.BaseIntTask; import speiger.src.collections.ints.utils.IntAsyncBuilder.BaseIntTask;
#endif #endif
import speiger.src.collections.utils.ISizeProvider; import speiger.src.collections.utils.ISizeProvider;
@@ -187,6 +208,25 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return new ObjectAsyncBuilder<>(ITERABLES.arrayFlatMap(iterable, mapper)); return new ObjectAsyncBuilder<>(ITERABLES.arrayFlatMap(iterable, mapper));
} }
#endif
#if TYPE_OBJECT
#iterate
#argument BUILDER BooleanAsyncBuilder ByteAsyncBuilder ShortAsyncBuilder IntAsyncBuilder LongAsyncBuilder FloatAsyncBuilder DoubleAsyncBuilder
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument TYPE Boolean Byte Short Int Long Float Double
#argument CHECK BOOLEAN_ASYNC_MODULE BYTE_ASYNC_MODULE SHORT_ASYNC_MODULE INT_ASYNC_MODULE LONG_ASYNC_MODULE FLOAT_ASYNC_MODULE DOUBLE_ASYNC_MODULE
#if CHECK
/**
* Maps the elements to something else
* @param mapper the mapping function
* @return a new Builder Object with the mapped Iterable
*/
public BUILDER mapToTYPE(MAPPER<T> mapper) {
return new BUILDER(ITERABLES.mapToTYPE(iterable, mapper));
}
#endif
#enditerate
#endif #endif
/** /**
* Filters out the unwanted elements out of the Iterable * Filters out the unwanted elements out of the Iterable
@@ -264,9 +304,8 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
* @param operator that reduces the elements. * @param operator that reduces the elements.
* @return self with the reduce action applied * @return self with the reduce action applied
*/ */
public ASYNC_BUILDER KEY_GENERIC_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { public ObjectAsyncBuilder<OPTIONAL KEY_GENERIC_TYPE> reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
task = new SimpleReduceTaskBRACES(iterable.iterator(), operator); return new ObjectAsyncBuilder<>(new SimpleReduceTaskBRACES(iterable.iterator(), operator));
return this;
} }
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -400,9 +439,8 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
* @param filter that decides the desired elements * @param filter that decides the desired elements
* @return self with the findFirst function applied * @return self with the findFirst function applied
*/ */
public ASYNC_BUILDER KEY_GENERIC_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public ObjectAsyncBuilder<OPTIONAL KEY_GENERIC_TYPE> findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
task = new FindFirstTaskBRACES(iterable.iterator(), filter); return new ObjectAsyncBuilder<>(new FindFirstTaskBRACES(iterable.iterator(), filter));
return this;
} }
#if INT_ASYNC_MODULE #if INT_ASYNC_MODULE
@@ -555,7 +593,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
#endif #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; ITERATOR KEY_GENERIC_TYPE iter;
UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator; UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator;
@@ -565,6 +603,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
public SimpleReduceTask(ITERATOR KEY_GENERIC_TYPE iter, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { public SimpleReduceTask(ITERATOR KEY_GENERIC_TYPE iter, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
this.iter = iter; this.iter = iter;
this.operator = operator; this.operator = operator;
this.setResult(OPTIONAL.empty());
} }
@Override @Override
@@ -579,7 +618,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
} }
if(!iter.hasNext()) { if(!iter.hasNext()) {
setResult(value); setResult(OPTIONAL.GET_OPTIONAL(value));
return true; return true;
} }
return false; return false;
@@ -654,7 +693,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
#endif #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; ITERATOR KEY_GENERIC_TYPE iter;
PREDICATE KEY_GENERIC_TYPE filter; PREDICATE KEY_GENERIC_TYPE filter;
@@ -662,6 +701,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
public FindFirstTask(ITERATOR KEY_GENERIC_TYPE iter, PREDICATE KEY_GENERIC_TYPE filter) { public FindFirstTask(ITERATOR KEY_GENERIC_TYPE iter, PREDICATE KEY_GENERIC_TYPE filter) {
this.iter = iter; this.iter = iter;
this.filter = filter; this.filter = filter;
this.setResult(OPTIONAL.empty());
} }
@Override @Override
@@ -669,7 +709,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
while(shouldRun() && iter.hasNext()) { while(shouldRun() && iter.hasNext()) {
KEY_TYPE entry = iter.NEXT(); KEY_TYPE entry = iter.NEXT();
if(filter.test(iter.NEXT())) { if(filter.test(iter.NEXT())) {
setResult(entry); setResult(OPTIONAL.GET_OPTIONAL(entry));
return true; return true;
} }
} }
@@ -8,6 +8,9 @@ import java.util.ConcurrentModificationException;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
#if JDK_TYPE
import java.util.OPTIONAL;
#endif
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.Comparator; import java.util.Comparator;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@@ -23,14 +26,19 @@ import java.util.function.Consumer;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.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; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
import speiger.src.collections.objects.utils.ObjectArrays; #if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif #endif
#if !JDK_FUNCTION #if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
@@ -77,6 +85,37 @@ public class COLLECTIONS
return c instanceof UnmodifiableCollection ? c : new UnmodifiableCollectionBRACES(c); 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. * Returns a synchronized Collection instance based on the instance given.
* @param c that should be synchronized * @param c that should be synchronized
@@ -108,7 +147,10 @@ public class COLLECTIONS
return new SingletonCollectionBRACES(element); 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(); return new CollectionWrapperBRACES();
} }
@@ -669,6 +711,38 @@ public class COLLECTIONS
@Override @Override
public SingletonCollection KEY_GENERIC_TYPE copy() { return new SingletonCollectionBRACES(element); } 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 * Synchronized Collection Wrapper for the synchronizedCollection function
@@ -804,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); } } public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { synchronized(mutex) { return c.reduce(identity, operator); } }
#endif #endif
@Override @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 @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 @Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return c.count(filter); } } 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 * Unmodifyable Collection Wrapper for the unmodifyableCollection method
* @Type(T) * @Type(T)
@@ -928,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); } public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { return c.reduce(identity, operator); }
#endif #endif
@Override @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 @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 @Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) { return c.count(filter); } public int count(PREDICATE KEY_GENERIC_TYPE filter) { return c.count(filter); }
} }
@@ -19,6 +19,26 @@ import speiger.src.collections.objects.collections.ObjectIterable;
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#else
#if BOOLEAN_COLLECTION_MODULE
import speiger.src.collections.booleans.functions.BooleanConsumer;
import speiger.src.collections.booleans.collections.BooleanIterable;
import speiger.src.collections.booleans.collections.BooleanIterator;
#endif
#iterate
#argument FILTER_TYPE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#argument CONSUMER ByteConsumer ShortConsumer IntConsumer LongConsumer FloatConsumer DoubleConsumer
#argument OUTPUT_ITERABLE ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument OUTPUT_ITERATOR ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument MAPPER ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument PACKAGE bytes shorts ints longs floats doubles
#if FILTER_TYPE
import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.function.MAPPER;
import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERABLE;
import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERATOR;
#endif
#enditerate
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
@@ -56,6 +76,39 @@ public class ITERABLES
return new MappedIterable<>(iterable, mapper); return new MappedIterable<>(iterable, mapper);
} }
#if TYPE_OBJECT
#iterate
#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble
#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument DATA_TYPE Boolean Byte Short Int Long Float Double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
/**
* A Helper function that maps a Java-Iterable into a new Type.
* @param iterable the iterable that should be mapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @return a iterable that is mapped to a new result
*/
public static <T> OUTPUT_ITERABLE mapToDATA_TYPE(Iterable<? extends CLASS_TYPE> iterable, MAPPER<T> mapper) {
return new MAPPED_TYPEIterable<>(wrap(iterable), mapper);
}
/**
* A Helper function that maps a Iterable into a new Type.
* @param iterable the iterable that should be mapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @return a iterable that is mapped to a new result
*/
public static <T> OUTPUT_ITERABLE mapToDATA_TYPE(ITERABLE KEY_GENERIC_TYPE iterable, MAPPER<T> mapper) {
return new MAPPED_TYPEIterable<>(iterable, mapper);
}
#endif
#enditerate
#endif
/** /**
* A Helper function that flatMaps a Java-Iterable into a new Type. * A Helper function that flatMaps a Java-Iterable into a new Type.
* @param iterable the iterable that should be flatMapped * @param iterable the iterable that should be flatMapped
@@ -280,6 +333,47 @@ public class ITERABLES
#endif #endif
} }
#if TYPE_OBJECT
#iterate
#argument CONSUMER BooleanConsumer ByteConsumer ShortConsumer IntConsumer LongConsumer FloatConsumer DoubleConsumer
#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble
#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument APPLY test applyAsByte applyAsShort applyAsInt applyAsLong applyAsFloat applyAsDouble
#argument DATA_TYPE Boolean Byte Short Int Long Float Double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
private static class MAPPED_TYPEIterable<E> implements OUTPUT_ITERABLE, ISizeProvider
{
ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable;
MAPPER<E> mapper;
MAPPED_TYPEIterable(ITERABLE<E> iterable, MAPPER<E> mapper) {
this.iterable = iterable;
this.mapper = mapper;
}
public OUTPUT_ITERATOR iterator() {
return ITERATORS.mapToDATA_TYPE(iterable.iterator(), mapper);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(this);
return prov == null ? -1 : prov.size();
}
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(E -> action.accept(mapper.APPLY(E)));
}
}
#endif
#enditerate
#endif
private static class MappedIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T>, ISizeProvider private static class MappedIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T>, ISizeProvider
{ {
ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable; ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable;
@@ -4,8 +4,8 @@ import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.Comparator; import java.util.Comparator;
import java.util.function.CONSUMER;
#endif #endif
import java.util.function.Consumer;
#if JDK_FUNCTION #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #endif
@@ -16,8 +16,23 @@ import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.utils.ObjectIterators; import speiger.src.collections.objects.utils.ObjectIterators;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#else
#if BOOLEAN_COLLECTION_MODULE
import speiger.src.collections.booleans.collections.BooleanIterator;
#endif
#iterate
#argument ITERATOR ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument PACKAGE bytes shorts ints longs floats doubles
#argument MAPPER ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument FILTER_TYPE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
import speiger.src.collections.objects.functions.function.MAPPER;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#endif
#enditerate
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION #if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
@@ -33,6 +48,7 @@ import speiger.src.collections.PACKAGE.lists.LINKED_LIST;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.CollectionWrapper;
/** /**
* A Helper class for Iterators * A Helper class for Iterators
@@ -49,7 +65,7 @@ public class ITERATORS
* @Type(T) * @Type(T)
* @return an empty iterator * @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 #if TYPE_OBJECT
return (EmptyIterator<KEY_TYPE>)EMPTY; return (EmptyIterator<KEY_TYPE>)EMPTY;
#else #else
@@ -107,6 +123,7 @@ public class ITERATORS
return iterator instanceof UnmodifiableListIterator ? iterator : new UnmodifiableListIteratorBRACES(iterator); return iterator instanceof UnmodifiableListIterator ? iterator : new UnmodifiableListIteratorBRACES(iterator);
} }
#if OBJECT_COLLECTION_MODULE
/** /**
* A Helper function that maps a Java-Iterator into a new Type. * A Helper function that maps a Java-Iterator into a new Type.
* @param iterator that should be mapped * @param iterator that should be mapped
@@ -131,6 +148,40 @@ public class ITERATORS
return new MappedIterator<>(iterator, mapper); return new MappedIterator<>(iterator, mapper);
} }
#endif
#if TYPE_OBJECT
#iterate
#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble
#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument DATA_TYPE Boolean Byte Short Int Long Float Double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
/**
* A Helper function that maps a Java-Iterator into a new Type.
* @param iterator that should be mapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @return a iterator that is mapped to a new result
*/
public static <T> OUTPUT_ITERATOR mapToDATA_TYPE(Iterator<? extends CLASS_TYPE> iterator, MAPPER<T> mapper) {
return new MAPPED_TYPEIterator<>(wrap(iterator), mapper);
}
/**
* A Helper function that maps a Iterator into a new Type.
* @param iterator that should be mapped
* @param mapper the function that decides what the result turns into.
* @Type(T)
* @return a iterator that is mapped to a new result
*/
public static <T> OUTPUT_ITERATOR mapToDATA_TYPE(ITERATOR KEY_GENERIC_TYPE iterator, MAPPER<T> mapper) {
return new MAPPED_TYPEIterator<>(iterator, mapper);
}
#endif
#enditerate
#endif
/** /**
* A Helper function that flatMaps a Java-Iterator into a new Type. * A Helper function that flatMaps a Java-Iterator into a new Type.
* @param iterator that should be flatMapped * @param iterator that should be flatMapped
@@ -245,6 +296,26 @@ public class ITERATORS
return new RepeatingIteratorBRACES(wrap(iterator), repeats); return new RepeatingIteratorBRACES(wrap(iterator), repeats);
} }
/**
* A Helper function that creates a infinitely looping iterator
* @param iterator that should be looping infinitely
* @Type(T)
* @return a infinitely looping iterator
*/
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE infinite(ITERATOR KEY_GENERIC_TYPE iterator) {
return new InfiniteIteratorBRACES(iterator);
}
/**
* A Helper function that creates a infinitely looping iterator from a Java Iterator
* @param iterator that should be looping infinitely
* @Type(T)
* @return a infinitely looping iterator
*/
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE infinite(Iterator<? extends CLASS_TYPE> iterator) {
return new InfiniteIteratorBRACES(wrap(iterator));
}
/** /**
* A Helper function that hard limits the Iterator to a specific size * A Helper function that hard limits the Iterator to a specific size
* @param iterator that should be limited * @param iterator that should be limited
@@ -329,7 +400,7 @@ public class ITERATORS
* @ArrayType(T) * @ArrayType(T)
* @return a Iterator that is wrapping a array. * @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); return wrap(a, 0, a.length);
} }
@@ -341,7 +412,7 @@ public class ITERATORS
* @ArrayType(T) * @ArrayType(T)
* @return a Iterator that is wrapping a array. * @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); return new ArrayIteratorBRACES(a, start, end);
} }
@@ -846,6 +917,45 @@ public class ITERATORS
} }
} }
#if TYPE_OBJECT
#iterate
#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble
#argument NEXT_TYPE nextBoolean nextByte nextShort nextInt nextLong nextFloat nextDouble
#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument APPLY test applyAsByte applyAsShort applyAsInt applyAsLong applyAsFloat applyAsDouble
#argument DATA_TYPE boolean byte short int long float double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
private static class MAPPED_TYPEIterator<E> implements OUTPUT_ITERATOR
{
ITERATOR<E> iterator;
MAPPER<E> mapper;
MAPPED_TYPEIterator(ITERATOR KEY_SPECIAL_GENERIC_TYPE<E> iterator, MAPPER<E> mapper) {
this.iterator = iterator;
this.mapper = mapper;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public DATA_TYPE NEXT_TYPE() {
return mapper.APPLY(iterator.NEXT());
}
@Override
public int skip(int amount) {
return iterator.skip(amount);
}
}
#endif
#enditerate
#endif
private static class FlatMappedIterator KSS_GENERIC_TYPE<E, T,[SPACE]V extends Iterable<T>> implements ObjectIterator<T> private static class FlatMappedIterator KSS_GENERIC_TYPE<E, T,[SPACE]V extends Iterable<T>> implements ObjectIterator<T>
{ {
ITERATOR KEY_SPECIAL_GENERIC_TYPE<E> iterator; ITERATOR KEY_SPECIAL_GENERIC_TYPE<E> iterator;
@@ -918,6 +1028,42 @@ public class ITERATORS
} }
} }
private static class InfiniteIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
{
ITERATOR KEY_GENERIC_TYPE iter;
CollectionWrapper KEY_GENERIC_TYPE looper = COLLECTIONS.wrapper();
int index = 0;
public InfiniteIterator(ITERATOR KEY_GENERIC_TYPE iter) {
this.iter = iter;
}
@Override
public boolean hasNext() {
return true;
}
@Override
public KEY_TYPE NEXT() {
if(iter != null) {
if(iter.hasNext()) {
KEY_TYPE value = iter.NEXT();
looper.add(value);
return value;
}
else iter = null;
}
return looper.GET_KEY((index++) % looper.size());
}
#if !TYPE_OBJECT
@Override
public void forEachRemaining(CONSUMER action) { throw new UnsupportedOperationException("This is a instant deadlock, so unsupported"); }
#endif
public void forEachRemaining(Consumer<? super CLASS_TYPE> action) { throw new UnsupportedOperationException("This is a instant deadlock, so unsupported"); }
public <E> void forEachRemaining(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { throw new UnsupportedOperationException("This is a instant deadlock, so unsupported"); }
}
private static class RepeatingIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE private static class RepeatingIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
{ {
final int repeats; final int repeats;
@@ -24,10 +24,10 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
import speiger.src.collections.PACKAGE.lists.ABSTRACT_LIST; import speiger.src.collections.PACKAGE.lists.ABSTRACT_LIST;
import speiger.src.collections.PACKAGE.lists.LIST; import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; #if INT_LIST_MODULE && !TYPE_INT
#if IARRAY_FEATURE import speiger.src.collections.ints.lists.IntList;
import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif #endif
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
@@ -45,7 +45,7 @@ public class LISTS
* @Type(T) * @Type(T)
* @return an empty list * @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 #if TYPE_OBJECT
return (EmptyList<KEY_TYPE>)EMPTY; return (EmptyList<KEY_TYPE>)EMPTY;
#else #else
@@ -411,11 +411,28 @@ public class LISTS
return l.listIterator(index); return l.listIterator(index);
} }
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) {
return l.indexedIterator(indecies);
}
#if INT_LIST_MODULE
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) {
return l.indexedIterator(indecies);
}
#endif
@Override @Override
public LIST KEY_GENERIC_TYPE subList(int from, int to) { public LIST KEY_GENERIC_TYPE subList(int from, int to) {
return LISTS.synchronize(l.subList(from, to)); return LISTS.synchronize(l.subList(from, to));
} }
@Override
public LIST KEY_GENERIC_TYPE reversed() {
return LISTS.synchronize(l.reversed());
}
@Override @Override
public void size(int size) { synchronized(mutex) { l.size(size); } } public void size(int size) { synchronized(mutex) { l.size(size); } }
@@ -533,11 +550,28 @@ public class LISTS
return ITERATORS.unmodifiable(l.listIterator(index)); return ITERATORS.unmodifiable(l.listIterator(index));
} }
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) {
return ITERATORS.unmodifiable(l.indexedIterator(indecies));
}
#if INT_LIST_MODULE
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) {
return ITERATORS.unmodifiable(l.indexedIterator(indecies));
}
#endif
@Override @Override
public LIST KEY_GENERIC_TYPE subList(int from, int to) { public LIST KEY_GENERIC_TYPE subList(int from, int to) {
return LISTS.unmodifiable(l.subList(from, to)); return LISTS.unmodifiable(l.subList(from, to));
} }
@Override
public LIST KEY_GENERIC_TYPE reversed() {
return LISTS.unmodifiable(l.reversed());
}
@Override @Override
public void size(int size) { throw new UnsupportedOperationException(); } public void size(int size) { throw new UnsupportedOperationException(); }
@@ -626,6 +660,18 @@ public class LISTS
return ITERATORS.empty(); return ITERATORS.empty();
} }
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) {
return ITERATORS.empty();
}
#if INT_LIST_MODULE
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) {
return ITERATORS.empty();
}
#endif
@Override @Override
public int hashCode() { return 1; } public int hashCode() { return 1; }
@@ -639,6 +685,9 @@ public class LISTS
@Override @Override
public LIST KEY_GENERIC_TYPE subList(int from, int to) { throw new UnsupportedOperationException(); } public LIST KEY_GENERIC_TYPE subList(int from, int to) { throw new UnsupportedOperationException(); }
@Override
public LIST KEY_GENERIC_TYPE reversed() { return this; }
@Override @Override
public void size(int size) { throw new UnsupportedOperationException(); } public void size(int size) { throw new UnsupportedOperationException(); }
@@ -4,16 +4,22 @@ package speiger.src.collections.PACKAGE.utils;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction;
#endif #endif
#if JDK_FUNCTION #if JDK_FUNCTION
import java.util.function.PREDICATE; import java.util.function.PREDICATE;
#endif #endif
#if JDK_TYPE
import java.util.OPTIONAL;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
#if !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
#if DEQUEUE_FEATURE #if DEQUEUE_FEATURE
import speiger.src.collections.PACKAGE.queues.PRIORITY_DEQUEUE; import speiger.src.collections.PACKAGE.queues.PRIORITY_DEQUEUE;
#endif #endif
@@ -24,6 +30,7 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER;
#if !JDK_FUNCTION #if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
/** /**
@@ -116,6 +123,8 @@ public class PRIORITY_QUEUES
@Override @Override
public KEY_TYPE peek(int index) { synchronized(mutex) { return queue.peek(index); } } public KEY_TYPE peek(int index) { synchronized(mutex) { return queue.peek(index); } }
@Override @Override
public boolean contains(KEY_TYPE e) { synchronized(mutex) { return queue.contains(e); } }
@Override
public boolean removeFirst(KEY_TYPE e) { synchronized(mutex) { return queue.removeFirst(e); } } public boolean removeFirst(KEY_TYPE e) { synchronized(mutex) { return queue.removeFirst(e); } }
@Override @Override
public boolean removeLast(KEY_TYPE e) { synchronized(mutex) { return queue.removeLast(e); } } public boolean removeLast(KEY_TYPE e) { synchronized(mutex) { return queue.removeLast(e); } }
@@ -138,7 +147,15 @@ public class PRIORITY_QUEUES
@Override @Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.matchesAll(filter); } } public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.matchesAll(filter); } }
@Override @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 @Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.count(filter); } } public int count(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.count(filter); } }
} }
@@ -360,6 +360,10 @@ public class SETS
s = c; s = c;
} }
@Override
public void addFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public void addLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -371,17 +375,19 @@ public class SETS
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return ITERATORS.unmodifiable(s.iterator()); } public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return ITERATORS.unmodifiable(s.iterator()); }
@Override @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)); } public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return ITERATORS.unmodifiable(s.iterator(fromElement)); }
@Override @Override
public ORDERED_SET KEY_GENERIC_TYPE copy() { return s.copy(); } public ORDERED_SET KEY_GENERIC_TYPE copy() { return s.copy(); }
@Override @Override
public KEY_TYPE FIRST_KEY() { return s.FIRST_KEY(); } public KEY_TYPE GET_FIRST_KEY() { return s.GET_FIRST_KEY(); }
@Override @Override
public KEY_TYPE POLL_FIRST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE REMOVE_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public KEY_TYPE LAST_KEY() { return s.LAST_KEY(); } public KEY_TYPE GET_LAST_KEY() { return s.GET_LAST_KEY(); }
@Override @Override
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE REMOVE_LAST_KEY() { throw new UnsupportedOperationException(); }
} }
#endif #endif
@@ -649,6 +655,10 @@ public class SETS
s = c; 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 @Override
public boolean addAndMoveToFirst(KEY_TYPE o) { synchronized(mutex) { return s.addAndMoveToFirst(o); } } public boolean addAndMoveToFirst(KEY_TYPE o) { synchronized(mutex) { return s.addAndMoveToFirst(o); } }
@Override @Override
@@ -660,17 +670,19 @@ public class SETS
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { synchronized(mutex) { return s.iterator(); } } public BI_ITERATOR KEY_GENERIC_TYPE iterator() { synchronized(mutex) { return s.iterator(); } }
@Override @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); } } public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { synchronized(mutex) { return s.iterator(fromElement); } }
@Override @Override
public ORDERED_SET KEY_GENERIC_TYPE copy() { synchronized(mutex) { return s.copy(); } } public ORDERED_SET KEY_GENERIC_TYPE copy() { synchronized(mutex) { return s.copy(); } }
@Override @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 @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 @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 @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 #endif
@@ -56,6 +56,9 @@ import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.utils.SETS; import speiger.src.collections.PACKAGE.utils.SETS;
#endif #endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; 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 #if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
#endif #endif
@@ -346,6 +349,16 @@ public class MAPS
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); }
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -408,6 +421,16 @@ public class MAPS
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); }
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -533,6 +556,10 @@ public class MAPS
@Override @Override
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
@Override @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(); } public boolean moveToFirst(KEY_TYPE key) { throw new UnsupportedOperationException(); }
@Override @Override
public boolean moveToLast(KEY_TYPE key) { throw new UnsupportedOperationException(); } public boolean moveToLast(KEY_TYPE key) { throw new UnsupportedOperationException(); }
@@ -553,13 +580,25 @@ public class MAPS
@Override @Override
public VALUE_TYPE LAST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); } public VALUE_TYPE LAST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); }
@Override @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(); } public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { return map.copy(); }
@Override @Override
public ORDERED_SET KEY_GENERIC_TYPE keySet() { public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keys == null) keys = SETS.unmodifiable(map.keySet()); if(keys == null) keys = SETS.unmodifiable(map.keySet());
return (ORDERED_SET KEY_GENERIC_TYPE)keys; 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 @Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new UnmodifyableOrderedEntrySetKV_BRACES(map.ENTRY_SET()); if(entrySet == null) entrySet = new UnmodifyableOrderedEntrySetKV_BRACES(map.ENTRY_SET());
@@ -659,6 +698,16 @@ public class MAPS
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); }
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -706,6 +755,10 @@ public class MAPS
set = 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 @Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); } public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override @Override
@@ -719,15 +772,17 @@ public class MAPS
@Override @Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { return ObjectIterators.unmodifiable(set.iterator()); } public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { return ObjectIterators.unmodifiable(set.iterator()); }
@Override @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)); } public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator(MAP.Entry KEY_VALUE_GENERIC_TYPE fromElement) { return ObjectIterators.unmodifiable(set.iterator(fromElement)); }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() { return set.first(); } public MAP.Entry KEY_VALUE_GENERIC_TYPE getFirst() { return set.getFirst(); }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() { throw new UnsupportedOperationException(); } public MAP.Entry KEY_VALUE_GENERIC_TYPE removeFirst() { throw new UnsupportedOperationException(); }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() { return set.last(); } public MAP.Entry KEY_VALUE_GENERIC_TYPE getLast() { return set.getLast(); }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() { throw new UnsupportedOperationException(); } public MAP.Entry KEY_VALUE_GENERIC_TYPE removeLast() { throw new UnsupportedOperationException(); }
} }
#endif #endif
@@ -908,6 +963,10 @@ public class MAPS
@Override @Override
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.putAndMoveToLast(key, value); } } public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.putAndMoveToLast(key, value); } }
@Override @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); } } public boolean moveToFirst(KEY_TYPE key) { synchronized(mutex) { return map.moveToFirst(key); } }
@Override @Override
public boolean moveToLast(KEY_TYPE key) { synchronized(mutex) { return map.moveToLast(key); } } public boolean moveToLast(KEY_TYPE key) { synchronized(mutex) { return map.moveToLast(key); } }
@@ -928,13 +987,25 @@ public class MAPS
@Override @Override
public VALUE_TYPE LAST_ENTRY_VALUE() { synchronized(mutex) { return map.LAST_ENTRY_VALUE(); } } public VALUE_TYPE LAST_ENTRY_VALUE() { synchronized(mutex) { return map.LAST_ENTRY_VALUE(); } }
@Override @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(); } } public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { synchronized(mutex) { return map.copy(); } }
@Override @Override
public ORDERED_SET KEY_GENERIC_TYPE keySet() { public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keys == null) keys = SETS.synchronize(map.keySet(), mutex); if(keys == null) keys = SETS.synchronize(map.keySet(), mutex);
return (ORDERED_SET KEY_GENERIC_TYPE)keys; 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 @Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = ObjectSets.synchronize(map.ENTRY_SET(), mutex); if(entrySet == null) entrySet = ObjectSets.synchronize(map.ENTRY_SET(), mutex);
@@ -1091,6 +1162,16 @@ public class MAPS
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_PRESENT(key, mappingFunction); } } public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_PRESENT(key, mappingFunction); } }
@Override @Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { synchronized(mutex) { return map.SUPPLY_IF_ABSENT(key, valueProvider); } } public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { synchronized(mutex) { return map.SUPPLY_IF_ABSENT(key, valueProvider); } }
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTENonDefault(key, mappingFunction); } }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_ABSENTNonDefault(key, mappingFunction); } }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_PRESENTNonDefault(key, mappingFunction); } }
@Override
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { synchronized(mutex) { return map.SUPPLY_IF_ABSENTNonDefault(key, valueProvider); } }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.MERGE(key, value, mappingFunction); } } public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.MERGE(key, value, mappingFunction); } }
@Override @Override
@@ -1,16 +1,29 @@
package speiger.src.testers.PACKAGE.builder; package speiger.src.testers.PACKAGE.builder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import com.google.common.collect.testing.AbstractTester; 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.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.CollectionFeature;
import com.google.common.collect.testing.features.Feature;
import junit.framework.TestSuite; 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.generators.TEST_ORDERED_SET_GENERATOR;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetMoveTester; 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_TYPEOrderedSetIterationTester;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetNavigationTester; 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") @SuppressWarnings("javadoc")
public class ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE extends SET_TEST_BUILDER KEY_GENERIC_TYPE { 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 #endignore
return super.createTestSuite(); 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();
}
} }
@@ -53,6 +53,11 @@ import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapCl
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeTester;
#if !VALUE_OBJECT
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentNonDefaultTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentNonDefaultTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeNonDefaultTester;
#endif
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapCopyTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapCopyTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapContainsTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapContainsTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapContainsKeyTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapContainsKeyTester;
@@ -78,6 +83,9 @@ import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapRe
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapReplaceTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapReplaceTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapSizeTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapSizeTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentTester;
#if !VALUE_OBJECT
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentNonDefaultTester;
#endif
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapToStringTester; import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEMapToStringTester;
import speiger.src.testers.objects.builder.ObjectSetTestSuiteBuilder; import speiger.src.testers.objects.builder.ObjectSetTestSuiteBuilder;
import speiger.src.testers.objects.generators.TestObjectSetGenerator; import speiger.src.testers.objects.generators.TestObjectSetGenerator;
@@ -105,6 +113,12 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
protected List<Class<? extends AbstractTester>> getTesters() { protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers = new ArrayList<>(); List<Class<? extends AbstractTester>> testers = new ArrayList<>();
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapClearTester.class); testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapClearTester.class);
#if !VALUE_OBJECT
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeNonDefaultTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentNonDefaultTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentNonDefaultTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentNonDefaultTester.class);
#endif
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeTester.class); testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester.class); testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentTester.class); testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentTester.class);
@@ -224,21 +238,17 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
private static Set<Feature<?>> computeEntrySetFeatures(Set<Feature<?>> mapFeatures) { private static Set<Feature<?>> computeEntrySetFeatures(Set<Feature<?>> mapFeatures) {
Set<Feature<?>> entrySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); Set<Feature<?>> entrySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore #ignore
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) { if (mapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
} if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) entrySetFeatures.add(SpecialFeature.COPYING);
if(mapFeatures.contains(SpecialFeature.CHILDREN_COPY)) { else entrySetFeatures.remove(SpecialFeature.COPYING);
entrySetFeatures.add(SpecialFeature.COPYING);
} if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) entrySetFeatures.add(SpecialFeature.MODIFIABLE);
else { else entrySetFeatures.remove(SpecialFeature.MODIFIABLE);
entrySetFeatures.remove(SpecialFeature.COPYING);
} if(mapFeatures.contains(SpecialFeature.REVERSE)) entrySetFeatures.add(SpecialFeature.REVERSE);
if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) { else entrySetFeatures.remove(SpecialFeature.REVERSE);
entrySetFeatures.add(SpecialFeature.MODIFIABLE);
}
else {
entrySetFeatures.remove(SpecialFeature.MODIFIABLE);
}
entrySetFeatures.add(SpecialFeature.MAP_ENTRY); entrySetFeatures.add(SpecialFeature.MAP_ENTRY);
#endignore #endignore
return entrySetFeatures; return entrySetFeatures;
@@ -248,23 +258,17 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
Set<Feature<?>> keySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); Set<Feature<?>> keySetFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore #ignore
keySetFeatures.add(CollectionFeature.SUBSET_VIEW); keySetFeatures.add(CollectionFeature.SUBSET_VIEW);
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) { if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) keySetFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
keySetFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES); else if (mapFeatures.contains(MapFeature.ALLOWS_NULL_KEY_QUERIES)) keySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
} 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.CHILDREN_COPY)) {
keySetFeatures.add(SpecialFeature.COPYING); if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) keySetFeatures.add(SpecialFeature.MODIFIABLE);
} else keySetFeatures.remove(SpecialFeature.MODIFIABLE);
else {
keySetFeatures.remove(SpecialFeature.COPYING); if(mapFeatures.contains(SpecialFeature.REVERSE)) keySetFeatures.add(SpecialFeature.REVERSE);
} else keySetFeatures.remove(SpecialFeature.REVERSE);
if(mapFeatures.contains(SpecialFeature.MODIFIABLE)) {
keySetFeatures.add(SpecialFeature.MODIFIABLE);
}
else {
keySetFeatures.remove(SpecialFeature.MODIFIABLE);
}
#endignore #endignore
return keySetFeatures; return keySetFeatures;
} }
@@ -273,18 +277,15 @@ public class MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MapTestSuiteBuilder
private static Set<Feature<?>> computeValuesCollectionFeatures(Set<Feature<?>> mapFeatures) { private static Set<Feature<?>> computeValuesCollectionFeatures(Set<Feature<?>> mapFeatures) {
Set<Feature<?>> valuesCollectionFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures); Set<Feature<?>> valuesCollectionFeatures = MapTestSuiteBuilder.computeCommonDerivedCollectionFeatures(mapFeatures);
#ignore #ignore
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) { if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
} if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
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.CHILDREN_COPY)) {
valuesCollectionFeatures.add(SpecialFeature.COPYING); if(mapFeatures.contains(SpecialFeature.REVERSE)) valuesCollectionFeatures.add(SpecialFeature.REVERSE);
} else valuesCollectionFeatures.remove(SpecialFeature.REVERSE);
else {
valuesCollectionFeatures.remove(SpecialFeature.COPYING);
}
#endignore #endignore
return valuesCollectionFeatures; return valuesCollectionFeatures;
} }
@@ -1,9 +1,14 @@
package speiger.src.testers.PACKAGE.builder.maps; package speiger.src.testers.PACKAGE.builder.maps;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import com.google.common.collect.testing.AbstractTester; 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.CollectionFeature;
import com.google.common.collect.testing.features.Feature;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; 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_ORDERED_SET_GENERATOR;
import speiger.src.testers.PACKAGE.generators.TEST_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.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_TYPEOrderedMapMoveTester;
import speiger.src.testers.PACKAGE.tests.maps.FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapNavigationTester; 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 #if !TYPE_OBJECT
import speiger.src.testers.objects.builder.ObjectSetTestSuiteBuilder; import speiger.src.testers.objects.builder.ObjectSetTestSuiteBuilder;
import speiger.src.testers.objects.generators.TestObjectSetGenerator; import speiger.src.testers.objects.generators.TestObjectSetGenerator;
import speiger.src.testers.objects.builder.ObjectOrderedSetTestSuiteBuilder; import speiger.src.testers.objects.builder.ObjectOrderedSetTestSuiteBuilder;
import speiger.src.testers.objects.generators.TestObjectOrderedSetGenerator; import speiger.src.testers.objects.generators.TestObjectOrderedSetGenerator;
#endif #endif
import speiger.src.testers.utils.SpecialFeature;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE 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(); List<Class<? extends AbstractTester>> testers = super.getTesters();
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapMoveTester.class); testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapMoveTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapNavigationTester.class); testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapNavigationTester.class);
testers.add(FILE_KEY_TYPE2FILE_VALUE_TYPEOrderedMapPutTester.class);
return testers; return testers;
} }
@@ -45,6 +54,15 @@ public class ORDERED_MAP_TEST_BUILDER KEY_VALUE_GENERIC_TYPE extends MAP_TEST_BU
return super.createTestSuite(); 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) { 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); 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) { 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); 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;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP.Entry; 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.NAVIGABLE_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.SORTED_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.SORTED_MAP;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.SET; 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 public static class MapGenerator KEY_VALUE_GENERIC_TYPE implements TEST_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE
{ {
TEST_MAP_GENERATOR KEY_VALUE_GENERIC_TYPE parent; 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 #if TYPE_OBJECT
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP; 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.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 #endif
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP; import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
@@ -134,6 +136,97 @@ public class MAP_CONSTRUCTOR_TESTS
} }
#if TYPE_OBJECT #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 #if VALUE_OBJECT
public static class EnumMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester<AnEnum, String> public static class EnumMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester<AnEnum, String>
#else #else
@@ -26,6 +26,15 @@ public class FILE_KEY_TYPECollectionForEachTester KEY_GENERIC_TYPE extends ABSTR
HELPERS.assertContentsAnyOrder(elements, createSamplesArray()); 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 #ignore
@CollectionFeature.Require(absent = KNOWN_ORDER) @CollectionFeature.Require(absent = KNOWN_ORDER)
public void testForEachExtraUnknownOrder() { public void testForEachExtraUnknownOrder() {
@@ -44,6 +53,15 @@ public class FILE_KEY_TYPECollectionForEachTester KEY_GENERIC_TYPE extends ABSTR
assertEquals("Different ordered iteration", HELPERS.copyToList(getOrderedElements()), elements); 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 #ignore
@CollectionFeature.Require(KNOWN_ORDER) @CollectionFeature.Require(KNOWN_ORDER)
public void testForEachExtraKnownOrder() { public void testForEachExtraKnownOrder() {
@@ -4,6 +4,12 @@ package speiger.src.testers.PACKAGE.tests.iterable;
import java.util.Objects; import java.util.Objects;
#endif #endif
#if JDK_TYPE
import java.util.OPTIONAL;
#else
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif
import org.junit.Ignore; import org.junit.Ignore;
import com.google.common.collect.testing.features.CollectionSize; 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) @CollectionSize.Require(absent = CollectionSize.ZERO)
#endignore #endignore
public void testIterableFindFirst_FindFirstElements() { 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() { 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 #ignore
@CollectionSize.Require(CollectionSize.SEVERAL) @CollectionSize.Require(CollectionSize.SEVERAL)
#endignore #endignore
public void testIterableFindFirst_FindLastElement() { 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 #if TYPE_OBJECT
import java.util.Objects; import java.util.Objects;
#endif
#if JDK_TYPE
import java.util.OPTIONAL;
#else
import speiger.src.collections.PACKAGE.functions.OPTIONAL;
#endif #endif
import org.junit.Ignore; import org.junit.Ignore;
import com.google.common.collect.testing.features.CollectionSize;
import speiger.src.testers.PACKAGE.tests.base.ABSTRACT_COLLECTION_TESTER; import speiger.src.testers.PACKAGE.tests.base.ABSTRACT_COLLECTION_TESTER;
@Ignore @Ignore
@@ -29,7 +36,7 @@ public class FILE_KEY_TYPEIterableReduceTester KEY_GENERIC_TYPE extends ABSTRACT
} }
public void testIterableReduce() { 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() { public void testIterableExtraReduce() {
@@ -0,0 +1,153 @@
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;
#endignore
#if !VALUE_BOOLEAN
#ignore
import static com.google.common.collect.testing.features.CollectionSize.ONE;
#endignore
#endif
import org.junit.Ignore;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import junit.framework.AssertionFailedError;
import speiger.src.testers.PACKAGE.tests.base.maps.ABSTRACT_MAP_TESTER;
@Ignore
@SuppressWarnings("javadoc")
public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentNonDefaultTester KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP_TESTER KEY_VALUE_GENERIC_TYPE
{
#ignore
@MapFeature.Require(SUPPORTS_PUT)
#endignore
public void testComputeIfAbsent_supportedAbsent() {
#if VALUE_BOOLEAN
getMap().setDefaultReturnValue(true);
#endif
assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v3(), getMap().COMPUTE_IF_ABSENTNonDefault(k3(), k -> {
assertEquals(k3(), k);
return v3();
}));
expectAdded(e3());
}
#if !VALUE_BOOLEAN
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(ONE)
#endignore
public void testComputeIfAbsent_supportedAbsentFirst() {
getMap().setDefaultReturnValue(v0());
assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v3(), getMap().COMPUTE_IF_ABSENTNonDefault(k0(), k -> {
assertEquals(k0(), k);
return v3();
}));
expectContents(entry(k0(), v3()));
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(ONE)
#endignore
public void testComputeIfAbsent_supportedAbsentSameResult() {
getMap().setDefaultReturnValue(v0());
assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v0(), getMap().COMPUTE_IF_ABSENTNonDefault(k0(), k -> {
assertEquals(k0(), k);
return v0();
}));
expectUnchanged();
}
#endif
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testComputeIfAbsent_supportedPresent() {
assertEquals("COMPUTE_IF_ABSENT(present, function) should return existing value", v0(), getMap().COMPUTE_IF_ABSENTNonDefault(k0(), k -> {
throw new AssertionFailedError();
}));
expectUnchanged();
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
#endignore
public void testComputeIfAbsent_functionReturnsNullNotInserted() {
assertEquals("COMPUTE_IF_ABSENT(absent, returnsNull) should return INVALID_VALUE", INVALID_VALUE, getMap().COMPUTE_IF_ABSENTNonDefault(k3(), k -> {
assertEquals(k3(), k);
return INVALID_VALUE;
}));
expectUnchanged();
}
static class ExpectedException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
#endignore
public void testComputeIfAbsent_functionThrows() {
try {
getMap().COMPUTE_IF_ABSENTNonDefault(k3(), k -> {
assertEquals(k3(), k);
throw new ExpectedException();
});
fail("Expected ExpectedException");
} catch (ExpectedException expected) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
#endignore
public void testComputeIfAbsent_unsupportedAbsent() {
try {
getMap().COMPUTE_IF_ABSENTNonDefault(k3(), k -> {
// allowed to be called
assertEquals(k3(), k);
return v3();
});
fail("COMPUTE_IF_ABSENT(notPresent, function) should throw");
} catch (UnsupportedOperationException expected) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testComputeIfAbsent_unsupportedPresentExistingValue() {
try {
assertEquals("COMPUTE_IF_ABSENT(present, returnsCurrentValue) should return present or throw", v0(), getMap().COMPUTE_IF_ABSENTNonDefault(k0(), k -> {
assertEquals(k0(), k);
return v0();
}));
} catch (UnsupportedOperationException tolerated) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testComputeIfAbsent_unsupportedPresentDifferentValue() {
try {
assertEquals("COMPUTE_IF_ABSENT(present, returnsDifferentValue) should return present or throw", v0(), getMap().COMPUTE_IF_ABSENTNonDefault(k0(), k -> {
assertEquals(k0(), k);
return v3();
}));
} catch (UnsupportedOperationException tolerated) {
}
expectUnchanged();
}
}
@@ -26,8 +26,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester KEY_VALUE_GEN
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
#endignore #endignore
public void testComputeIfAbsent_supportedAbsent() { public void testComputeIfAbsent_supportedAbsent() {
assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v3(), assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v3(), getMap().COMPUTE_IF_ABSENT(k3(), k -> {
getMap().COMPUTE_IF_ABSENT(k3(), k -> {
assertEquals(k3(), k); assertEquals(k3(), k);
return v3(); return v3();
})); }));
@@ -41,12 +40,19 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester KEY_VALUE_GEN
#endignore #endignore
public void testComputeIfAbsent_supportedAbsentFirst() { public void testComputeIfAbsent_supportedAbsentFirst() {
getMap().setDefaultReturnValue(v0()); getMap().setDefaultReturnValue(v0());
assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v3(), #if VALUE_OBJECT
getMap().COMPUTE_IF_ABSENT(k0(), k -> { assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v3(), getMap().COMPUTE_IF_ABSENT(k0(), k -> {
assertEquals(k0(), k); assertEquals(k0(), k);
return v3(); return v3();
})); }));
expectContents(entry(k0(), v3())); expectContents(entry(k0(), v3()));
#else
assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v0(), getMap().COMPUTE_IF_ABSENT(k0(), k -> {
assertEquals(k0(), k);
return v3();
}));
expectUnchanged();
#endif
} }
#ignore #ignore
@@ -55,8 +61,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester KEY_VALUE_GEN
#endignore #endignore
public void testComputeIfAbsent_supportedAbsentSameResult() { public void testComputeIfAbsent_supportedAbsentSameResult() {
getMap().setDefaultReturnValue(v0()); getMap().setDefaultReturnValue(v0());
assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v0(), assertEquals("COMPUTE_IF_ABSENT(notPresent, function) should return new value", v0(), getMap().COMPUTE_IF_ABSENT(k0(), k -> {
getMap().COMPUTE_IF_ABSENT(k0(), k -> {
assertEquals(k0(), k); assertEquals(k0(), k);
return v0(); return v0();
})); }));
@@ -69,8 +74,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester KEY_VALUE_GEN
@CollectionSize.Require(absent = ZERO) @CollectionSize.Require(absent = ZERO)
#endignore #endignore
public void testComputeIfAbsent_supportedPresent() { public void testComputeIfAbsent_supportedPresent() {
assertEquals("COMPUTE_IF_ABSENT(present, function) should return existing value", v0(), assertEquals("COMPUTE_IF_ABSENT(present, function) should return existing value", v0(), getMap().COMPUTE_IF_ABSENT(k0(), k -> {
getMap().COMPUTE_IF_ABSENT(k0(), k -> {
throw new AssertionFailedError(); throw new AssertionFailedError();
})); }));
expectUnchanged(); expectUnchanged();
@@ -80,12 +84,15 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester KEY_VALUE_GEN
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
#endignore #endignore
public void testComputeIfAbsent_functionReturnsNullNotInserted() { public void testComputeIfAbsent_functionReturnsNullNotInserted() {
assertEquals("COMPUTE_IF_ABSENT(absent, returnsNull) should return INVALID_VALUE", assertEquals("COMPUTE_IF_ABSENT(absent, returnsNull) should return INVALID_VALUE", INVALID_VALUE, getMap().COMPUTE_IF_ABSENT(k3(), k -> {
INVALID_VALUE, getMap().COMPUTE_IF_ABSENT(k3(), k -> {
assertEquals(k3(), k); assertEquals(k3(), k);
return INVALID_VALUE; return INVALID_VALUE;
})); }));
#if VALUE_OBJECT
expectUnchanged(); expectUnchanged();
#else
expectAdded(entry(k3(), INVALID_VALUE));
#endif
} }
static class ExpectedException extends RuntimeException { static class ExpectedException extends RuntimeException {
@@ -129,8 +136,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester KEY_VALUE_GEN
#endignore #endignore
public void testComputeIfAbsent_unsupportedPresentExistingValue() { public void testComputeIfAbsent_unsupportedPresentExistingValue() {
try { try {
assertEquals("COMPUTE_IF_ABSENT(present, returnsCurrentValue) should return present or throw", v0(), assertEquals("COMPUTE_IF_ABSENT(present, returnsCurrentValue) should return present or throw", v0(), getMap().COMPUTE_IF_ABSENT(k0(), k -> {
getMap().COMPUTE_IF_ABSENT(k0(), k -> {
assertEquals(k0(), k); assertEquals(k0(), k);
return v0(); return v0();
})); }));
@@ -145,8 +151,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfAbsentTester KEY_VALUE_GEN
#endignore #endignore
public void testComputeIfAbsent_unsupportedPresentDifferentValue() { public void testComputeIfAbsent_unsupportedPresentDifferentValue() {
try { try {
assertEquals("COMPUTE_IF_ABSENT(present, returnsDifferentValue) should return present or throw", v0(), assertEquals("COMPUTE_IF_ABSENT(present, returnsDifferentValue) should return present or throw", v0(), getMap().COMPUTE_IF_ABSENT(k0(), k -> {
getMap().COMPUTE_IF_ABSENT(k0(), k -> {
assertEquals(k0(), k); assertEquals(k0(), k);
return v3(); return v3();
})); }));
@@ -0,0 +1,104 @@
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;
#endignore
import org.junit.Ignore;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import junit.framework.AssertionFailedError;
import speiger.src.testers.PACKAGE.tests.base.maps.ABSTRACT_MAP_TESTER;
@Ignore
@SuppressWarnings("javadoc")
public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentNonDefaultTester KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP_TESTER KEY_VALUE_GENERIC_TYPE
{
#ignore
@MapFeature.Require(SUPPORTS_PUT)
#endignore
public void testComputeIfPresent_supportedAbsent() {
assertEquals("COMPUTE_IF_PRESENT(notPresent, function) should return INVALID_VALUE", INVALID_VALUE, getMap().COMPUTE_IF_PRESENTNonDefault(k3(), (k, v) -> {
throw new AssertionFailedError();
}));
expectUnchanged();
}
#if !VALUE_BOOLEAN
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testComputeIfPresent_supportedPresent() {
assertEquals("COMPUTE_IF_PRESENT(present, function) should return new value", v3(), getMap().COMPUTE_IF_PRESENTNonDefault(k0(), (k, v) -> {
assertEquals(k0(), k);
assertEquals(v0(), v);
return v3();
}));
expectReplacement(entry(k0(), v3()));
}
#endif
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testComputeIfPresent_functionReturnsNull() {
assertEquals("COMPUTE_IF_PRESENT(present, returnsNull) should return INVALID_VALUE", INVALID_VALUE, getMap().COMPUTE_IF_PRESENTNonDefault(k0(), (k, v) -> {
assertEquals(k0(), k);
assertEquals(v0(), v);
return INVALID_VALUE;
}));
expectMissing(e0());
}
static class ExpectedException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testComputeIfPresent_functionThrows() {
try {
getMap().COMPUTE_IF_PRESENTNonDefault(k0(), (k, v) -> {
assertEquals(k0(), k);
assertEquals(v0(), v);
throw new ExpectedException();
});
fail("Expected ExpectedException");
} catch (ExpectedException expected) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
#endignore
public void testComputeIfPresent_unsupportedAbsent() {
try {
getMap().COMPUTE_IF_PRESENTNonDefault(k3(), (k, v) -> {
throw new AssertionFailedError();
});
} catch (UnsupportedOperationException tolerated) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testComputeIfPresent_unsupportedPresent() {
try {
getMap().COMPUTE_IF_PRESENTNonDefault(k0(), (k, v) -> v3());
fail("Expected UnsupportedOperationException");
} catch (UnsupportedOperationException expected) {
}
expectUnchanged();
}
}
@@ -21,8 +21,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentTester KEY_VALUE_GE
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
#endignore #endignore
public void testComputeIfPresent_supportedAbsent() { public void testComputeIfPresent_supportedAbsent() {
assertEquals("COMPUTE_IF_PRESENT(notPresent, function) should return INVALID_VALUE", INVALID_VALUE, assertEquals("COMPUTE_IF_PRESENT(notPresent, function) should return INVALID_VALUE", INVALID_VALUE, getMap().COMPUTE_IF_PRESENT(k3(), (k, v) -> {
getMap().COMPUTE_IF_PRESENT(k3(), (k, v) -> {
throw new AssertionFailedError(); throw new AssertionFailedError();
})); }));
expectUnchanged(); expectUnchanged();
@@ -33,8 +32,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentTester KEY_VALUE_GE
@CollectionSize.Require(absent = ZERO) @CollectionSize.Require(absent = ZERO)
#endignore #endignore
public void testComputeIfPresent_supportedPresent() { public void testComputeIfPresent_supportedPresent() {
assertEquals("COMPUTE_IF_PRESENT(present, function) should return new value", v3(), assertEquals("COMPUTE_IF_PRESENT(present, function) should return new value", v3(), getMap().COMPUTE_IF_PRESENT(k0(), (k, v) -> {
getMap().COMPUTE_IF_PRESENT(k0(), (k, v) -> {
assertEquals(k0(), k); assertEquals(k0(), k);
assertEquals(v0(), v); assertEquals(v0(), v);
return v3(); return v3();
@@ -47,8 +45,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeIfPresentTester KEY_VALUE_GE
@CollectionSize.Require(absent = ZERO) @CollectionSize.Require(absent = ZERO)
#endignore #endignore
public void testComputeIfPresent_functionReturnsNull() { public void testComputeIfPresent_functionReturnsNull() {
assertEquals("COMPUTE_IF_PRESENT(present, returnsNull) should return INVALID_VALUE", INVALID_VALUE, assertEquals("COMPUTE_IF_PRESENT(present, returnsNull) should return INVALID_VALUE", INVALID_VALUE, getMap().COMPUTE_IF_PRESENT(k0(), (k, v) -> {
getMap().COMPUTE_IF_PRESENT(k0(), (k, v) -> {
assertEquals(k0(), k); assertEquals(k0(), k);
assertEquals(v0(), v); assertEquals(v0(), v);
return INVALID_VALUE; return INVALID_VALUE;
@@ -0,0 +1,148 @@
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;
#endignore
import org.junit.Ignore;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import speiger.src.testers.PACKAGE.tests.base.maps.ABSTRACT_MAP_TESTER;
@Ignore
@SuppressWarnings("javadoc")
public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeNonDefaultTester KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP_TESTER KEY_VALUE_GENERIC_TYPE
{
#if !VALUE_BOOLEAN
#ignore
@MapFeature.Require({ SUPPORTS_PUT, SUPPORTS_REMOVE })
#endignore
public void testCompute_absentToPresent() {
assertEquals("Map.COMPUTE(absent, functionReturningValue) should return value", v3(), getMap().COMPUTENonDefault(k3(), (k, v) -> {
assertEquals(k3(), k);
assertEquals(INVALID_VALUE, v);
return v3();
}));
expectAdded(e3());
assertEquals(getNumElements() + 1, getMap().size());
}
#endif
#ignore
@MapFeature.Require({ SUPPORTS_PUT, SUPPORTS_REMOVE })
#endignore
public void testCompute_absentToAbsent() {
assertEquals("Map.COMPUTE(absent, functionReturningNull) should return INVALID_VALUE", INVALID_VALUE, getMap().COMPUTENonDefault(k3(), (k, v) -> {
assertEquals(k3(), k);
assertEquals(INVALID_VALUE, v);
return INVALID_VALUE;
}));
expectUnchanged();
assertEquals(getNumElements(), getMap().size());
}
#ignore
@MapFeature.Require({ SUPPORTS_PUT, SUPPORTS_REMOVE })
@CollectionSize.Require(absent = ZERO)
#endignore
public void testCompute_presentToPresent() {
#if VALUE_BOOLEAN
getMap().setDefaultReturnValue(true);
#endif
assertEquals("Map.COMPUTE(present, functionReturningValue) should return new value", v3(), getMap().COMPUTENonDefault(k0(), (k, v) -> {
assertEquals(k0(), k);
assertEquals(v0(), v);
return v3();
}));
expectReplacement(entry(k0(), v3()));
assertEquals(getNumElements(), getMap().size());
}
#ignore
@MapFeature.Require({ SUPPORTS_PUT, SUPPORTS_REMOVE })
@CollectionSize.Require(absent = ZERO)
#endignore
public void testCompute_presentToAbsent() {
assertEquals("Map.COMPUTE(present, functionReturningNull) should return INVALID_VALUE", INVALID_VALUE, getMap().COMPUTENonDefault(k0(), (k, v) -> {
assertEquals(k0(), k);
assertEquals(v0(), v);
return INVALID_VALUE;
}));
expectMissing(e0());
expectMissingKeys(k0());
assertEquals(getNumElements() - 1, getMap().size());
}
static class ExpectedException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
#ignore
@MapFeature.Require({ SUPPORTS_PUT, SUPPORTS_REMOVE })
@CollectionSize.Require(absent = ZERO)
#endignore
public void testCompute_presentFunctionThrows() {
try {
getMap().COMPUTENonDefault(k0(), (k, v) -> {
assertEquals(k0(), k);
assertEquals(v0(), v);
throw new ExpectedException();
});
fail("Expected ExpectedException");
} catch (ExpectedException expected) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require({ SUPPORTS_PUT, SUPPORTS_REMOVE })
#endignore
public void testCompute_absentFunctionThrows() {
try {
getMap().COMPUTENonDefault(k3(), (k, v) -> {
assertEquals(k3(), k);
assertEquals(INVALID_VALUE, v);
throw new ExpectedException();
});
fail("Expected ExpectedException");
} catch (ExpectedException expected) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_REMOVE)
#endignore
public void testCompute_removeAbsent() {
try {
getMap().COMPUTENonDefault(k3(), (k, v) -> {
assertEquals(k3(), k);
assertEquals(INVALID_VALUE, v);
return INVALID_VALUE;
});
fail("Expected UnsupportedOperationException");
} catch (UnsupportedOperationException expected) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
#endignore
public void testCompute_putAbsent() {
try {
getMap().COMPUTENonDefault(k3(), (k, v) -> {
assertEquals(k3(), k);
assertEquals(INVALID_VALUE, v);
return INVALID_VALUE;
});
fail("Expected UnsupportedOperationException");
} catch (UnsupportedOperationException expected) {
}
expectUnchanged();
}
}
@@ -21,8 +21,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeTester KEY_VALUE_GENERIC_TYP
@MapFeature.Require({ SUPPORTS_PUT, SUPPORTS_REMOVE }) @MapFeature.Require({ SUPPORTS_PUT, SUPPORTS_REMOVE })
#endignore #endignore
public void testCompute_absentToPresent() { public void testCompute_absentToPresent() {
assertEquals("Map.COMPUTE(absent, functionReturningValue) should return value", v3(), assertEquals("Map.COMPUTE(absent, functionReturningValue) should return value", v3(), getMap().COMPUTE(k3(), (k, v) -> {
getMap().COMPUTE(k3(), (k, v) -> {
assertEquals(k3(), k); assertEquals(k3(), k);
assertEquals(INVALID_VALUE, v); assertEquals(INVALID_VALUE, v);
return v3(); return v3();
@@ -40,8 +39,13 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeTester KEY_VALUE_GENERIC_TYP
assertEquals(INVALID_VALUE, v); assertEquals(INVALID_VALUE, v);
return INVALID_VALUE; return INVALID_VALUE;
})); }));
#if VALUE_OBJECT
expectUnchanged(); expectUnchanged();
assertEquals(getNumElements(), getMap().size()); assertEquals(getNumElements(), getMap().size());
#else
expectAdded(entry(k3(), INVALID_VALUE));
assertEquals(getNumElements()+1, getMap().size());
#endif
} }
#ignore #ignore
@@ -49,8 +53,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeTester KEY_VALUE_GENERIC_TYP
@CollectionSize.Require(absent = ZERO) @CollectionSize.Require(absent = ZERO)
#endignore #endignore
public void testCompute_presentToPresent() { public void testCompute_presentToPresent() {
assertEquals("Map.COMPUTE(present, functionReturningValue) should return new value", v3(), assertEquals("Map.COMPUTE(present, functionReturningValue) should return new value", v3(), getMap().COMPUTE(k0(), (k, v) -> {
getMap().COMPUTE(k0(), (k, v) -> {
assertEquals(k0(), k); assertEquals(k0(), k);
assertEquals(v0(), v); assertEquals(v0(), v);
return v3(); return v3();
@@ -69,9 +72,14 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapComputeTester KEY_VALUE_GENERIC_TYP
assertEquals(v0(), v); assertEquals(v0(), v);
return INVALID_VALUE; return INVALID_VALUE;
})); }));
#if VALUE_OBJECT
expectMissing(e0()); expectMissing(e0());
expectMissingKeys(k0()); expectMissingKeys(k0());
assertEquals(getNumElements() - 1, getMap().size()); assertEquals(getNumElements() - 1, getMap().size());
#else
expectReplacement(entry(k0(), INVALID_VALUE));
assertEquals(getNumElements(), getMap().size());
#endif
} }
static class ExpectedException extends RuntimeException { static class ExpectedException extends RuntimeException {
@@ -27,6 +27,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapContainsTester KEY_VALUE_GENERIC_TY
#ignore #ignore
@CollectionSize.Require(absent = ZERO) @CollectionSize.Require(absent = ZERO)
@SuppressWarnings("unlikely-arg-type")
#endignore #endignore
public void testContainsObject_yes() { public void testContainsObject_yes() {
assertTrue("contains(present) should return true", getMap().ENTRY_SET().contains(new AbstractMap.SimpleEntry<>(e0()))); 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())); assertFalse("contains(notPresent) should return false", getMap().ENTRY_SET().contains(e3()));
} }
@SuppressWarnings("unlikely-arg-type")
public void testContainsObject_no() { public void testContainsObject_no() {
assertFalse("contains(notPresent) should return false", getMap().ENTRY_SET().contains(new AbstractMap.SimpleEntry<>(e3()))); 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 #ignore
@CollectionSize.Require(ONE) @CollectionSize.Require(ONE)
@MapFeature.Require(SUPPORTS_REMOVE) @MapFeature.Require(SUPPORTS_REMOVE)
@SuppressWarnings("unlikely-arg-type")
#endignore #endignore
public void testRemove_supportedObjectEntryPresent() { public void testRemove_supportedObjectEntryPresent() {
assertTrue(getMap().ENTRY_SET().remove(new AbstractMap.SimpleEntry<>(e0()))); assertTrue(getMap().ENTRY_SET().remove(new AbstractMap.SimpleEntry<>(e0())));
@@ -154,6 +155,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapRemoveEntryTester KEY_VALUE_GENERIC
#ignore #ignore
@CollectionSize.Require(ONE) @CollectionSize.Require(ONE)
@MapFeature.Require(SUPPORTS_REMOVE) @MapFeature.Require(SUPPORTS_REMOVE)
@SuppressWarnings("unlikely-arg-type")
#endignore #endignore
public void testRemove_supportedObjectEntryMissing() { public void testRemove_supportedObjectEntryMissing() {
assertFalse(getMap().ENTRY_SET().remove(new AbstractMap.SimpleEntry<>(e3()))); assertFalse(getMap().ENTRY_SET().remove(new AbstractMap.SimpleEntry<>(e3())));
@@ -0,0 +1,130 @@
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;
#endignore
#if !VALUE_BOOLEAN
#ignore
import static com.google.common.collect.testing.features.CollectionSize.ONE;
#endignore
#endif
import org.junit.Ignore;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import junit.framework.AssertionFailedError;
import speiger.src.testers.PACKAGE.tests.base.maps.ABSTRACT_MAP_TESTER;
@Ignore
@SuppressWarnings("javadoc")
public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentNonDefaultTester KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP_TESTER KEY_VALUE_GENERIC_TYPE
{
#ignore
@MapFeature.Require(SUPPORTS_PUT)
#endignore
public void testSupplyIfAbsent_supportedAbsent() {
#if VALUE_BOOLEAN
getMap().setDefaultReturnValue(true);
#endif
assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v3(), getMap().SUPPLY_IF_ABSENTNonDefault(k3(), this::v3));
expectAdded(e3());
}
#if !VALUE_BOOLEAN
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(ONE)
#endignore
public void testSupplyIfAbsent_supportedAbsentFirst() {
getMap().setDefaultReturnValue(v0());
assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v3(), getMap().SUPPLY_IF_ABSENTNonDefault(k0(), this::v3));
expectContents(entry(k0(), v3()));
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(ONE)
#endignore
public void testSupplyIfAbsent_supportedAbsentSameResult() {
getMap().setDefaultReturnValue(v0());
assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v0(), getMap().SUPPLY_IF_ABSENTNonDefault(k0(), this::v0));
expectUnchanged();
}
#endif
#ignore
@MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testSupplyIfAbsent_supportedPresent() {
assertEquals("SUPPLY_IF_ABSENT(present, function) should return existing value", v0(), getMap().SUPPLY_IF_ABSENTNonDefault(k0(), () -> {
throw new AssertionFailedError();
}));
expectUnchanged();
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
#endignore
public void testSupplyIfAbsent_functionReturnsNullNotInserted() {
assertEquals("SUPPLY_IF_ABSENT(absent, returnsNull) should return INVALID_VALUE", INVALID_VALUE, getMap().SUPPLY_IF_ABSENTNonDefault(k3(), () -> INVALID_VALUE));
expectUnchanged();
}
static class ExpectedException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
#ignore
@MapFeature.Require(SUPPORTS_PUT)
#endignore
public void testSupplyIfAbsent_functionThrows() {
try {
getMap().SUPPLY_IF_ABSENTNonDefault(k3(), () -> {
throw new ExpectedException();
});
fail("Expected ExpectedException");
} catch (ExpectedException expected) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
#endignore
public void testSupplyIfAbsent_unsupportedAbsent() {
try {
getMap().SUPPLY_IF_ABSENTNonDefault(k3(), this::v3);
fail("SUPPLY_IF_ABSENT(notPresent, function) should throw");
} catch (UnsupportedOperationException expected) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testSupplyIfAbsent_unsupportedPresentExistingValue() {
try {
assertEquals("SUPPLY_IF_ABSENT(present, returnsCurrentValue) should return present or throw", v0(), getMap().SUPPLY_IF_ABSENTNonDefault(k0(), this::v0));
} catch (UnsupportedOperationException tolerated) {
}
expectUnchanged();
}
#ignore
@MapFeature.Require(absent = SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO)
#endignore
public void testSupplyIfAbsent_unsupportedPresentDifferentValue() {
try {
assertEquals("SUPPLY_IF_ABSENT(present, returnsDifferentValue) should return present or throw", v0(), getMap().SUPPLY_IF_ABSENTNonDefault(k0(), this::v3));
} catch (UnsupportedOperationException tolerated) {
}
expectUnchanged();
}
}
@@ -26,8 +26,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentTester KEY_VALUE_GENE
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
#endignore #endignore
public void testSupplyIfAbsent_supportedAbsent() { public void testSupplyIfAbsent_supportedAbsent() {
assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v3(), assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v3(), getMap().SUPPLY_IF_ABSENT(k3(), this::v3));
getMap().SUPPLY_IF_ABSENT(k3(), this::v3));
expectAdded(e3()); expectAdded(e3());
} }
@@ -38,9 +37,13 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentTester KEY_VALUE_GENE
#endignore #endignore
public void testSupplyIfAbsent_supportedAbsentFirst() { public void testSupplyIfAbsent_supportedAbsentFirst() {
getMap().setDefaultReturnValue(v0()); getMap().setDefaultReturnValue(v0());
assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v3(), #if VALUE_OBJECT
getMap().SUPPLY_IF_ABSENT(k0(), this::v3)); assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v3(), getMap().SUPPLY_IF_ABSENT(k0(), this::v3));
expectContents(entry(k0(), v3())); expectContents(entry(k0(), v3()));
#else
assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v0(), getMap().SUPPLY_IF_ABSENT(k0(), this::v3));
expectUnchanged();
#endif
} }
#ignore #ignore
@@ -49,8 +52,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentTester KEY_VALUE_GENE
#endignore #endignore
public void testSupplyIfAbsent_supportedAbsentSameResult() { public void testSupplyIfAbsent_supportedAbsentSameResult() {
getMap().setDefaultReturnValue(v0()); getMap().setDefaultReturnValue(v0());
assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v0(), assertEquals("SUPPLY_IF_ABSENT(notPresent, function) should return new value", v0(), getMap().SUPPLY_IF_ABSENT(k0(), this::v0));
getMap().SUPPLY_IF_ABSENT(k0(), this::v0));
expectUnchanged(); expectUnchanged();
} }
@@ -60,8 +62,7 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentTester KEY_VALUE_GENE
@CollectionSize.Require(absent = ZERO) @CollectionSize.Require(absent = ZERO)
#endignore #endignore
public void testSupplyIfAbsent_supportedPresent() { public void testSupplyIfAbsent_supportedPresent() {
assertEquals("SUPPLY_IF_ABSENT(present, function) should return existing value", v0(), assertEquals("SUPPLY_IF_ABSENT(present, function) should return existing value", v0(), getMap().SUPPLY_IF_ABSENT(k0(), () -> {
getMap().SUPPLY_IF_ABSENT(k0(), () -> {
throw new AssertionFailedError(); throw new AssertionFailedError();
})); }));
expectUnchanged(); expectUnchanged();
@@ -72,7 +73,11 @@ public class FILE_KEY_TYPE2FILE_VALUE_TYPEMapSupplyIfAbsentTester KEY_VALUE_GENE
#endignore #endignore
public void testSupplyIfAbsent_functionReturnsNullNotInserted() { public void testSupplyIfAbsent_functionReturnsNullNotInserted() {
assertEquals("SUPPLY_IF_ABSENT(absent, returnsNull) should return INVALID_VALUE", INVALID_VALUE, getMap().SUPPLY_IF_ABSENT(k3(), () -> INVALID_VALUE)); assertEquals("SUPPLY_IF_ABSENT(absent, returnsNull) should return INVALID_VALUE", INVALID_VALUE, getMap().SUPPLY_IF_ABSENT(k3(), () -> INVALID_VALUE));
#if VALUE_OBJECT
expectUnchanged(); expectUnchanged();
#else
expectAdded(entry(k3(), INVALID_VALUE));
#endif
} }
static class ExpectedException extends RuntimeException { static class ExpectedException extends RuntimeException {

Some files were not shown because too many files have changed in this diff Show More