14 Commits
Author SHA1 Message Date
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 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
61 changed files with 8632 additions and 5983 deletions
+33 -32
View File
@@ -1,32 +1,33 @@
name: Latest Build name: Latest Build
on: on:
push: push:
branches: [ master ] branches: [ master ]
pull_request: pull_request:
branches: [ master ] branches: [ master ]
jobs: jobs:
build: build:
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:
java-version: ${{ matrix.jdk }} distribution: 'temurin'
java-version: ${{ matrix.jdk }}
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b - name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Make gradlew executable
run: chmod +x ./gradlew - name: Make gradlew executable
run: chmod +x ./gradlew
- name: Build with Gradle
run: ./gradlew build - name: Build with Gradle
run: ./gradlew build
+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@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 11
uses: actions/setup-java@v3
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
+16
View File
@@ -1,8 +1,24 @@
# 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 ### Version 0.8.0
- Added: getFirst/getLast/removeFirst/removeLast to Lists - Added: getFirst/getLast/removeFirst/removeLast to Lists
- Added: Dedicated implementations for toArray into TreeSets - 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)
+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'
} }
``` ```
+33 -25
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,7 +46,7 @@ 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:31.0.1-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
} }
} }
+4 -1
View File
@@ -1 +1,4 @@
org.gradle.jvmargs=-Xmx3G org.gradle.jvmargs=-Xmx3G
maxMemory = 1024m
testThreads = 2
+5 -5
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
@@ -1,155 +1,155 @@
package speiger.src.builder; package speiger.src.builder;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import speiger.src.builder.mappers.IMapper; import speiger.src.builder.mappers.IMapper;
import speiger.src.builder.processor.TemplateProcess; import speiger.src.builder.processor.TemplateProcess;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class ModulePackage public class ModulePackage
{ {
private static final BiConsumer<String, RequiredType> VOID = (K, V) -> {}; private static final BiConsumer<String, RequiredType> VOID = (K, V) -> {};
public static final ClassType[] TYPE = ClassType.values(); public static final ClassType[] TYPE = ClassType.values();
final ClassType keyType; final ClassType keyType;
final ClassType valueType; final ClassType valueType;
Set<String> blocked = new HashSet<>(); Set<String> blocked = new HashSet<>();
Map<String, String> nameRemapper = new HashMap<>(); Map<String, String> nameRemapper = new HashMap<>();
Map<String, String> splitters = new HashMap<>(); Map<String, String> splitters = new HashMap<>();
List<Predicate<String>> blockedFilters = new ArrayList<>(); List<Predicate<String>> blockedFilters = new ArrayList<>();
List<IMapper> mappers = new ArrayList<>(); List<IMapper> mappers = new ArrayList<>();
Set<String> flags = new LinkedHashSet<>(); Set<String> flags = new LinkedHashSet<>();
Set<String> globalFlags; Set<String> globalFlags;
Map<String, Integer> flaggedValues = new HashMap<>(); Map<String, Integer> flaggedValues = new HashMap<>();
BiConsumer<String, RequiredType> requirements = VOID; BiConsumer<String, RequiredType> requirements = VOID;
public ModulePackage(Set<String> globalFlags, ClassType keyType, ClassType valueType) { public ModulePackage(Set<String> globalFlags, ClassType keyType, ClassType valueType) {
this.globalFlags = globalFlags; this.globalFlags = globalFlags;
this.keyType = keyType; this.keyType = keyType;
this.valueType = valueType; this.valueType = valueType;
} }
public void finish() { public void finish() {
requirements = VOID; requirements = VOID;
mappers.sort(Comparator.comparing(IMapper::getSearchValue, Comparator.comparingInt(String::length).reversed())); mappers.sort(Comparator.comparing(IMapper::getSearchValue, Comparator.comparingInt(String::length).reversed()));
mappers.sort(Comparator.comparing(IMapper::getSearchValue, this::sort)); mappers.sort(Comparator.comparing(IMapper::getSearchValue, this::sort));
} }
public void setRequirements(BiConsumer<String, RequiredType> requirements) { public void setRequirements(BiConsumer<String, RequiredType> requirements) {
this.requirements = requirements; this.requirements = requirements;
} }
public boolean isSame() { public boolean isSame() {
return keyType == valueType; return keyType == valueType;
} }
public boolean isEnumValid() { public boolean isEnumValid() {
return keyType == ClassType.OBJECT; return keyType == ClassType.OBJECT;
} }
public ClassType getKeyType() { public ClassType getKeyType() {
return keyType; return keyType;
} }
public ClassType getValueType() { public ClassType getValueType() {
return valueType; return valueType;
} }
public void addFlag(String flag) { public void addFlag(String flag) {
flags.add(flag); flags.add(flag);
} }
public void addGlobalFlag(String flag) { public void addGlobalFlag(String flag) {
globalFlags.add(flag); globalFlags.add(flag);
} }
public void addValue(String key, int value) { public void addValue(String key, int value) {
flaggedValues.put(key, value); flaggedValues.put(key, value);
} }
public void addRequirement(String fileName, RequiredType type) { public void addRequirement(String fileName, RequiredType type) {
requirements.accept(fileName, type); requirements.accept(fileName, type);
} }
public void addMapper(IMapper mapper) { public void addMapper(IMapper mapper) {
mappers.add(mapper); mappers.add(mapper);
} }
public void addBlockedFilter(Predicate<String> filter) { public void addBlockedFilter(Predicate<String> filter) {
blockedFilters.add(filter); blockedFilters.add(filter);
} }
public void addBlockedFiles(String... names) { public void addBlockedFiles(String... names) {
blocked.addAll(Arrays.asList(names)); blocked.addAll(Arrays.asList(names));
} }
public void addSplitter(String fileName, String splitter) { public void addSplitter(String fileName, String splitter) {
splitters.put(fileName, splitter); splitters.put(fileName, splitter);
} }
public void addRemapper(String fileName, String actualName) { public void addRemapper(String fileName, String actualName) {
nameRemapper.put(fileName, actualName); nameRemapper.put(fileName, actualName);
} }
public void process(String fileName, Consumer<TemplateProcess> result) { public void process(String fileName, Consumer<TemplateProcess> result) {
if(isBlocked(fileName)) return; if(isBlocked(fileName)) return;
String splitter = String.format(splitters.getOrDefault(fileName, keyType.getFileType()), keyType.getFileType(), valueType.getFileType()); String splitter = String.format(splitters.getOrDefault(fileName, keyType.getFileType()), keyType.getFileType(), valueType.getFileType());
String newName = String.format(nameRemapper.getOrDefault(fileName, "%s"+fileName), splitter); String newName = String.format(nameRemapper.getOrDefault(fileName, "%s"+fileName), splitter);
TemplateProcess process = new TemplateProcess(newName+".java"); TemplateProcess process = new TemplateProcess(newName+".java");
process.setPathBuilder(new PathBuilder(keyType.getPathType())); process.setPathBuilder(new PathBuilder(keyType.getPathType()));
process.addFlags(flags); process.addFlags(flags);
process.addFlags(globalFlags); process.addFlags(globalFlags);
process.addMappers(mappers); process.addMappers(mappers);
process.addValues(flaggedValues); process.addValues(flaggedValues);
result.accept(process); result.accept(process);
} }
private boolean isBlocked(String fileName) { private boolean isBlocked(String fileName) {
if(blocked.contains(fileName)) return true; if(blocked.contains(fileName)) return true;
for(int i = 0,m=blockedFilters.size();i<m;i++) { for(int i = 0,m=blockedFilters.size();i<m;i++) {
if(blockedFilters.get(i).test(fileName)) return true; if(blockedFilters.get(i).test(fileName)) return true;
} }
return false; return false;
} }
public static List<ModulePackage> createPackages(Set<String> globalFlags) { public static List<ModulePackage> createPackages(Set<String> globalFlags) {
List<ModulePackage> list = new ArrayList<>(); List<ModulePackage> list = new ArrayList<>();
for(ClassType key : TYPE) { for(ClassType key : TYPE) {
for(ClassType value : TYPE) { for(ClassType value : TYPE) {
list.add(new ModulePackage(globalFlags, key, value)); list.add(new ModulePackage(globalFlags, key, value));
} }
} }
return list; return list;
} }
private int sort(String key, String value) { private int sort(String key, String value) {
if(value.contains(key)) return 1; if(value.contains(key)) return 1;
else if(key.contains(value)) return -1; else if(key.contains(value)) return -1;
return 0; return 0;
} }
class PathBuilder implements UnaryOperator<Path> { class PathBuilder implements UnaryOperator<Path> {
String before; String before;
public PathBuilder(String before) { public PathBuilder(String before) {
this.before = before; this.before = before;
} }
@Override @Override
public Path apply(Path t) { public Path apply(Path t) {
return t.subpath(0, 6).resolve(before).resolve(t.subpath(6, t.getNameCount())); return t.subpath(0, 6).resolve(before).resolve(t.subpath(6, t.getNameCount()));
} }
} }
} }
@@ -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,31 @@ 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);
} }
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 +150,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 +166,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 +174,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 +185,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));
@@ -59,6 +59,9 @@ public abstract class BaseModule
public Set<String> getModuleKeys(ClassType keyType, ClassType valueType) { return Collections.emptySet(); } public Set<String> getModuleKeys(ClassType keyType, ClassType valueType) { return Collections.emptySet(); }
public boolean isModuleValid(ClassType keyType, ClassType valueType) { return true; } public boolean isModuleValid(ClassType keyType, ClassType valueType) { return true; }
public ClassType keyType() { return keyType; }
public ClassType valueType() { return valueType; }
protected boolean isModuleEnabled() { protected boolean isModuleEnabled() {
return manager == null || manager.isModuleEnabled(this, keyType, valueType); return manager == null || manager.isModuleEnabled(this, keyType, valueType);
} }
@@ -54,8 +54,8 @@ public class FunctionModule extends BaseModule
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
@@ -108,6 +108,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
@@ -158,6 +161,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,6 +190,7 @@ 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");
@@ -16,6 +16,19 @@ 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 #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 +178,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
@@ -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);
} }
@@ -1,15 +1,20 @@
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;
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#if INT_LIST_MODULE && !TYPE_INT
import speiger.src.collections.ints.lists.IntList;
#endif
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@@ -66,8 +71,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 +225,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);
@@ -230,13 +239,25 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() { public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
return listIterator(0); return listIterator(0);
} }
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) { public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
if(index < 0 || index > size()) throw new IndexOutOfBoundsException(); if(index < 0 || index > size()) throw new IndexOutOfBoundsException();
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 +266,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;
@@ -490,7 +643,155 @@ 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 +869,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;
} }
} }
@@ -13,6 +13,7 @@ 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;
@@ -1080,6 +1081,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
@@ -13,6 +13,7 @@ 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;
@@ -1331,6 +1332,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
@@ -24,6 +24,9 @@ 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
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#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;
@@ -425,6 +428,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)
@@ -432,6 +455,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
@@ -201,6 +201,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 +305,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 +319,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 +333,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)) {
@@ -256,7 +346,8 @@ 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);
@@ -517,28 +517,58 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
int hash = getHashCode(key); int hash = getHashCode(key);
return getSegment(hash).compute(hash, key, mappingFunction); return getSegment(hash).compute(hash, key, mappingFunction);
} }
@Override @Override
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) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int hash = getHashCode(key); int hash = getHashCode(key);
return getSegment(hash).computeIfAbsent(hash, key, mappingFunction); return getSegment(hash).computeIfAbsent(hash, key, mappingFunction);
} }
@Override @Override
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) {
Objects.requireNonNull(valueProvider); Objects.requireNonNull(valueProvider);
int hash = getHashCode(key); int hash = getHashCode(key);
return getSegment(hash).supplyIfAbsent(hash, key, valueProvider); return getSegment(hash).supplyIfAbsent(hash, key, valueProvider);
} }
@Override @Override
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) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int hash = getHashCode(key); int hash = getHashCode(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);
@@ -652,7 +682,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];
} }
} }
@@ -664,14 +694,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];
} }
@@ -692,7 +722,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];
} }
} }
@@ -711,7 +741,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];
} }
} }
@@ -724,14 +754,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];
} }
@@ -746,14 +776,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];
} }
@@ -768,14 +798,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];
} }
@@ -797,7 +827,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];
} }
} }
@@ -821,11 +851,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];
} }
} }
@@ -839,14 +869,14 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public 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 entry;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
@@ -862,14 +892,14 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
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];
} }
@@ -1519,12 +1549,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
@@ -1709,6 +1739,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;
@@ -1744,7 +1801,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;
} }
@@ -2193,6 +2250,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;
@@ -2210,7 +2371,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);
@@ -2233,7 +2395,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);
@@ -2256,7 +2418,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);
@@ -2274,6 +2436,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 {
@@ -680,17 +680,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];
} }
@@ -703,7 +703,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];
} }
} }
@@ -714,7 +714,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];
} }
} }
@@ -723,10 +723,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];
} }
@@ -737,10 +737,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];
} }
@@ -751,10 +751,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];
} }
@@ -767,7 +767,7 @@ 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;
@@ -782,11 +782,11 @@ 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 state;
@@ -796,10 +796,10 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public 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 null;
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 entry;
index = (int)links[index]; index = (int)links[index];
} }
@@ -810,11 +810,11 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
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];
} }
@@ -1312,12 +1312,12 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@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
@@ -537,6 +537,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;
@@ -551,7 +640,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) {
@@ -570,7 +659,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,9 +676,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
} }
return newValue; return newValue;
} }
@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();
@@ -602,6 +691,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);
@@ -790,6 +880,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;
@@ -797,7 +914,11 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public MapEntry(int index) { public MapEntry(int index) {
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];
@@ -820,19 +941,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;
@@ -840,12 +961,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());
} }
} }
@@ -862,21 +983,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);
} }
} }
@@ -886,9 +1007,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));
} }
} }
@@ -896,9 +1017,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));
} }
} }
@@ -906,14 +1027,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;
} }
} }
@@ -924,14 +1045,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;
} }
} }
@@ -942,14 +1063,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;
} }
} }
@@ -960,10 +1081,10 @@ 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;
} }
@@ -974,17 +1095,17 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
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 state;
} }
@@ -993,14 +1114,14 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public 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 null;
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 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 entry;
} }
} }
@@ -1011,15 +1132,15 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
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++;
} }
} }
@@ -1433,7 +1554,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
@@ -684,17 +684,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];
} }
@@ -707,7 +707,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];
} }
} }
@@ -718,7 +718,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];
} }
} }
@@ -727,10 +727,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];
} }
@@ -741,10 +741,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];
} }
@@ -755,10 +755,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];
} }
@@ -771,7 +771,7 @@ 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;
@@ -786,11 +786,11 @@ 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 state;
@@ -800,10 +800,10 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public 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 null;
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 entry;
index = (int)links[index]; index = (int)links[index];
} }
@@ -815,10 +815,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];
} }
@@ -1312,12 +1312,12 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@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
@@ -497,6 +497,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;
@@ -511,7 +600,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) {
@@ -530,7 +619,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) {
@@ -549,7 +638,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();
@@ -562,6 +651,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);
@@ -749,6 +839,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;
@@ -756,7 +873,11 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public MapEntry(int index) { public MapEntry(int index) {
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];
@@ -779,19 +900,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;
@@ -799,12 +920,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());
} }
} }
@@ -821,21 +942,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);
} }
} }
@@ -845,9 +966,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));
} }
} }
@@ -855,9 +976,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));
} }
} }
@@ -865,14 +986,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;
} }
} }
@@ -883,14 +1004,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;
} }
} }
@@ -901,14 +1022,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;
} }
} }
@@ -919,10 +1040,10 @@ 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;
} }
@@ -933,17 +1054,17 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
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 state;
} }
@@ -952,14 +1073,14 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public 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 null;
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 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 entry;
} }
} }
@@ -970,15 +1091,15 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
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++;
} }
} }
@@ -1388,7 +1509,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
@@ -493,16 +493,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(); }
@@ -495,6 +495,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;
@@ -509,7 +598,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) {
@@ -528,7 +617,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) {
@@ -547,7 +636,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();
@@ -560,6 +649,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);
@@ -788,16 +878,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);
} }
} }
@@ -806,7 +896,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));
} }
} }
@@ -814,7 +904,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));
} }
} }
@@ -822,9 +912,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;
@@ -834,9 +924,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;
@@ -846,9 +936,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;
@@ -859,7 +949,7 @@ 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;
} }
@@ -872,10 +962,10 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
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 state;
} }
@@ -884,9 +974,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) { public 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 null;
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 entry;
} }
return null; return null;
@@ -897,9 +987,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;
@@ -1276,12 +1366,12 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@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
@@ -1397,6 +1487,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;
@@ -1404,7 +1521,11 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public MapEntry(int index) { public MapEntry(int index) {
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];
@@ -1427,19 +1548,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;
@@ -1447,12 +1568,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;
@@ -684,7 +802,11 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
public MapEntry(int index) { public MapEntry(int index) {
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());
} }
} }
} }
@@ -480,17 +480,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];
} }
@@ -749,12 +749,12 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@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
@@ -903,6 +903,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;
@@ -910,7 +937,11 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
public MapEntry(int index) { public MapEntry(int index) {
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 +964,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 +984,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());
} }
} }
} }
@@ -546,6 +546,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) {
@@ -564,7 +663,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);
@@ -585,7 +684,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);
@@ -606,7 +705,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);
@@ -622,6 +721,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);
@@ -1671,6 +1771,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())) {
@@ -1679,6 +1780,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
@@ -548,6 +548,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) {
@@ -566,7 +665,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);
@@ -587,7 +686,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);
@@ -608,7 +707,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);
@@ -624,6 +723,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);
@@ -1737,6 +1837,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())) {
@@ -1745,6 +1846,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
@@ -398,7 +398,6 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
* @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". * If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
@@ -418,6 +417,45 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_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". * If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
@@ -1,459 +1,468 @@
package speiger.src.collections.PACKAGE.queues; package speiger.src.collections.PACKAGE.queues;
import java.util.Arrays; import java.util.Arrays;
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.Comparator; import java.util.Comparator;
import java.util.function.Consumer; 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;
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 !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;
#endif #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.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
/** /**
* A Simple First In First Out Priority Queue that is a Good Replacement for a linked list (or ArrayDequeue) * A Simple First In First Out Priority Queue that is a Good Replacement for a linked list (or ArrayDequeue)
* Its specific implementation uses a backing array that grows and shrinks as it is needed. * Its specific implementation uses a backing array that grows and shrinks as it is needed.
* @Type(T) * @Type(T)
*/ */
public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_GENERIC_TYPE, ITrimmable public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_GENERIC_TYPE, ITrimmable
{ {
/** Max Possible ArraySize without the JVM Crashing */ /** Max Possible ArraySize without the JVM Crashing */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/** The Minimum Capacity that is allowed */ /** The Minimum Capacity that is allowed */
public static final int MIN_CAPACITY = 4; public static final int MIN_CAPACITY = 4;
/** The Backing array */ /** The Backing array */
protected transient KEY_TYPE[] array; protected transient KEY_TYPE[] array;
/** The First Index pointer */ /** The First Index pointer */
protected int first; protected int first;
/** The Last Index pointer */ /** The Last Index pointer */
protected int last; protected int last;
/** The Minimum Capacity of the Queue **/ /** The Minimum Capacity of the Queue **/
protected int minCapacity; protected int minCapacity;
/** /**
* Constructor using a initial array * Constructor using a initial array
* @param values the Array that should be used * @param values the Array that should be used
*/ */
public ARRAY_FIFO_QUEUE(KEY_TYPE[] values) { public ARRAY_FIFO_QUEUE(KEY_TYPE[] values) {
this(values, 0, values.length); this(values, 0, values.length);
} }
/** /**
* Constructor using a initial array * Constructor using a initial array
* @param values the Array that should be used * @param values the Array that should be used
* @param size the amount of elements that are in the initial array * @param size the amount of elements that are in the initial array
* @throws IllegalStateException if values is smaller then size * @throws IllegalStateException if values is smaller then size
*/ */
public ARRAY_FIFO_QUEUE(KEY_TYPE[] values, int size) { public ARRAY_FIFO_QUEUE(KEY_TYPE[] values, int size) {
this(values, 0, size); this(values, 0, size);
} }
/** /**
* Constructor using a initial array * Constructor using a initial array
* @param values the Array that should be used * @param values the Array that should be used
* @param offset where to begin in the initial array * @param offset where to begin in the initial array
* @param size the amount of elements that are in the initial array * @param size the amount of elements that are in the initial array
* @throws IllegalStateException if values is smaller then size * @throws IllegalStateException if values is smaller then size
*/ */
public ARRAY_FIFO_QUEUE(KEY_TYPE[] values, int offset, int size) { public ARRAY_FIFO_QUEUE(KEY_TYPE[] values, int offset, int size) {
if (values.length < size) throw new IllegalArgumentException("Initial array (" + values.length + ") is smaller then the expected size (" + size + ")"); if (values.length < size) throw new IllegalArgumentException("Initial array (" + values.length + ") is smaller then the expected size (" + size + ")");
if(values.length <= 0) values = NEW_KEY_ARRAY(MIN_CAPACITY); if(values.length <= 0) values = NEW_KEY_ARRAY(MIN_CAPACITY);
else if(values.length < MIN_CAPACITY) values = Arrays.copyOf(values, MIN_CAPACITY); else if(values.length < MIN_CAPACITY) values = Arrays.copyOf(values, MIN_CAPACITY);
minCapacity = MIN_CAPACITY; minCapacity = MIN_CAPACITY;
array = values; array = values;
first = offset; first = offset;
last = (offset + size) % array.length; last = (offset + size) % array.length;
if(array.length == size) expand(); if(array.length == size) expand();
} }
/** /**
* Constructor with a Min Capacity * Constructor with a Min Capacity
* @param capacity the initial capacity of the backing array * @param capacity the initial capacity of the backing array
* @throws IllegalStateException if the initial size is smaller 0 * @throws IllegalStateException if the initial size is smaller 0
*/ */
public ARRAY_FIFO_QUEUE(int capacity) { public ARRAY_FIFO_QUEUE(int capacity) {
if (capacity < 0) throw new IllegalArgumentException("Initial capacity (" + capacity + ") is negative"); if (capacity < 0) throw new IllegalArgumentException("Initial capacity (" + capacity + ") is negative");
array = NEW_KEY_ARRAY(Math.max(MIN_CAPACITY, capacity+1)); array = NEW_KEY_ARRAY(Math.max(MIN_CAPACITY, capacity+1));
minCapacity = array.length; minCapacity = array.length;
} }
/** /**
* Default Construtor * Default Construtor
*/ */
public ARRAY_FIFO_QUEUE() { public ARRAY_FIFO_QUEUE() {
this(MIN_CAPACITY); this(MIN_CAPACITY);
} }
@Override @Override
public ITERATOR KEY_GENERIC_TYPE iterator() { public ITERATOR KEY_GENERIC_TYPE iterator() {
return new Iter(); return new Iter();
} }
@Override @Override
public int size() { public int size() {
final int apparentLength = last - first; final int apparentLength = last - first;
return apparentLength >= 0 ? apparentLength : array.length + apparentLength; return apparentLength >= 0 ? apparentLength : array.length + apparentLength;
} }
@Override @Override
public void clear() { public void clear() {
if(first != last) { if(first != last) {
#if TYPE_OBJECT #if TYPE_OBJECT
Arrays.fill(array, null); Arrays.fill(array, null);
#endif #endif
first = last = 0; first = last = 0;
} }
else if(first != 0) { else if(first != 0) {
first = last = 0; first = last = 0;
} }
} }
@Override @Override
public void enqueue(KEY_TYPE e) { public void enqueue(KEY_TYPE e) {
array[last++] = e; array[last++] = e;
if(last == array.length) last = 0; if(last == array.length) last = 0;
if(last == first) expand(); if(last == first) expand();
} }
@Override @Override
public void enqueueFirst(KEY_TYPE e) { public void enqueueFirst(KEY_TYPE e) {
if(first == 0) first = array.length; if(first == 0) first = array.length;
array[--first] = e; array[--first] = e;
if(first == last) expand(); if(first == last) expand();
} }
@Override @Override
public KEY_TYPE dequeue() { public KEY_TYPE dequeue() {
if(first == last) throw new NoSuchElementException(); if(first == last) throw new NoSuchElementException();
KEY_TYPE data = array[first]; KEY_TYPE data = array[first];
#if TYPE_OBJECT #if TYPE_OBJECT
array[first] = null; array[first] = null;
#endif #endif
if(++first == array.length) first = 0; if(++first == array.length) first = 0;
reduce(); reduce();
return data; return data;
} }
@Override @Override
public KEY_TYPE dequeueLast() { public KEY_TYPE dequeueLast() {
if(first == last) throw new NoSuchElementException(); if(first == last) throw new NoSuchElementException();
if(last == 0) last = array.length; if(last == 0) last = array.length;
KEY_TYPE data = array[--last]; KEY_TYPE data = array[--last];
#if TYPE_OBJECT #if TYPE_OBJECT
array[last] = null; array[last] = null;
#endif #endif
reduce(); reduce();
return data; return data;
} }
@Override @Override
public KEY_TYPE peek(int index) { public KEY_TYPE peek(int index) {
if(first == last || index < 0 || index >= size()) throw new NoSuchElementException(); if(first == last || index < 0 || index >= size()) throw new NoSuchElementException();
index += first; index += first;
return index >= array.length ? array[index-array.length] : array[index]; return index >= array.length ? array[index-array.length] : array[index];
} }
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean contains(KEY_TYPE e) {
if(first == last) return false; if(first == last) return false;
for(int i = 0,m=size();i<m;i++) { for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length; if(e == array[(first + i) % array.length]) return true;
if(e == array[index]) }
return removeIndex(index); return false;
} }
return false;
} @Override
public boolean removeFirst(KEY_TYPE e) {
@Override if(first == last) return false;
public boolean removeLast(KEY_TYPE e) { for(int i = 0,m=size();i<m;i++) {
if(first == last) return false; int index = (first + i) % array.length;
for(int i = size()-1;i>=0;i--) { if(e == array[index])
int index = (first + i) % array.length; return removeIndex(index);
if(e == array[index]) }
return removeIndex(index); return false;
} }
return false;
} @Override
public boolean removeLast(KEY_TYPE e) {
protected boolean removeIndex(int index) { if(first == last) return false;
if(first >= last ? index < first && index > last : index < first || index > last) return false; for(int i = size()-1;i>=0;i--) {
if(index == first) { int index = (first + i) % array.length;
#if TYPE_OBJECT if(e == array[index])
array[first] = null; return removeIndex(index);
#endif }
first++; return false;
} }
else if(index == last) {
last--; protected boolean removeIndex(int index) {
#if TYPE_OBJECT if(first >= last ? index < first && index > last : index < first || index > last) return false;
array[last] = null; if(index == first) {
#endif #if TYPE_OBJECT
} array[first] = null;
else if(index > last) { #endif
System.arraycopy(array, first, array, first+1, (index - first)); first++;
#if TYPE_OBJECT }
array[first] = null; else if(index == last) {
#endif last--;
first = ++first % array.length; #if TYPE_OBJECT
} array[last] = null;
else if(index < first) { #endif
System.arraycopy(array, index+1, array, index, (last - index) - 1); }
#if TYPE_OBJECT else if(index > last) {
array[last] = null; System.arraycopy(array, first, array, first+1, (index - first));
#endif #if TYPE_OBJECT
if(--last < 0) last += array.length; array[first] = null;
} #endif
else { first = ++first % array.length;
if(index - first < last - index) { }
System.arraycopy(array, first, array, first+1, (index - first)); else if(index < first) {
#if TYPE_OBJECT System.arraycopy(array, index+1, array, index, (last - index) - 1);
array[first] = null; #if TYPE_OBJECT
#endif array[last] = null;
first = ++first % array.length; #endif
} if(--last < 0) last += array.length;
else { }
System.arraycopy(array, index+1, array, index, (last - index) - 1); else {
#if TYPE_OBJECT if(index - first < last - index) {
array[last] = null; System.arraycopy(array, first, array, first+1, (index - first));
#endif #if TYPE_OBJECT
if(--last < 0) last += array.length; array[first] = null;
} #endif
} first = ++first % array.length;
reduce(); }
return true; else {
} System.arraycopy(array, index+1, array, index, (last - index) - 1);
#if TYPE_OBJECT
@Override array[last] = null;
public void onChanged() {} #endif
if(--last < 0) last += array.length;
@Override }
public ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE copy() { }
ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_FIFO_QUEUEBRACES(); reduce();
queue.first = first; return true;
queue.last = last; }
queue.minCapacity = minCapacity;
queue.array = Arrays.copyOf(array, array.length); @Override
return queue; public void onChanged() {}
}
@Override
@Override public ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE copy() {
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { return null; } ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_FIFO_QUEUEBRACES();
queue.first = first;
@Override queue.last = last;
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { queue.minCapacity = minCapacity;
Objects.requireNonNull(action); queue.array = Arrays.copyOf(array, array.length);
if(first == last) return; return queue;
for(int i = 0,m=size();i<m;i++) }
action.accept(array[(first + i) % array.length]);
clearAndTrim(0); @Override
} public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { return null; }
@Override @Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
if(first == last) return; if(first == last) return;
for(int i = 0,m=size();i<m;i++) for(int i = 0,m=size();i<m;i++)
action.accept(i, array[(first + i) % array.length]); action.accept(array[(first + i) % array.length]);
clearAndTrim(0); clearAndTrim(0);
} }
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
if(first == last) return; if(first == last) return;
for(int i = 0,m=size();i<m;i++) for(int i = 0,m=size();i<m;i++)
action.accept(input, array[(first + i) % array.length]); action.accept(i, array[(first + i) % array.length]);
clearAndTrim(0); clearAndTrim(0);
} }
@Override @Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(filter); Objects.requireNonNull(action);
for(int i = 0,m=size();i<m;i++) { if(first == last) return;
if(filter.test(array[(first + i) % array.length])) return true; for(int i = 0,m=size();i<m;i++)
} action.accept(input, array[(first + i) % array.length]);
return false; clearAndTrim(0);
} }
@Override @Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(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++) {
if(filter.test(array[(first + i) % array.length])) return false; if(filter.test(array[(first + i) % array.length])) return true;
} }
return true; return false;
} }
@Override @Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(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++) {
if(!filter.test(array[(first + i) % array.length])) return false; if(filter.test(array[(first + i) % array.length])) return false;
} }
return true; return true;
} }
@Override @Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(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; if(!filter.test(array[(first + i) % array.length])) return false;
if(filter.test(array[index])) { }
KEY_TYPE data = array[index]; return true;
removeIndex(index); }
return data;
} @Override
} public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
return EMPTY_VALUE; Objects.requireNonNull(filter);
} for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length;
#if !TYPE_OBJECT if(filter.test(array[index])) {
@Override KEY_TYPE data = array[index];
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { removeIndex(index);
Objects.requireNonNull(operator); return data;
KEY_TYPE state = identity; }
for(int i = 0,m=size();i<m;i++) { }
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]); return EMPTY_VALUE;
} }
return state;
} #if !TYPE_OBJECT
@Override
#else public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
@Override Objects.requireNonNull(operator);
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) { KEY_TYPE state = identity;
Objects.requireNonNull(operator); for(int i = 0,m=size();i<m;i++) {
KEY_SPECIAL_TYPE state = identity; state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
for(int i = 0,m=size();i<m;i++) { }
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]); return state;
} }
return state;
} #else
@Override
#endif public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
@Override Objects.requireNonNull(operator);
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { KEY_SPECIAL_TYPE state = identity;
Objects.requireNonNull(operator); for(int i = 0,m=size();i<m;i++) {
KEY_TYPE state = EMPTY_VALUE; state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
boolean empty = true; }
for(int i = 0,m=size();i<m;i++) { return state;
if(empty) { }
empty = false;
state = array[(first + i) % array.length]; #endif
continue; @Override
} public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]); Objects.requireNonNull(operator);
} KEY_TYPE state = EMPTY_VALUE;
return state; boolean empty = true;
} for(int i = 0,m=size();i<m;i++) {
if(empty) {
@Override empty = false;
public int count(PREDICATE KEY_GENERIC_TYPE filter) { state = array[(first + i) % array.length];
Objects.requireNonNull(filter); continue;
int result = 0; }
for(int i = 0,m=size();i<m;i++) { state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
if(filter.test(array[(first + i) % array.length])) result++; }
} return state;
return result; }
}
@Override
@Override public int count(PREDICATE KEY_GENERIC_TYPE filter) {
public boolean trim(int size) { Objects.requireNonNull(filter);
int newSize = Math.max(Math.max(size, size()), minCapacity); int result = 0;
if(newSize >= array.length) return false; for(int i = 0,m=size();i<m;i++) {
KEY_TYPE[] newArray = NEW_KEY_ARRAY(newSize); if(filter.test(array[(first + i) % array.length])) result++;
if(first <= last) System.arraycopy(array, first, newArray, 0, last - first); }
else { return result;
System.arraycopy(array, first, newArray, 0, array.length - first); }
System.arraycopy(array, 0, newArray, array.length - first, last);
} @Override
first = 0; public boolean trim(int size) {
last = size(); int newSize = Math.max(Math.max(size, size()), minCapacity);
array = newArray; if(newSize >= array.length) return false;
return true; KEY_TYPE[] newArray = NEW_KEY_ARRAY(newSize);
} if(first <= last) System.arraycopy(array, first, newArray, 0, last - first);
else {
/** System.arraycopy(array, first, newArray, 0, array.length - first);
* Trims the collection down to the requested size and clears all elements while doing so System.arraycopy(array, 0, newArray, array.length - first, last);
* @param size the amount of elements that should be allowed }
* @note this will enforce minimum size of the collection itself first = 0;
*/ last = size();
@Override array = newArray;
public void clearAndTrim(int size) { return true;
int newSize = Math.max(minCapacity, size); }
if(array.length <= newSize) {
clear(); /**
return; * Trims the collection down to the requested size and clears all elements while doing so
} * @param size the amount of elements that should be allowed
first = last = 0; * @note this will enforce minimum size of the collection itself
array = NEW_KEY_ARRAY(newSize); */
} @Override
public void clearAndTrim(int size) {
@Override int newSize = Math.max(minCapacity, size);
public GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) { if(array.length <= newSize) {
if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); clear();
if (first <= last) System.arraycopy(array, first, input, 0, last - first); return;
else { }
System.arraycopy(array, first, input, 0, array.length - first); first = last = 0;
System.arraycopy(array, 0, input, array.length - first, last); array = NEW_KEY_ARRAY(newSize);
} }
return input;
} @Override
public GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
protected void reduce() { if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size());
final int size = size(); if (first <= last) System.arraycopy(array, first, input, 0, last - first);
if (array.length > minCapacity && size <= array.length / 4) resize(size, Math.max(array.length / 2, minCapacity)); else {
} System.arraycopy(array, first, input, 0, array.length - first);
System.arraycopy(array, 0, input, array.length - first, last);
protected void expand() { }
resize(array.length, (int)Math.min(MAX_ARRAY_SIZE, 2L * array.length)); return input;
} }
protected final void resize(int oldSize, int newSize) { protected void reduce() {
KEY_TYPE[] newArray = NEW_KEY_ARRAY(newSize); final int size = size();
if(first >= last) { if (array.length > minCapacity && size <= array.length / 4) resize(size, Math.max(array.length / 2, minCapacity));
if(oldSize != 0) }
{
System.arraycopy(array, first, newArray, 0, array.length - first); protected void expand() {
System.arraycopy(array, 0, newArray, array.length - first, last); resize(array.length, (int)Math.min(MAX_ARRAY_SIZE, 2L * array.length));
} }
}
else System.arraycopy(array, first, newArray, 0, last-first); protected final void resize(int oldSize, int newSize) {
first = 0; KEY_TYPE[] newArray = NEW_KEY_ARRAY(newSize);
last = oldSize; if(first >= last) {
array = newArray; if(oldSize != 0)
} {
System.arraycopy(array, first, newArray, 0, array.length - first);
private class Iter implements ITERATOR KEY_GENERIC_TYPE System.arraycopy(array, 0, newArray, array.length - first, last);
{ }
int index = first; }
@Override else System.arraycopy(array, first, newArray, 0, last-first);
public boolean hasNext() first = 0;
{ last = oldSize;
return index != last; array = newArray;
} }
@Override private class Iter implements ITERATOR KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { {
if(!hasNext()) throw new NoSuchElementException(); int index = first;
KEY_TYPE value = array[index]; @Override
removeIndex(index); public boolean hasNext()
index = ++index % array.length; {
return value; return index != last;
} }
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
KEY_TYPE value = array[index];
removeIndex(index);
index = ++index % array.length;
return value;
}
}
} }
@@ -1,440 +1,447 @@
package speiger.src.collections.PACKAGE.queues; package speiger.src.collections.PACKAGE.queues;
import java.util.Arrays; import java.util.Arrays;
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; 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_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 !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;
#endif #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.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
* A Array Priority Queue, this is a very unoptimized implementation of the PriorityQueue for very specific usecases. * A Array Priority Queue, this is a very unoptimized implementation of the PriorityQueue for very specific usecases.
* It allows for duplicated entries and works like {@link java.util.List#indexOf(Object)} search. * It allows for duplicated entries and works like {@link java.util.List#indexOf(Object)} search.
* It is highly suggested to use HeapPriorityQueue otherwise, unless you know why you need this specific implementation * It is highly suggested to use HeapPriorityQueue otherwise, unless you know why you need this specific implementation
* @Type(T) * @Type(T)
*/ */
public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE
{ {
/** The Backing Array */ /** The Backing Array */
protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY; protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY;
/** The Amount of elements stored within the array */ /** The Amount of elements stored within the array */
protected int size; protected int size;
/** The Last known first index pointer */ /** The Last known first index pointer */
protected int firstIndex = -1; protected int firstIndex = -1;
/** The Sorter of the Array */ /** The Sorter of the Array */
protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator; protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator;
/** /**
* Default Constructor * Default Constructor
*/ */
public ARRAY_PRIORITY_QUEUE() { public ARRAY_PRIORITY_QUEUE() {
this(0, null); this(0, null);
} }
/** /**
* Constructor using custom sorter * Constructor using custom sorter
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
*/ */
public ARRAY_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public ARRAY_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this(0, comp); this(0, comp);
} }
/** /**
* Constructor with a Min Capacity * Constructor with a Min Capacity
* @param size the initial capacity of the backing array * @param size the initial capacity of the backing array
* @throws IllegalStateException if the initial size is smaller 0 * @throws IllegalStateException if the initial size is smaller 0
*/ */
public ARRAY_PRIORITY_QUEUE(int size) { public ARRAY_PRIORITY_QUEUE(int size) {
this(size, null); this(size, null);
} }
/** /**
* Constructor with a Min Capacity and custom Sorter * Constructor with a Min Capacity and custom Sorter
* @param size the initial capacity of the backing array * @param size the initial capacity of the backing array
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
* @throws IllegalStateException if the initial size is smaller 0 * @throws IllegalStateException if the initial size is smaller 0
*/ */
public ARRAY_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public ARRAY_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
if(size < 0) throw new IllegalAccessError("Size has to be 0 or positive"); if(size < 0) throw new IllegalAccessError("Size has to be 0 or positive");
if(size > 0) array = NEW_KEY_ARRAY(size); if(size > 0) array = NEW_KEY_ARRAY(size);
comparator = comp; comparator = comp;
} }
/** /**
* Constructor using a initial array * Constructor using a initial array
* @param array the Array that should be used * @param array the Array that should be used
*/ */
public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array) { public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array) {
this(array, array.length); this(array, array.length);
} }
/** /**
* Constructor using a initial array * Constructor using a initial array
* @param array the Array that should be used * @param array the Array that should be used
* @param size the amount of elements found within the array * @param size the amount of elements found within the array
* @throws NegativeArraySizeException if size is smaller then 0 * @throws NegativeArraySizeException if size is smaller then 0
*/ */
public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size) { public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size) {
this.array = Arrays.copyOf(array, size); this.array = Arrays.copyOf(array, size);
this.size = size; this.size = size;
} }
/** /**
* Constructor using a initial array and a custom sorter * Constructor using a initial array and a custom sorter
* @param array the Array that should be used * @param array the Array that should be used
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
*/ */
public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this(array, array.length, comp); this(array, array.length, comp);
} }
/** /**
* Constructor using a initial array and a custom sorter * Constructor using a initial array and a custom sorter
* @param array the Array that should be used * @param array the Array that should be used
* @param size the amount of elements found within the array * @param size the amount of elements found within the array
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
* @throws NegativeArraySizeException if size is smaller then 0 * @throws NegativeArraySizeException if size is smaller then 0
*/ */
public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this.array = Arrays.copyOf(array, size); this.array = Arrays.copyOf(array, size);
this.size = size; this.size = size;
this.comparator = comp; this.comparator = comp;
} }
/** /**
* Constructor using a Collection * Constructor using a Collection
* @param c the Collection that should be used * @param c the Collection that should be used
*/ */
public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) { public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) {
array = CAST_KEY_ARRAY c.TO_ARRAY(); array = CAST_KEY_ARRAY c.TO_ARRAY();
size = c.size(); size = c.size();
} }
/** /**
* Constructor using a Collection and a custom sorter * Constructor using a Collection and a custom sorter
* @param c the Collection that should be used * @param c the Collection that should be used
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
*/ */
public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
array = CAST_KEY_ARRAY c.TO_ARRAY(); array = CAST_KEY_ARRAY c.TO_ARRAY();
size = c.size(); size = c.size();
comparator = comp; comparator = comp;
} }
/** /**
* Wrapping method to help serialization * Wrapping method to help serialization
* @param array the array that should be used * @param array the array that should be used
* @Type(T) * @Type(T)
* @return a ArrayPriorityQueue containing the original input array * @return a ArrayPriorityQueue containing the original input array
*/ */
public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) {
return wrap(array, array.length); return wrap(array, array.length);
} }
/** /**
* Wrapping method to help serialization * Wrapping method to help serialization
* @param array the array that should be used * @param array the array that should be used
* @param size the amount of elements within the array * @param size the amount of elements within the array
* @Type(T) * @Type(T)
* @return a ArrayPriorityQueue containing the original input array * @return a ArrayPriorityQueue containing the original input array
*/ */
public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) { public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) {
ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES(); ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES();
queue.array = array; queue.array = array;
queue.size = size; queue.size = size;
return queue; return queue;
} }
/** /**
* Wrapping method to help serialization, using a custom sorter * Wrapping method to help serialization, using a custom sorter
* @param array the array that should be used * @param array the array that should be used
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
* @Type(T) * @Type(T)
* @return a ArrayPriorityQueue containing the original input array * @return a ArrayPriorityQueue containing the original input array
*/ */
public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
return wrap(array, array.length, comp); return wrap(array, array.length, comp);
} }
/** /**
* Wrapping method to help serialization, using a custom sorter * Wrapping method to help serialization, using a custom sorter
* @param array the array that should be used * @param array the array that should be used
* @param size the amount of elements within the array * @param size the amount of elements within the array
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
* @Type(T) * @Type(T)
* @return a ArrayPriorityQueue containing the original input array * @return a ArrayPriorityQueue containing the original input array
*/ */
public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES(comp); ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES(comp);
queue.array = array; queue.array = array;
queue.size = size; queue.size = size;
return queue; return queue;
} }
@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));
if(firstIndex != -1){ if(firstIndex != -1){
int compare = comparator == null ? COMPAREABLE_TO_KEY(e, array[firstIndex]) : comparator.compare(e, array[firstIndex]); int compare = comparator == null ? COMPAREABLE_TO_KEY(e, array[firstIndex]) : comparator.compare(e, array[firstIndex]);
if(compare < 0) firstIndex = size; if(compare < 0) firstIndex = size;
else if(compare > 0) firstIndex = -1; else if(compare > 0) firstIndex = -1;
} }
array[size++] = e; array[size++] = e;
} }
@Override @Override
public KEY_TYPE dequeue() { public KEY_TYPE dequeue() {
if(size <= 0) throw new NoSuchElementException(); if(size <= 0) throw new NoSuchElementException();
int index = findFirstIndex(); int index = findFirstIndex();
KEY_TYPE value = array[index]; KEY_TYPE value = array[index];
if(index != --size) System.arraycopy(array, index+1, array, index, size - index); if(index != --size) System.arraycopy(array, index+1, array, index, size - index);
#if TYPE_OBJECT #if TYPE_OBJECT
array[size] = null; array[size] = null;
#endif #endif
firstIndex = -1; firstIndex = -1;
return value; return value;
} }
@Override @Override
public KEY_TYPE first() { public KEY_TYPE first() {
if(isEmpty()) throw new NoSuchElementException(); if(isEmpty()) throw new NoSuchElementException();
if(firstIndex == -1) findFirstIndex(); if(firstIndex == -1) findFirstIndex();
return array[firstIndex]; return array[firstIndex];
} }
@Override @Override
public KEY_TYPE peek(int index) { public KEY_TYPE peek(int index) {
if(index < 0 || index >= size) throw new NoSuchElementException(); if(index < 0 || index >= size) throw new NoSuchElementException();
return array[index]; return array[index];
} }
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean contains(KEY_TYPE e) {
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i); if(KEY_EQUALS(e, array[i])) return true;
return false; return false;
} }
@Override @Override
public boolean removeLast(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
for(int i = size-1;i>=0;i--) for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i); if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false; return false;
} }
protected boolean removeIndex(int index) { @Override
if(index != --size) System.arraycopy(array, index+1, array, index, size - index); public boolean removeLast(KEY_TYPE e) {
#if TYPE_OBJECT for(int i = size-1;i>=0;i--)
array[size] = null; if(KEY_EQUALS(e, array[i])) return removeIndex(i);
#endif return false;
if(index == firstIndex) firstIndex = -1; }
else if(firstIndex != -1 && index >= firstIndex) firstIndex--;
return true; protected boolean removeIndex(int index) {
} if(index != --size) System.arraycopy(array, index+1, array, index, size - index);
#if TYPE_OBJECT
@Override array[size] = null;
public void onChanged() { #endif
firstIndex = -1; if(index == firstIndex) firstIndex = -1;
} else if(firstIndex != -1 && index >= firstIndex) firstIndex--;
return true;
@Override }
public int size() {
return size; @Override
} public void onChanged() {
firstIndex = -1;
@Override }
public void clear() {
#if TYPE_OBJECT @Override
Arrays.fill(array, null); public int size() {
#endif return size;
size = 0; }
}
@Override
@Override public void clear() {
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { #if TYPE_OBJECT
Objects.requireNonNull(action); Arrays.fill(array, null);
for(int i = 0,m=size;i<m;i++) action.accept(dequeue()); #endif
} size = 0;
}
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { @Override
Objects.requireNonNull(action); public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue()); Objects.requireNonNull(action);
} for(int i = 0,m=size;i<m;i++) action.accept(dequeue());
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { @Override
Objects.requireNonNull(action); public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
for(int i = 0,m=size;i<m;i++) action.accept(input, dequeue()); Objects.requireNonNull(action);
} for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue());
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { @Override
Objects.requireNonNull(filter); public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
for(int i = 0;i<size;i++) { Objects.requireNonNull(action);
if(filter.test(array[i])) return true; for(int i = 0,m=size;i<m;i++) action.accept(input, dequeue());
} }
return false;
} @Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
@Override Objects.requireNonNull(filter);
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { for(int i = 0;i<size;i++) {
Objects.requireNonNull(filter); if(filter.test(array[i])) return true;
for(int i = 0;i<size;i++) { }
if(filter.test(array[i])) return false; return false;
} }
return true;
} @Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
@Override Objects.requireNonNull(filter);
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { for(int i = 0;i<size;i++) {
Objects.requireNonNull(filter); if(filter.test(array[i])) return false;
for(int i = 0;i<size;i++) { }
if(!filter.test(array[i])) return false; return true;
} }
return true;
} @Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
#if !TYPE_OBJECT Objects.requireNonNull(filter);
@Override for(int i = 0;i<size;i++) {
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { if(!filter.test(array[i])) return false;
Objects.requireNonNull(operator); }
KEY_TYPE state = identity; return true;
for(int i = 0;i<size;i++) { }
state = operator.APPLY_VALUE(state, array[i]);
} #if !TYPE_OBJECT
return state; @Override
} public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
#else KEY_TYPE state = identity;
@Override for(int i = 0;i<size;i++) {
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) { state = operator.APPLY_VALUE(state, array[i]);
Objects.requireNonNull(operator); }
KEY_SPECIAL_TYPE state = identity; return state;
for(int i = 0;i<size;i++) { }
state = operator.APPLY_VALUE(state, array[i]);
} #else
return state; @Override
} public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
Objects.requireNonNull(operator);
#endif KEY_SPECIAL_TYPE state = identity;
@Override for(int i = 0;i<size;i++) {
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { state = operator.APPLY_VALUE(state, array[i]);
Objects.requireNonNull(operator); }
KEY_TYPE state = EMPTY_VALUE; return state;
boolean empty = true; }
for(int i = 0;i<size;i++) {
if(empty) { #endif
empty = false; @Override
state = array[i]; public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
continue; Objects.requireNonNull(operator);
} KEY_TYPE state = EMPTY_VALUE;
state = operator.APPLY_VALUE(state, array[i]); boolean empty = true;
} for(int i = 0;i<size;i++) {
return state; if(empty) {
} empty = false;
state = array[i];
@Override continue;
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { }
Objects.requireNonNull(filter); state = operator.APPLY_VALUE(state, array[i]);
for(int i = 0;i<size;i++) { }
if(filter.test(array[i])) { return state;
KEY_TYPE data = array[i]; }
removeIndex(i);
return data; @Override
} public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
} Objects.requireNonNull(filter);
return EMPTY_VALUE; for(int i = 0;i<size;i++) {
} if(filter.test(array[i])) {
KEY_TYPE data = array[i];
@Override removeIndex(i);
public int count(PREDICATE KEY_GENERIC_TYPE filter) { return data;
Objects.requireNonNull(filter); }
int result = 0; }
for(int i = 0;i<size;i++) { return EMPTY_VALUE;
if(filter.test(array[i])) result++; }
}
return result; @Override
} public int count(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
@Override int result = 0;
public ITERATOR KEY_GENERIC_TYPE iterator() { for(int i = 0;i<size;i++) {
return new Iter(); if(filter.test(array[i])) result++;
} }
return result;
@Override }
public ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE copy() {
ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES(); @Override
queue.firstIndex = firstIndex; public ITERATOR KEY_GENERIC_TYPE iterator() {
queue.size = size; return new Iter();
queue.comparator = comparator; }
queue.array = Arrays.copyOf(array, array.length);
return queue; @Override
} public ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE copy() {
ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES();
@Override queue.firstIndex = firstIndex;
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { queue.size = size;
return comparator; queue.comparator = comparator;
} queue.array = Arrays.copyOf(array, array.length);
return queue;
@Override }
public GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); @Override
System.arraycopy(array, 0, input, 0, size()); public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() {
return input; return comparator;
} }
protected int findFirstIndex() { @Override
if(firstIndex == -1) { public GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
int index = size-1; if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size());
KEY_TYPE value = array[index]; System.arraycopy(array, 0, input, 0, size());
if(comparator == null) { return input;
for(int i = index;i>=0;i--) { }
if(COMPAREABLE_TO_KEY(array[i], value) < 0)
value = array[index = i]; protected int findFirstIndex() {
} if(firstIndex == -1) {
} int index = size-1;
else { KEY_TYPE value = array[index];
for(int i = index;i>=0;i--) { if(comparator == null) {
if(comparator.compare(array[i], value) < 0) for(int i = index;i>=0;i--) {
value = array[index = i]; if(COMPAREABLE_TO_KEY(array[i], value) < 0)
} value = array[index = i];
} }
firstIndex = index; }
} else {
return firstIndex; for(int i = index;i>=0;i--) {
} if(comparator.compare(array[i], value) < 0)
value = array[index = i];
private class Iter implements ITERATOR KEY_GENERIC_TYPE { }
@Override }
public boolean hasNext() { firstIndex = index;
return !isEmpty(); }
} return firstIndex;
}
@Override
public KEY_TYPE NEXT() { private class Iter implements ITERATOR KEY_GENERIC_TYPE {
if(!hasNext()) throw new NoSuchElementException(); @Override
return dequeue(); public boolean hasNext() {
} return !isEmpty();
} }
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
return dequeue();
}
}
} }
@@ -1,408 +1,415 @@
package speiger.src.collections.PACKAGE.queues; package speiger.src.collections.PACKAGE.queues;
import java.util.Arrays; import java.util.Arrays;
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; 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_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 !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;
#endif #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.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
* A Simple Heap base Priority Queue implementation * A Simple Heap base Priority Queue implementation
* It is a ArrayBased Alternative to TreeSets that has less object allocations * It is a ArrayBased Alternative to TreeSets that has less object allocations
* @Type(T) * @Type(T)
*/ */
public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE
{ {
/** The Backing Array */ /** The Backing Array */
protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY; protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY;
/** The Amount of elements stored within the array */ /** The Amount of elements stored within the array */
protected int size; protected int size;
/** The Sorter of the Array */ /** The Sorter of the Array */
protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator; protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator;
/** /**
* Default Constructor * Default Constructor
*/ */
public HEAP_PRIORITY_QUEUE() { public HEAP_PRIORITY_QUEUE() {
this(0, null); this(0, null);
} }
/** /**
* Constructor using custom sorter * Constructor using custom sorter
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
*/ */
public HEAP_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public HEAP_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this(0, comp); this(0, comp);
} }
/** /**
* Constructor with a Min Capacity * Constructor with a Min Capacity
* @param size the initial capacity of the backing array * @param size the initial capacity of the backing array
* @throws IllegalStateException if the initial size is smaller 0 * @throws IllegalStateException if the initial size is smaller 0
*/ */
public HEAP_PRIORITY_QUEUE(int size) { public HEAP_PRIORITY_QUEUE(int size) {
this(size, null); this(size, null);
} }
/** /**
* Constructor with a Min Capacity and custom Sorter * Constructor with a Min Capacity and custom Sorter
* @param size the initial capacity of the backing array * @param size the initial capacity of the backing array
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
* @throws IllegalStateException if the initial size is smaller 0 * @throws IllegalStateException if the initial size is smaller 0
*/ */
public HEAP_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public HEAP_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
if(size > 0) array = NEW_KEY_ARRAY(size); if(size > 0) array = NEW_KEY_ARRAY(size);
comparator = comp; comparator = comp;
} }
/** /**
* Constructor using a initial array * Constructor using a initial array
* @param array the Array that should be used * @param array the Array that should be used
*/ */
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array) { public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array) {
this(array, array.length); this(array, array.length);
} }
/** /**
* Constructor using a initial array * Constructor using a initial array
* @param array the Array that should be used * @param array the Array that should be used
* @param size the amount of elements found within the array * @param size the amount of elements found within the array
* @throws NegativeArraySizeException if size is smaller then 0 * @throws NegativeArraySizeException if size is smaller then 0
*/ */
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size) { public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size) {
this.array = Arrays.copyOf(array, size); this.array = Arrays.copyOf(array, size);
this.size = size; this.size = size;
ARRAYS.heapify(array, size, null); ARRAYS.heapify(array, size, null);
} }
/** /**
* Constructor using a initial array and a custom sorter * Constructor using a initial array and a custom sorter
* @param array the Array that should be used * @param array the Array that should be used
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
*/ */
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this(array, array.length, comp); this(array, array.length, comp);
} }
/** /**
* Constructor using a initial array and a custom sorter * Constructor using a initial array and a custom sorter
* @param array the Array that should be used * @param array the Array that should be used
* @param size the amount of elements found within the array * @param size the amount of elements found within the array
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
* @throws NegativeArraySizeException if size is smaller then 0 * @throws NegativeArraySizeException if size is smaller then 0
*/ */
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this.array = Arrays.copyOf(array, size); this.array = Arrays.copyOf(array, size);
this.size = size; this.size = size;
comparator = comp; comparator = comp;
ARRAYS.heapify(array, size, comp); ARRAYS.heapify(array, size, comp);
} }
/** /**
* Constructor using a Collection * Constructor using a Collection
* @param c the Collection that should be used * @param c the Collection that should be used
*/ */
public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) { public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) {
array = CAST_KEY_ARRAY c.TO_ARRAY(); array = CAST_KEY_ARRAY c.TO_ARRAY();
size = c.size(); size = c.size();
ARRAYS.heapify(array, size, null); ARRAYS.heapify(array, size, null);
} }
/** /**
* Constructor using a Collection and a custom sorter * Constructor using a Collection and a custom sorter
* @param c the Collection that should be used * @param c the Collection that should be used
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
*/ */
public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
array = CAST_KEY_ARRAY c.TO_ARRAY(); array = CAST_KEY_ARRAY c.TO_ARRAY();
size = c.size(); size = c.size();
comparator = comp; comparator = comp;
ARRAYS.heapify(array, size, comp); ARRAYS.heapify(array, size, comp);
} }
/** /**
* Wrapping method to help serialization * Wrapping method to help serialization
* @param array the array that should be used * @param array the array that should be used
* @Type(T) * @Type(T)
* @return a HeapPriorityQueue containing the original input array * @return a HeapPriorityQueue containing the original input array
*/ */
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) {
return wrap(array, array.length); return wrap(array, array.length);
} }
/** /**
* Wrapping method to help serialization * Wrapping method to help serialization
* @param array the array that should be used * @param array the array that should be used
* @param size the amount of elements within the array * @param size the amount of elements within the array
* @Type(T) * @Type(T)
* @return a HeapPriorityQueue containing the original input array * @return a HeapPriorityQueue containing the original input array
*/ */
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) { public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) {
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(); HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES();
queue.array = array; queue.array = array;
queue.size = size; queue.size = size;
ARRAYS.heapify(array, size, null); ARRAYS.heapify(array, size, null);
return queue; return queue;
} }
/** /**
* Wrapping method to help serialization, using a custom sorter * Wrapping method to help serialization, using a custom sorter
* @param array the array that should be used * @param array the array that should be used
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
* @Type(T) * @Type(T)
* @return a HeapPriorityQueue containing the original input array * @return a HeapPriorityQueue containing the original input array
*/ */
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
return wrap(array, array.length, comp); return wrap(array, array.length, comp);
} }
/** /**
* Wrapping method to help serialization, using a custom sorter * Wrapping method to help serialization, using a custom sorter
* @param array the array that should be used * @param array the array that should be used
* @param size the amount of elements within the array * @param size the amount of elements within the array
* @param comp Comparator to sort the Array. Can be null * @param comp Comparator to sort the Array. Can be null
* @Type(T) * @Type(T)
* @return a HeapPriorityQueue containing the original input array * @return a HeapPriorityQueue containing the original input array
*/ */
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(comp); HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(comp);
queue.array = array; queue.array = array;
queue.size = size; queue.size = size;
ARRAYS.heapify(array, size, comp); ARRAYS.heapify(array, size, comp);
return queue; return queue;
} }
@Override @Override
public int size() { public int size() {
return size; return size;
} }
@Override @Override
public void clear() { public void clear() {
#if TYPE_OBJECT #if TYPE_OBJECT
Arrays.fill(array, null); Arrays.fill(array, null);
#endif #endif
size = 0; size = 0;
} }
@Override @Override
public ITERATOR KEY_GENERIC_TYPE iterator() { public ITERATOR KEY_GENERIC_TYPE iterator() {
return new Iter(); return new Iter();
} }
@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));
array[size++] = e; array[size++] = e;
ARRAYS.shiftUp(array, size-1, comparator); ARRAYS.shiftUp(array, size-1, comparator);
} }
@Override @Override
public KEY_TYPE dequeue() { public KEY_TYPE dequeue() {
if(size <= 0) throw new NoSuchElementException(); if(size <= 0) throw new NoSuchElementException();
KEY_TYPE value = array[0]; KEY_TYPE value = array[0];
array[0] = array[--size]; array[0] = array[--size];
#if TYPE_OBJECT #if TYPE_OBJECT
array[size] = null; array[size] = null;
#endif #endif
if(size != 0) ARRAYS.shiftDown(array, size, 0, comparator); if(size != 0) ARRAYS.shiftDown(array, size, 0, comparator);
return value; return value;
} }
@Override @Override
public KEY_TYPE peek(int index) { public KEY_TYPE peek(int index) {
if(index < 0 || index >= size) throw new NoSuchElementException(); if(index < 0 || index >= size) throw new NoSuchElementException();
return array[index]; return array[index];
} }
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean contains(KEY_TYPE e) {
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i); if(KEY_EQUALS(e, array[i])) return true;
return false; return false;
} }
@Override @Override
public boolean removeLast(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
for(int i = size-1;i>=0;i--) for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i); if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false; return false;
} }
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public boolean removeLast(KEY_TYPE e) {
Objects.requireNonNull(action); for(int i = size-1;i>=0;i--)
for(int i = 0,m=size;i<m;i++) action.accept(dequeue()); if(KEY_EQUALS(e, array[i])) return removeIndex(i);
} return false;
}
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { @Override
Objects.requireNonNull(action); public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue()); Objects.requireNonNull(action);
} for(int i = 0,m=size;i<m;i++) action.accept(dequeue());
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { @Override
Objects.requireNonNull(action); public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
for(int i = 0,m=size;i<m;i++) action.accept(input, dequeue()); Objects.requireNonNull(action);
} for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue());
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { @Override
Objects.requireNonNull(filter); public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
for(int i = 0;i<size;i++) { Objects.requireNonNull(action);
if(filter.test(array[i])) return true; for(int i = 0,m=size;i<m;i++) action.accept(input, dequeue());
} }
return false;
} @Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
@Override Objects.requireNonNull(filter);
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { for(int i = 0;i<size;i++) {
Objects.requireNonNull(filter); if(filter.test(array[i])) return true;
for(int i = 0;i<size;i++) { }
if(filter.test(array[i])) return false; return false;
} }
return true;
} @Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
@Override Objects.requireNonNull(filter);
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { for(int i = 0;i<size;i++) {
Objects.requireNonNull(filter); if(filter.test(array[i])) return false;
for(int i = 0;i<size;i++) { }
if(!filter.test(array[i])) return false; return true;
} }
return true;
} @Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
#if !TYPE_OBJECT Objects.requireNonNull(filter);
@Override for(int i = 0;i<size;i++) {
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { if(!filter.test(array[i])) return false;
Objects.requireNonNull(operator); }
KEY_TYPE state = identity; return true;
for(int i = 0;i<size;i++) { }
state = operator.APPLY_VALUE(state, array[i]);
} #if !TYPE_OBJECT
return state; @Override
} public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
#else KEY_TYPE state = identity;
@Override for(int i = 0;i<size;i++) {
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) { state = operator.APPLY_VALUE(state, array[i]);
Objects.requireNonNull(operator); }
KEY_SPECIAL_TYPE state = identity; return state;
for(int i = 0;i<size;i++) { }
state = operator.APPLY_VALUE(state, array[i]);
} #else
return state; @Override
} public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
Objects.requireNonNull(operator);
#endif KEY_SPECIAL_TYPE state = identity;
@Override for(int i = 0;i<size;i++) {
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { state = operator.APPLY_VALUE(state, array[i]);
Objects.requireNonNull(operator); }
KEY_TYPE state = EMPTY_VALUE; return state;
boolean empty = true; }
for(int i = 0;i<size;i++) {
if(empty) { #endif
empty = false; @Override
state = array[i]; public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
continue; Objects.requireNonNull(operator);
} KEY_TYPE state = EMPTY_VALUE;
state = operator.APPLY_VALUE(state, array[i]); boolean empty = true;
} for(int i = 0;i<size;i++) {
return state; if(empty) {
} empty = false;
state = array[i];
@Override continue;
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { }
Objects.requireNonNull(filter); state = operator.APPLY_VALUE(state, array[i]);
for(int i = 0;i<size;i++) { }
if(filter.test(array[i])) { return state;
KEY_TYPE data = array[i]; }
removeIndex(i);
return data; @Override
} public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
} Objects.requireNonNull(filter);
return EMPTY_VALUE; for(int i = 0;i<size;i++) {
} if(filter.test(array[i])) {
KEY_TYPE data = array[i];
@Override removeIndex(i);
public int count(PREDICATE KEY_GENERIC_TYPE filter) { return data;
Objects.requireNonNull(filter); }
int result = 0; }
for(int i = 0;i<size;i++) { return EMPTY_VALUE;
if(filter.test(array[i])) result++; }
}
return result; @Override
} public int count(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
protected boolean removeIndex(int index) { int result = 0;
array[index] = array[--size]; for(int i = 0;i<size;i++) {
#if TYPE_OBJECT if(filter.test(array[i])) result++;
array[size] = null; }
#endif return result;
if(size != index) ARRAYS.shiftDown(array, size, index, comparator); }
return true;
} protected boolean removeIndex(int index) {
array[index] = array[--size];
@Override #if TYPE_OBJECT
public void onChanged() { array[size] = null;
if(size <= 0) return; #endif
ARRAYS.shiftDown(array, size, 0, comparator); if(size != index) ARRAYS.shiftDown(array, size, index, comparator);
} return true;
}
@Override
public HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE copy() { @Override
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(); public void onChanged() {
queue.size = size; if(size <= 0) return;
queue.comparator = comparator; ARRAYS.shiftDown(array, size, 0, comparator);
queue.array = Arrays.copyOf(array, array.length); }
return queue;
} @Override
public HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE copy() {
@Override HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES();
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { queue.size = size;
return comparator; queue.comparator = comparator;
} queue.array = Arrays.copyOf(array, array.length);
return queue;
@Override }
public GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); @Override
System.arraycopy(array, 0, input, 0, size()); public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() {
return input; return comparator;
} }
private class Iter implements ITERATOR KEY_GENERIC_TYPE { @Override
@Override public GENERIC_SPECIAL_KEY_BRACES<E> KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
public boolean hasNext() { if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size());
return !isEmpty(); System.arraycopy(array, 0, input, 0, size());
} return input;
}
@Override
public KEY_TYPE NEXT() { private class Iter implements ITERATOR KEY_GENERIC_TYPE {
if(!hasNext()) throw new NoSuchElementException(); @Override
return dequeue(); public boolean hasNext() {
} return !isEmpty();
} }
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
return dequeue();
}
}
} }
@@ -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
File diff suppressed because it is too large Load Diff
@@ -690,7 +690,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++) {
@@ -16,6 +16,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 +33,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 +71,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 +81,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 +203,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
@@ -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,44 @@ 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
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)));
}
}
#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 BOOLEAN_COLLECTION_MODULE
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
@@ -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
@@ -846,6 +917,42 @@ 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
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);
}
}
#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 +1025,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,6 +24,9 @@ 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;
#if INT_LIST_MODULE && !TYPE_INT
import speiger.src.collections.ints.lists.IntList;
#endif
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@@ -408,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); } }
@@ -530,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(); }
@@ -623,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; }
@@ -636,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(); }
@@ -116,6 +116,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); } }
@@ -346,6 +346,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 +418,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
@@ -659,6 +679,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
@@ -1091,6 +1121,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
@@ -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);
@@ -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,14 +26,13 @@ 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(); }));
}));
expectAdded(e3()); expectAdded(e3());
} }
#if !VALUE_BOOLEAN #if !VALUE_BOOLEAN
#ignore #ignore
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
@@ -41,22 +40,28 @@ 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
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(ONE) @CollectionSize.Require(ONE)
#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,29 +74,31 @@ 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();
} }
#ignore #ignore
@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 {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }
#ignore #ignore
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
#endignore #endignore
@@ -129,11 +136,10 @@ 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(); }));
}));
} catch (UnsupportedOperationException tolerated) { } catch (UnsupportedOperationException tolerated) {
} }
expectUnchanged(); expectUnchanged();
@@ -145,11 +151,10 @@ 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(); }));
}));
} catch (UnsupportedOperationException tolerated) { } catch (UnsupportedOperationException tolerated) {
} }
expectUnchanged(); expectUnchanged();
@@ -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,45 +21,42 @@ 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();
} }
#ignore #ignore
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
@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(); }));
}));
expectReplacement(entry(k0(), v3())); expectReplacement(entry(k0(), v3()));
} }
#ignore #ignore
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
@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; }));
}));
expectMissing(e0()); expectMissing(e0());
} }
static class ExpectedException extends RuntimeException { static class ExpectedException extends RuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }
#ignore #ignore
@MapFeature.Require(SUPPORTS_PUT) @MapFeature.Require(SUPPORTS_PUT)
@CollectionSize.Require(absent = ZERO) @CollectionSize.Require(absent = ZERO)
@@ -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,12 +21,11 @@ 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(); }));
}));
expectAdded(e3()); expectAdded(e3());
assertEquals(getNumElements() + 1, getMap().size()); assertEquals(getNumElements() + 1, getMap().size());
} }
@@ -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,12 +53,11 @@ 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(); }));
}));
expectReplacement(entry(k0(), v3())); expectReplacement(entry(k0(), v3()));
assertEquals(getNumElements(), getMap().size()); assertEquals(getNumElements(), getMap().size());
} }
@@ -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 {
@@ -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,10 +62,9 @@ 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 {
@@ -1,5 +1,8 @@
package speiger.src.collections.utils; package speiger.src.collections.utils;
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.function.IntFunction;
/** /**
* The Stack Interface represents the Last-In-First-Out layout (LIFO). * The Stack Interface represents the Last-In-First-Out layout (LIFO).
@@ -16,6 +19,14 @@ public interface Stack<T>
*/ */
public void push(T e); public void push(T 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 +70,33 @@ public interface Stack<T>
* @throws ArrayIndexOutOfBoundsException if the index is out of bounds * @throws ArrayIndexOutOfBoundsException if the index is out of bounds
*/ */
public T peek(int index); public T peek(int index);
/**
* A method to drop the contents of the Queue without clearing the queue
* @param <E> the keyType of elements maintained by this Collection
* @return the contents of the queue into a seperate array.
*/
public default <E> E[] toArray() {
return toArray((E[])new Object[size()]);
}
/**
* A method to drop the contents of the Stack without clearing the stack
* @param array where the elements should be inserted to. If it does not fit then it creates a new appropriately created array
* @param <E> the keyType of elements maintained by this Collection
* @return the contents of the stack into a separate array.
* @note if the Type is generic then a Object Array is created instead of a Type Array
*/
public <E> E[] toArray(E[] array);
/**
* A Helper function that simplifies the process of creating a new Array.
* @param action the array creation function
* @param <E> the returning arrayType
* @return an array containing all of the elements in this collection
* @see Collection#toArray(Object[])
*/
public default <E> E[] toArray(IntFunction<E[]> action) {
return toArray(action.apply(size()));
}
} }
@@ -1,174 +1,174 @@
package speiger.src.collections.ints.base; package speiger.src.collections.ints.base;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import speiger.src.collections.ints.collections.IntIterable; import speiger.src.collections.ints.collections.IntIterable;
import speiger.src.collections.ints.collections.IntIterator; import speiger.src.collections.ints.collections.IntIterator;
import speiger.src.collections.ints.lists.IntArrayList; import speiger.src.collections.ints.lists.IntArrayList;
import speiger.src.collections.ints.utils.IntArrays; import speiger.src.collections.ints.utils.IntArrays;
import speiger.src.collections.ints.utils.IntIterators; import speiger.src.collections.ints.utils.IntIterators;
import speiger.src.collections.objects.utils.ObjectArrays; import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.objects.utils.ObjectIterators; import speiger.src.collections.objects.utils.ObjectIterators;
import speiger.src.collections.tests.IterableTest; import speiger.src.collections.tests.IterableTest;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public abstract class BaseIntIterableTest public abstract class BaseIntIterableTest
{ {
protected static final int[] EMPTY_ARRAY = new int[0]; protected static final int[] EMPTY_ARRAY = new int[0];
protected static final int[] TEST_ARRAY = IntStream.range(0, 100).toArray(); protected static final int[] TEST_ARRAY = IntStream.range(0, 100).toArray();
protected static final int[] DISTINCT_ARRAY = IntStream.range(0, 100).flatMap(T -> Arrays.stream(new int[]{T, T})).toArray(); protected static final int[] DISTINCT_ARRAY = IntStream.range(0, 100).flatMap(T -> Arrays.stream(new int[]{T, T})).toArray();
protected abstract IntIterable create(int[] data); protected abstract IntIterable create(int[] data);
protected EnumSet<IterableTest> getValidIterableTests() { return EnumSet.allOf(IterableTest.class); } protected EnumSet<IterableTest> getValidIterableTests() { return EnumSet.allOf(IterableTest.class); }
@Test @Test
public void testForEach() { public void testForEach() {
if(getValidIterableTests().contains(IterableTest.FOR_EACH)) { if(getValidIterableTests().contains(IterableTest.FOR_EACH)) {
create(TEST_ARRAY).forEach(T -> Assert.assertTrue(T >= 0 && T < 100)); create(TEST_ARRAY).forEach(T -> Assert.assertTrue(T >= 0 && T < 100));
} }
} }
@Test @Test
public void testIteratorForEach() { public void testIteratorForEach() {
if(getValidIterableTests().contains(IterableTest.ITERATOR_FOR_EACH)) { if(getValidIterableTests().contains(IterableTest.ITERATOR_FOR_EACH)) {
create(TEST_ARRAY).iterator().forEachRemaining(T -> Assert.assertTrue(T >= 0 && T < 100)); create(TEST_ARRAY).iterator().forEachRemaining(T -> Assert.assertTrue(T >= 0 && T < 100));
} }
} }
@Test @Test
public void testSkip() { public void testSkip() {
if(getValidIterableTests().contains(IterableTest.ITERATOR_SKIP)) { if(getValidIterableTests().contains(IterableTest.ITERATOR_SKIP)) {
IntIterator iter = create(TEST_ARRAY).iterator(); IntIterator iter = create(TEST_ARRAY).iterator();
Assert.assertEquals(50, iter.skip(50)); Assert.assertEquals(50, iter.skip(50));
Assert.assertNotEquals(100, iter.skip(100)); Assert.assertNotEquals(100, iter.skip(100));
} }
} }
@Test @Test
public void testIteratorLoop() { public void testIteratorLoop() {
if(getValidIterableTests().contains(IterableTest.ITERATOR_LOOP)) { if(getValidIterableTests().contains(IterableTest.ITERATOR_LOOP)) {
for(int entry : create(TEST_ARRAY)) Assert.assertTrue(entry >= 0 && entry < 100); for(int entry : create(TEST_ARRAY)) Assert.assertTrue(entry >= 0 && entry < 100);
for(IntIterator iter = create(TEST_ARRAY).iterator();iter.hasNext();) { for(IntIterator iter = create(TEST_ARRAY).iterator();iter.hasNext();) {
int entry = iter.nextInt(); int entry = iter.nextInt();
Assert.assertTrue(entry >= 0 && entry < 100); Assert.assertTrue(entry >= 0 && entry < 100);
} }
} }
} }
@Test @Test
public void testIteratorRemovalLoop() { public void testIteratorRemovalLoop() {
if(getValidIterableTests().contains(IterableTest.ITERATOR_REMOVAL)) { if(getValidIterableTests().contains(IterableTest.ITERATOR_REMOVAL)) {
for(IntIterator iter = create(TEST_ARRAY).iterator();iter.hasNext();) { for(IntIterator iter = create(TEST_ARRAY).iterator();iter.hasNext();) {
int entry = iter.nextInt(); int entry = iter.nextInt();
Assert.assertTrue(entry >= 0 && entry < 100); Assert.assertTrue(entry >= 0 && entry < 100);
iter.remove(); iter.remove();
} }
} }
} }
@Test @Test
public void testStreamCount() { public void testStreamCount() {
if(getValidIterableTests().contains(IterableTest.STREAM_COUNT)) { if(getValidIterableTests().contains(IterableTest.STREAM_COUNT)) {
long expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).count(); long expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).count();
int size = create(TEST_ARRAY).count(T -> T % 2 == 0); int size = create(TEST_ARRAY).count(T -> T % 2 == 0);
Assert.assertEquals(expected, size); Assert.assertEquals(expected, size);
} }
} }
@Test @Test
public void testStreamFilter() { public void testStreamFilter() {
if(getValidIterableTests().contains(IterableTest.STREAM_FILTER)) { if(getValidIterableTests().contains(IterableTest.STREAM_FILTER)) {
int[] expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).toArray(); int[] expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).toArray();
int[] actual = IntIterators.pour(create(TEST_ARRAY).filter(T -> T % 2 == 0).iterator()).toIntArray(); int[] actual = IntIterators.pour(create(TEST_ARRAY).filter(T -> T % 2 == 0).iterator()).toIntArray();
IntArrays.stableSort(actual); IntArrays.stableSort(actual);
Assert.assertArrayEquals(expected, actual); Assert.assertArrayEquals(expected, actual);
} }
} }
@Test @Test
public void testStreamFindFirst() { public void testStreamFindFirst() {
if(getValidIterableTests().contains(IterableTest.STREAM_FIND_FIRST)) { if(getValidIterableTests().contains(IterableTest.STREAM_FIND_FIRST)) {
int expected = IntStream.of(TEST_ARRAY).filter(T -> T / 50 > 0).findFirst().getAsInt(); int expected = IntStream.of(TEST_ARRAY).filter(T -> T / 50 > 0).findFirst().getAsInt();
int actual = create(TEST_ARRAY).findFirst(T -> T / 50 > 0); int actual = create(TEST_ARRAY).findFirst(T -> T / 50 > 0);
Assert.assertEquals(expected, actual); Assert.assertEquals(expected, actual);
} }
} }
@Test @Test
public void teastStreamDistinct() { public void teastStreamDistinct() {
if(getValidIterableTests().contains(IterableTest.STREAM_DISTINCT)) { if(getValidIterableTests().contains(IterableTest.STREAM_DISTINCT)) {
int[] expected = IntStream.of(DISTINCT_ARRAY).distinct().toArray(); int[] expected = IntStream.of(DISTINCT_ARRAY).distinct().toArray();
int[] actual = IntIterators.pour(create(DISTINCT_ARRAY).distinct().iterator()).toIntArray(); int[] actual = IntIterators.pour(create(DISTINCT_ARRAY).distinct().iterator()).toIntArray();
IntArrays.stableSort(actual); IntArrays.stableSort(actual);
Assert.assertArrayEquals(expected, actual); Assert.assertArrayEquals(expected, actual);
} }
} }
@Test @Test
public void testStreamLimit() { public void testStreamLimit() {
if(getValidIterableTests().contains(IterableTest.STREAM_LIMIT)) { if(getValidIterableTests().contains(IterableTest.STREAM_LIMIT)) {
int[] expected = IntStream.of(TEST_ARRAY).limit(25).toArray(); int[] expected = IntStream.of(TEST_ARRAY).limit(25).toArray();
int[] actual = IntIterators.pour(create(TEST_ARRAY).limit(25).iterator()).toIntArray(); int[] actual = IntIterators.pour(create(TEST_ARRAY).limit(25).iterator()).toIntArray();
Assert.assertEquals(expected.length, actual.length); Assert.assertEquals(expected.length, actual.length);
} }
} }
@Test @Test
public void testStreamMap() { public void testStreamMap() {
if(getValidIterableTests().contains(IterableTest.STREAM_MAP)) { if(getValidIterableTests().contains(IterableTest.STREAM_MAP)) {
Integer[] expected = IntStream.of(TEST_ARRAY).mapToObj(Integer::valueOf).toArray(Integer[]::new); Integer[] expected = IntStream.of(TEST_ARRAY).mapToObj(Integer::valueOf).toArray(Integer[]::new);
Integer[] actual = ObjectIterators.pour(create(TEST_ARRAY).map(Integer::valueOf).iterator()).toArray(Integer[]::new); Integer[] actual = ObjectIterators.pour(create(TEST_ARRAY).map(Integer::valueOf).iterator()).toArray(Integer[]::new);
ObjectArrays.stableSort(actual); ObjectArrays.stableSort(actual);
Assert.assertArrayEquals(expected, actual); Assert.assertArrayEquals(expected, actual);
} }
} }
@Test @Test
public void testStreamMatches() { public void testStreamMatches() {
if(getValidIterableTests().contains(IterableTest.STREAM_MATCHES)) { if(getValidIterableTests().contains(IterableTest.STREAM_MATCHES)) {
IntIterable iterable = create(TEST_ARRAY); IntIterable iterable = create(TEST_ARRAY);
Assert.assertTrue(iterable.matchesAll(T -> T >= 0)); Assert.assertTrue(iterable.matchesAll(T -> T >= 0));
Assert.assertFalse(iterable.matchesAll(T -> T < 0)); Assert.assertFalse(iterable.matchesAll(T -> T < 0));
Assert.assertTrue(iterable.matchesAny(T -> T % 2 != 0)); Assert.assertTrue(iterable.matchesAny(T -> T % 2 != 0));
Assert.assertFalse(iterable.matchesAny(T -> T % 2 >= 2)); Assert.assertFalse(iterable.matchesAny(T -> T % 2 >= 2));
Assert.assertTrue(iterable.matchesNone(T -> T % 2 >= 2)); Assert.assertTrue(iterable.matchesNone(T -> T % 2 >= 2));
Assert.assertFalse(iterable.matchesNone(T -> T % 2 != 0)); Assert.assertFalse(iterable.matchesNone(T -> T % 2 != 0));
} }
} }
@Test @Test
public void testStreamPeek() { public void testStreamPeek() {
if(getValidIterableTests().contains(IterableTest.STREAM_PEEK)) { if(getValidIterableTests().contains(IterableTest.STREAM_PEEK)) {
int[] peekCount = new int[2]; int[] peekCount = new int[2];
create(TEST_ARRAY).peek(T -> peekCount[0]++).forEach(T -> peekCount[1]++); create(TEST_ARRAY).peek(T -> peekCount[0]++).forEach(T -> peekCount[1]++);
Assert.assertEquals(TEST_ARRAY.length, peekCount[0]); Assert.assertEquals(TEST_ARRAY.length, peekCount[0]);
Assert.assertEquals(TEST_ARRAY.length, peekCount[1]); Assert.assertEquals(TEST_ARRAY.length, peekCount[1]);
} }
} }
@Test @Test
public void testStreamPour() { public void testStreamPour() {
if(getValidIterableTests().contains(IterableTest.STREAM_POUR)) { if(getValidIterableTests().contains(IterableTest.STREAM_POUR)) {
int[] expected = TEST_ARRAY; int[] expected = TEST_ARRAY;
int[] actual = create(TEST_ARRAY).pour(new IntArrayList()).toIntArray(); int[] actual = create(TEST_ARRAY).pour(new IntArrayList()).toIntArray();
IntArrays.stableSort(actual); IntArrays.stableSort(actual);
Assert.assertArrayEquals(expected, actual); Assert.assertArrayEquals(expected, actual);
} }
} }
@Test @Test
public void testStreamReduce() { public void testStreamReduce() {
if(getValidIterableTests().contains(IterableTest.STREAM_REDUCE)) { if(getValidIterableTests().contains(IterableTest.STREAM_REDUCE)) {
int expected = IntStream.of(TEST_ARRAY).reduce(0, Integer::sum); int expected = IntStream.of(TEST_ARRAY).reduce(0, Integer::sum);
int actual = create(TEST_ARRAY).reduce(0, Integer::sum); int actual = create(TEST_ARRAY).reduce(0, Integer::sum);
Assert.assertEquals(expected, actual); Assert.assertEquals(expected, actual);
} }
} }
} }
@@ -1,150 +1,162 @@
package speiger.src.collections.ints.base; package speiger.src.collections.ints.base;
import java.util.EnumSet; import java.util.EnumSet;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import speiger.src.collections.ints.queues.IntPriorityQueue; import speiger.src.collections.ints.queues.IntPriorityQueue;
import speiger.src.collections.ints.utils.IntArrays; import speiger.src.collections.ints.utils.IntArrays;
import speiger.src.collections.tests.IterableTest; import speiger.src.collections.tests.IterableTest;
import speiger.src.collections.tests.PriorityQueueTest; import speiger.src.collections.tests.PriorityQueueTest;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public abstract class BaseIntPriorityQueueTest extends BaseIntIterableTest public abstract class BaseIntPriorityQueueTest extends BaseIntIterableTest
{ {
@Override @Override
protected abstract IntPriorityQueue create(int[] data); protected abstract IntPriorityQueue create(int[] data);
@Override @Override
protected EnumSet<IterableTest> getValidIterableTests() { return EnumSet.of(IterableTest.FOR_EACH, IterableTest.ITERATOR_FOR_EACH, IterableTest.ITERATOR_LOOP, IterableTest.ITERATOR_SKIP); } protected EnumSet<IterableTest> getValidIterableTests() { return EnumSet.of(IterableTest.FOR_EACH, IterableTest.ITERATOR_FOR_EACH, IterableTest.ITERATOR_LOOP, IterableTest.ITERATOR_SKIP); }
protected EnumSet<PriorityQueueTest> getValidPriorityQueueTests() { return EnumSet.allOf(PriorityQueueTest.class); } protected EnumSet<PriorityQueueTest> getValidPriorityQueueTests() { return EnumSet.allOf(PriorityQueueTest.class); }
protected boolean isUnsortedRead() { return true; } protected boolean isUnsortedRead() { return true; }
@Test @Test
public void testEnqueue() { public void testEnqueue() {
if(getValidPriorityQueueTests().contains(PriorityQueueTest.IN_OUT)) { if(getValidPriorityQueueTests().contains(PriorityQueueTest.IN_OUT)) {
IntPriorityQueue queue = create(EMPTY_ARRAY); IntPriorityQueue queue = create(EMPTY_ARRAY);
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
queue.enqueue(i); queue.enqueue(i);
} }
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
Assert.assertEquals(i, queue.dequeue()); Assert.assertEquals(i, queue.dequeue());
} }
queue = create(TEST_ARRAY); queue = create(TEST_ARRAY);
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
Assert.assertEquals(i, queue.dequeue()); Assert.assertEquals(i, queue.dequeue());
} }
} }
} }
@Test @Test
public void testPeek() { public void testPeek() {
if(getValidPriorityQueueTests().contains(PriorityQueueTest.PEEK)) { if(getValidPriorityQueueTests().contains(PriorityQueueTest.PEEK)) {
IntPriorityQueue queue = create(EMPTY_ARRAY); IntPriorityQueue queue = create(EMPTY_ARRAY);
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
queue.enqueue(i); queue.enqueue(i);
} }
if(isUnsortedRead()) { if(isUnsortedRead()) {
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
int value = queue.peek(i); int value = queue.peek(i);
Assert.assertTrue(value >= 0 && value < 100); Assert.assertTrue(value >= 0 && value < 100);
} }
} }
else { else {
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
Assert.assertEquals(i, queue.peek(i)); Assert.assertEquals(i, queue.peek(i));
} }
} }
} }
} }
@Test @Test
public void testRemove() { public void testContains() {
if(getValidPriorityQueueTests().contains(PriorityQueueTest.REMOVE)) { if(getValidPriorityQueueTests().contains(PriorityQueueTest.CONTAINS)) {
IntPriorityQueue queue = create(EMPTY_ARRAY); IntPriorityQueue queue = create(EMPTY_ARRAY);
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
queue.enqueue(i); queue.enqueue(i);
} }
queue.removeFirst(40); Assert.assertEquals(true, queue.contains(40));
for(int i = 0;i<99;i++) { Assert.assertEquals(false, queue.contains(140));
if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue()); }
else Assert.assertEquals(i, queue.dequeue()); }
}
for(int i = 0;i<100;i++) { @Test
queue.enqueue(i); public void testRemove() {
} if(getValidPriorityQueueTests().contains(PriorityQueueTest.REMOVE)) {
queue.removeLast(40); IntPriorityQueue queue = create(EMPTY_ARRAY);
for(int i = 0;i<99;i++) { for(int i = 0;i<100;i++) {
if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue()); queue.enqueue(i);
else Assert.assertEquals(i, queue.dequeue()); }
} queue.removeFirst(40);
} for(int i = 0;i<99;i++) {
} if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue());
else Assert.assertEquals(i, queue.dequeue());
@Test }
public void testUnorderedPeek() { for(int i = 0;i<100;i++) {
EnumSet<PriorityQueueTest> valid = getValidPriorityQueueTests(); queue.enqueue(i);
if(valid.contains(PriorityQueueTest.IN_OUT) && valid.contains(PriorityQueueTest.PEEK) && !isUnsortedRead()) { }
IntPriorityQueue queue = create(EMPTY_ARRAY); queue.removeLast(40);
for(int i = 0;i<100;i++) { for(int i = 0;i<99;i++) {
queue.enqueue(i); if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue());
} else Assert.assertEquals(i, queue.dequeue());
for(int i = 0;i<25;i++) { }
queue.dequeue(); }
queue.enqueue(i); }
}
for(int i = 0;i<100;i++) { @Test
Assert.assertEquals((i+25) % 100, queue.peek(i)); public void testUnorderedPeek() {
} EnumSet<PriorityQueueTest> valid = getValidPriorityQueueTests();
} if(valid.contains(PriorityQueueTest.IN_OUT) && valid.contains(PriorityQueueTest.PEEK) && !isUnsortedRead()) {
} IntPriorityQueue queue = create(EMPTY_ARRAY);
for(int i = 0;i<100;i++) {
@Test queue.enqueue(i);
@SuppressWarnings("deprecation") }
public void testToArray() { for(int i = 0;i<25;i++) {
if(getValidPriorityQueueTests().contains(PriorityQueueTest.TO_ARRAY)) { queue.dequeue();
IntPriorityQueue queue = create(EMPTY_ARRAY); queue.enqueue(i);
if(isUnsortedRead()) { }
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
queue.enqueue(i); Assert.assertEquals((i+25) % 100, queue.peek(i));
} }
int[] array = queue.toIntArray(); }
IntArrays.stableSort(array); }
Assert.assertArrayEquals(TEST_ARRAY, array);
int[] data = queue.toIntArray(new int[100]); @Test
int[] nonData = queue.toIntArray(new int[0]); @SuppressWarnings("deprecation")
IntArrays.stableSort(data); public void testToArray() {
IntArrays.stableSort(nonData); if(getValidPriorityQueueTests().contains(PriorityQueueTest.TO_ARRAY)) {
Assert.assertArrayEquals(array, data); IntPriorityQueue queue = create(EMPTY_ARRAY);
Assert.assertArrayEquals(array, nonData); if(isUnsortedRead()) {
} for(int i = 0;i<100;i++) {
else { queue.enqueue(i);
int[] shiftPrimArray = new int[100]; }
for(int i = 0; i < 100; i++) { int[] array = queue.toIntArray();
queue.enqueue(i); IntArrays.stableSort(array);
shiftPrimArray[(i+80) % 100] = i; Assert.assertArrayEquals(TEST_ARRAY, array);
} int[] data = queue.toIntArray(new int[100]);
Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray()); int[] nonData = queue.toIntArray(new int[0]);
Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray(new int[100])); IntArrays.stableSort(data);
Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray(null)); IntArrays.stableSort(nonData);
IntPriorityQueue other = create(queue.toIntArray()); Assert.assertArrayEquals(array, data);
for(int i = 0;i<20;i++) { Assert.assertArrayEquals(array, nonData);
other.dequeue(); }
other.enqueue(i); else {
} int[] shiftPrimArray = new int[100];
Assert.assertArrayEquals(shiftPrimArray, other.toIntArray()); for(int i = 0; i < 100; i++) {
Assert.assertArrayEquals(shiftPrimArray, other.toIntArray(new int[100])); queue.enqueue(i);
} shiftPrimArray[(i+80) % 100] = i;
} }
} Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray());
Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray(new int[100]));
@Test Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray(null));
public void testCopy() { IntPriorityQueue other = create(queue.toIntArray());
if(!getValidPriorityQueueTests().contains(PriorityQueueTest.COPY)) return; for(int i = 0;i<20;i++) {
IntPriorityQueue queue = create(TEST_ARRAY); other.dequeue();
IntPriorityQueue copy = queue.copy(); other.enqueue(i);
Assert.assertFalse(queue == copy); }
Assert.assertEquals(queue, copy); Assert.assertArrayEquals(shiftPrimArray, other.toIntArray());
} Assert.assertArrayEquals(shiftPrimArray, other.toIntArray(new int[100]));
} }
}
}
@Test
public void testCopy() {
if(!getValidPriorityQueueTests().contains(PriorityQueueTest.COPY)) return;
IntPriorityQueue queue = create(TEST_ARRAY);
IntPriorityQueue copy = queue.copy();
Assert.assertFalse(queue == copy);
Assert.assertEquals(queue, copy);
}
}
@@ -1,11 +1,12 @@
package speiger.src.collections.tests; package speiger.src.collections.tests;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public enum PriorityQueueTest public enum PriorityQueueTest
{ {
IN_OUT, IN_OUT,
PEEK, PEEK,
REMOVE, CONTAINS,
TO_ARRAY, REMOVE,
COPY; TO_ARRAY,
COPY;
} }