Author SHA1 Message Date
Speiger 20927a97eb Reworked Module Settings System
Changelog:
- Added: Dependency System that will resolve missing classes and enable
them as needed. (This isn't perfect on some low level modules like
Functions)
- Added: Dependency Error system that will throw errors if a dependency
is that is required is specifically disabled.
- Added: Default setting for "undefined" entries.
- Fixed: A few bugs that made the dependency system unnecessary
difficult.
- Updated: Documentation
2025-03-09 23:29:13 +01:00
Speiger ebe75b0fea Fixing a few things and testing more. Not useable atm. 2025-03-08 01:08:31 +01:00
Speiger a6be24c59d Start of a Advanced Dependency System.
The idea behind this system is that you can select systems a lot easier.
So if a custom system isn't required it can be disabled and all the
subsystems that require it either get disabled too.
it also allows you to set systems as: Only if they are required. Meaning
if only a specific system is required its dependencies can still load.
2025-03-08 01:08:31 +01:00
Speiger afdd27648e Updated Changelog and Readme to include Maven Central 2024-04-11 19:11:07 +02:00
Speiger 7e475b5472 Fixed a few bugs in the maven central script 2024-03-30 05:12:57 +01:00
Speiger e65fde736b Fixed 2024-03-30 01:08:38 +01:00
Speiger bf0b4172de Added Maven central Badge 2024-03-30 01:07:46 +01:00
Speiger 961b47a58c Fixed java8 compat 2024-03-30 01:02:42 +01:00
Speiger 330be87338 finalizing the maven central release. 2024-03-30 00:32:37 +01:00
Speiger 4b30ce12c9 Upgraded thread workers and disable GPG temporarly. 2024-03-29 22:35:44 +01:00
Speiger 0be7dba5d3 Fixed script bug 2024-03-29 22:26:34 +01:00
SpeigerandSpeiger 6eaa992f5f Create SECURITY.md 2024-03-29 22:19:29 +01:00
Speiger 9b23d713ff Started maven publish plugin. 2024-03-29 22:17:38 +01:00
Speiger 85d230c561 Fixed a auto generation bug where iterators wouldn't accept settings 2023-07-04 17:29:32 +02:00
Speiger 6afed5e174 Version Bump 2023-06-29 22:52:44 +02:00
Speiger 640a1a8161 Fixed tests and added missing changelog 2023-06-29 20:04:45 +02:00
Speiger 274d37c4d6 New Features.
-Added: List.indexedIterator which allows you to create a iterator with a customized iteration indecies. Useful if you want to transform lists output.
-Added: PriorityQueue.contains is now a function
-Added: Iterators/Async Builders now support MapToPrimitiveType function on the object variant. So more processing can be done. (Will be expanded upon later versions)
-Updated: SimpleCodeGenerator 1.3.0 is now being used which allows for iterative code support.
2023-06-29 18:30:22 +02:00
Speiger a89c812c06 Added Infinite Iterators 2023-06-17 01:22:56 +02:00
Speiger 6af0656216 Adding coverage to master to make things simpler! 2023-06-15 18:53:08 +02:00
Speiger e76db94136 Upgrading Other dependencies! 2023-06-15 18:31:22 +02:00
Speiger 7011101b05 Upgraded Gradle to be java19/20 friendly 2023-06-15 18:19:12 +02:00
Speiger d0599b99ec Upgraded Build Script and support now java19/20 2023-06-15 18:09:14 +02:00
Speiger d7c5b9ad7d Optimized SelectionSort a tiny bit. 2023-06-15 18:08:57 +02:00
Speiger d2c81e7779 Fixed all the reported issues by the Unit testing. 2023-06-15 17:12:11 +02:00
Speiger ef5fdbd377 Finished Code Cleanup with Compute functions and added ReversedWrappers 2023-06-14 17:40:27 +02:00
Speiger 5e67e45910 Fixed failing tests/errors 2023-06-06 11:21:52 +02:00
Speiger 63ef68fb95 New Compute function and better toArray implementations 2023-06-05 23:40:48 +02:00
Speiger 0f9751bf70 Fixed that setValue wasn't working with ForEach implementations. 2023-05-18 23:02:27 +02:00
Speiger bcc2ffdc13 New features.
-Added: Improved Map documentation for compute methods
-Added: Dedicated toArray implementations to TreeSets
2023-05-17 09:58:55 +02:00
Speiger 2da4588430 Added getFirst/getLast/removeFirst/removeLast to lists 2023-05-17 09:20:45 +02:00
Speiger ed9ce60af4 Small Fixes to doc and Useless Imports 2023-05-17 09:01:09 +02:00
Speiger 4dd3a4a6e8 0.8.0 Release 2022-12-20 09:33:26 +01:00
Speiger efd29bbe7e First draft of the 0.8.0 patch. 2022-12-19 16:03:43 +01:00
Speiger 96458bd8b6 Changes:
- Added: RandomGenerator support (Java17), though requires self
compilation
- Added: Optimizations for HashUtils next power of function.
- Added: toArray() now returns a cached empty array if the collection is
empty.
- Added: toArray function for AsyncBuilder
- Updated: SCG to version 1.2.2
2022-12-16 18:17:51 +01:00
Speiger 477f3c9f40 Implemented ForEachIndexed into all collections 2022-12-16 13:03:28 +01:00
Speiger 3f6e7fbb88 Added forEachIndexed 2022-12-15 20:08:33 +01:00
Speiger 5650c6e69b Fixed tests don't force generate 2022-12-15 18:28:00 +01:00
Speiger 61df32b7b2 Fixed unit tests and java 8 incompat. 2022-12-15 18:10:59 +01:00
Speiger 859d00da16 Fixed Java9 or newer issues. 2022-12-15 17:13:34 +01:00
Speiger 9df95c0fc3 Supplier now uses javas function name. Tests will still fail. 2022-12-15 16:26:05 +01:00
Speiger d6d2c0a396 Changed that function names are closer to javas names. 2022-12-15 16:07:44 +01:00
Speiger 127eb71968 Massive refactor.
-Changed: Classes that used Primitive Collections Functions now use Java functions if possible to increase compat.
-Changed: Started that functions go closer to javas naming sceme.
2022-12-14 18:32:04 +01:00
Speiger 6005d0fd39 Updated SCG to version 1.2.1
This fixes that all expressions are supported.
2022-12-13 13:34:11 +01:00
Speiger 290e626f07 Updated to SCG 1.2.0 2022-12-13 13:07:24 +01:00
Speiger e30d011273 Fixed Unit Test and Added putIfAbsentTest 2022-12-08 10:40:21 +01:00
Speiger 4c52636c23 Fixed Unit Tests 2022-12-07 08:22:45 +01:00
Speiger aa580c1772 Merged branches hopefully 2022-12-07 07:36:25 +01:00
Speiger 8f7d49b280 Finished Function module and added breaking change. 2022-12-07 07:31:30 +01:00
Speiger 342b0cece9 Collection Module Works now. (Least Configurable for obvious Reasons) 2022-12-07 06:27:47 +01:00
Speiger 3ce52668df Added Priority Queue Module 2022-12-07 05:30:23 +01:00
Speiger ce9343348e Pair Module is now done. 2022-12-07 04:35:29 +01:00
Speiger 8d9f7a6761 Improved Settings a bit.
-Added: "Implementations" configuration to turn of all "Implementations" keeping the interfaces/wrappers/abstract classes. Reducing the amount of configurations that need to be set.
-Changed: removed "Sets/Maps/Lists" configuration and replaced it with "Wrappers" since they are wrappers.
-Changed: Category Specific settings (except "Enabled") is sorted by Name.
2022-12-07 04:07:11 +01:00
Speiger 1b1ec4b87a Improving Dependency Checks to be more recursive. 2022-12-07 03:30:59 +01:00
Speiger cc92ef953a Added Dependency Checks into the Module System.
Why a Dependency Check system was added?
2022-12-07 03:23:19 +01:00
Speiger 8d8c30c9a7 Finishing the Set configuration. 2022-12-07 02:50:42 +01:00
Speiger d44ad2d42e 99% of the Set Module done.
The 1% is the Distinct Iterator that relies on a Set implementation.
So I have to make a dedicated set implementation.
2022-12-06 04:57:43 +01:00
Speiger 2ed090e989 Fixed a few bugs and Started the Set compilation. 2022-12-06 04:09:40 +01:00
Speiger dafb162797 Fixed a small bug where generic types can not be disabled. 2022-12-06 03:21:48 +01:00
Speiger 57280b8285 Map Generation can now be turned off. 2022-12-06 03:05:58 +01:00
Speiger c9fc963670 Few changes.
-Removed: BooleanSet classes are gone. (Unused anyways)
-Removed: Boolean2xMaps are also now gone. (Unused Anyways)
-Added: GlobalFlags that are shared across packages.
2022-12-05 07:10:53 +01:00
Speiger cc87cae145 Implemented Lists can now be Disabled
Each List implementation can be now turned off.
Or all Lists can be turned off.
ListIterator can't be turned of since it is a IndexBasedIterator and not
a List and a few implementation use them.
2022-12-05 00:01:53 +01:00
Speiger f53d61a5bc Fixed bug in the module generator config. 2022-12-04 08:00:31 +01:00
Speiger b29874189c Finishing Framework and making Async Module Optional. 2022-12-04 07:56:04 +01:00
Speiger 6722f399db Implemented Module Configuration 2022-12-02 22:36:34 +01:00
Speiger 8e39acef45 Finished adding the modules and implemented sorting algorythm.
That this works is crazy...
2022-11-29 14:33:16 +01:00
Speiger b065ebe9ba Start of the Modularization
-Added: Base code to modularize the project.
-Added: Javas Base Module.
2022-11-27 13:16:21 +01:00
Speiger 25a7cd060a The beginning of modulizing Primitive Collections.
This will be a small rewrite of the "Builder".
Why this is done?
Basically this library is really big and having the Option to turn of
modules that you don't need is really important.

And right now enabling/disabling modules is really difficult since
everything is merged together.

So the first goal is to modularized where everything can be turned on or
of as wished.
2022-11-21 06:45:07 +01:00
Speiger 21f330260e The beginning of modulizing Primitive Collections.
This will be a small rewrite of the "Builder".
Why this is done?
2022-11-21 06:39:22 +01:00
Speiger 99e9afe7b1 Started working on the next patch.
- Added: ISizeProvider interface (Optimization Helper)
- Added: ISizeProvider into most Iterable implementations
(Distinct/Filter/FlatMap/ArrayFlatMap don't support it, for obvious
reasons)
- Added: ToArray function into Iterable which uses ISizeProvider to
reduce overhead of duplicating arrays.
- Fixed: putIfAbsent now replaces defaultValues
2022-11-20 08:56:23 +01:00
Speiger 5118ae8b1f Small Publish action fix.
-Fixed: Renamed files to junit_files since the original is deprecated
2022-07-16 05:00:50 +02:00
Speiger 03b23f0e3c Added New Iterable Feature
-Added: Repeating iterable/iterator/async feature which allows to repeate collections a desired amount of times.
-Added: Tests for it.
2022-07-16 05:00:22 +02:00
Speiger ca33c9eb9e Upgrading to TestResult Publish V2 2022-07-16 04:02:45 +02:00
Speiger b4374fdd4d Reverting build scripts because done with it. 2022-07-06 16:47:15 +02:00
Speiger 455ee64a88 Trying to expand memory a bit. 2022-07-06 14:44:06 +02:00
Speiger 893b371017 Adding a forced delay 2022-07-05 07:51:49 +02:00
Speiger 5fa9baae7a Testing Ram limits 2022-07-04 22:55:27 +02:00
Speiger 70d565c785 Hopefully Fixed setup-java 2022-07-04 22:02:49 +02:00
Speiger 5c27e332cd Attempt on including testruns. 2022-07-02 07:43:18 +02:00
Speiger f2d919bae5 Undoing what i have done so unit tests pass again. 2022-06-21 13:20:34 +02:00
Speiger 7d4c77332b Testing Improved Test Info Generator 2022-06-21 12:08:44 +02:00
Speiger d1186d4f82 Updated Readme and disabled auto sync. 2022-06-14 10:44:02 +02:00
Speiger 3b8a02ac51 Fixed syncer 2022-06-14 09:33:10 +02:00
Speiger f356d4ab57 Trying out a auto sync between branches. 2022-06-14 09:23:20 +02:00
Speiger b07bc85114 Oops 2022-06-14 09:04:38 +02:00
Speiger c37746cd84 Small Fixes
-Fixed: Unit Test Generator is now Silenced. Because 4k lines.
-Fixed: Reverted to JavaSetupV1 for build because java14 support.
-Added: Java18 support for build
2022-06-14 09:03:20 +02:00
Speiger fb7c417394 Refactor of the Project on Github.
-Added: Better System to decide what code should be generated.
-Added: Unit Tests are now included in the main branch.
-Added: Automatic System to test the main branch and ensure that tests work.
-Added: Pull Requests now run tests too.
2022-06-14 08:55:40 +02:00
Speiger ddc58ee221 Version 0.7.0 Release
- Added: Coverage Badge
- Updated: Changelog.
- Changed: Changelog now has info how to obtain the sourcecode.
- Added: Over 11 Million Unit Tests to this library to ensure quality.
- Added: ArrayList size constructor now throws IllegalStateException if
the size parameter is negative
- Added: EnumMap specialized forEach implementation.
- Added: AbstractMap.remove now delegates to its primitive counterpart.
- Added: ConcurrentHashMap now implements ITrimmable
- Refactor: Removed a lot of disabled code from ArraySet.
- Removed: LinkedList.addAll(index, List) now delegates to
LinkedList.addAll(index, Collection) due to no special optimization
required.
- Fixed: AbstractList.SubList.get/set/swapRemove didn't calculate their
List index Properly
- Fixed: AbstractList.SubList chains now properly if you create SubLists
within SubLists.
- Fixed: AbstractList.Iterator.add now respects
Immutable/UnmodifiableLists.
- Fixed: AbstractList.Iterator.skip/back now keep track of the last
returned value for remove function to work properly.
- Fixed: CopyOnWriteArrayList.extract/removeElements(int, int) does now
proper range checks and remove elements properly.
- Fixed: CopyOnWriteArrayList.SubList now works properly. (Reimplemented
entirely)
- Fixed: CopyOnWriteArrayList.Iterator.previous() was returning the
wrong values.
- Fixed: CopyOnWriteArrayList.Iterator.skip now skips the right amount
of elements and stops where it should.
- Fixed: LinkedList.first/last/dequeue/dequeueLast now throws
NoSuchElementException when empty instead of IllegalStateException.
- Fixed: LinkedList had an edge case where the entire reverse iterator
would break if the wrong element was removed.
- Fixed: LinkedList.extractElement now returns the correct values.
- Fixed: AbstractMap.entrySet().remove(Object) now returns true if
defaultReturnValue elements were removed.
- Fixed: ConcurrentHashMap.remove(Object, Object) checks if the type
matches before comparing against null Values.
- Fixed: LinkedHashMap.clearAndTrim() was checking the wrong value for
determining the full reset or clearing of a Map.
- Fixed: HashMap.trim/clearToTrim() was using the wrong value to
determin if something should be done.
- Fixed: HashMap now compares empty values (0) against nullKeys when
Object Variants of the type are used.
- Fixed: ImmutableMap now compares empty values (0) against nullKeys
when Object Variants of the type are used.
- Fixed: ArrayMap.iterator(key) now throws NoSuchElementException when
the element wasn't found.
- Fixed: Linked/EnumMap array constructor was creating the wrong size
values array.
- Fixed: LinkedEnumMap.getAndMoveToFirst/Last was moving elements even
if the element wasn't present.
- Fixed: AVL/RBTreeMap.getFirst/LastKey was not throwing a
NoSuchElementException if the map was empty.
- Fixed: Map.Builder wasn't throwing a IllegalStateException when
creating a negative size builder.
- Fixed: AVL/RBTreeSet.DecendingSet.subSet(from, fromInclusive, to,
toInclusive) was creating a corrupt asending subset.
- Fixed: ArraySet throws now a IllegalStateException when trying to
create it with a negative size.
- Fixed: ArraySet.addMoveToLast(key) was crashing when a key was already
present.
- Fixed: Immutable/LinkedHashSet now keep track of their iteration index
properly.
- Fixed: LinkedHashSet.moveToFirst/Last(key) would crash if the Set was
empty.
- Fixed: LinkedHashSet.clearAndTrim() was checking the wrong value for
determining the full reset or clearing of a Map.
- Fixed: HashSet.trim/clearToTrim() was using the wrong value to
determin if something should be done.
2022-06-12 14:31:45 +02:00
Speiger 8b5e5a75c1 Fixing bugs found when implementing Bidirectional Iterator unit tests.
-Fixed: AbstractList/ImmutableList/ArraySet/ArrayMap skip/back implementation was causing crashes and didn't update the last returned value.
-Fixed: ArraySet/ArrayMap previous was not subtracting before returning value.
-Fixed: BidirectionalIterator back was calling the object variant instead of the TypeSpecific Variant.
-Fixed: TreeSets/Maps Iterator now fully supports backwards Iterating.
-Added: Specialized skip/back function to improve speed in ImmutableHashSet/LinkedHashSet/CustomLinkedHashSet
2022-06-04 21:05:31 +02:00
Speiger c1862e6b05 Fixed a Few bugs with wrappers.
-Fixed: Maps.EmptyMap getOrDefault wasn't returning the default value.
-Fixed: Maps.UnmodifiableMap wasn't respecting the change of the DefaultReturnValue. (it has its own version of it so it doesn't break the rule of it, it wasn't returning the expected value.
-Added: A bunch of Methods for Unmodifiable/Empty maps that should fail right out but would still make it past a certain point. (Compute/Merge/Supply/etc)
2022-06-03 14:38:56 +02:00
Speiger c2c2780967 MapFixes found with unit tests.
-Fixed: CollectionWrapper.equals wasn't accounting for self.
-Fixed: MapWrapper.get didn't account for that it was a wrapper.
-Fixed: UnmodifiableMapWrapper was linking to synchronized maps due to a unknown reason.
-Added: UnmodifiableMapWrapper now has a lot more functions it right out says unsupported instead of indirect ways.
2022-06-02 16:21:48 +02:00
Speiger 086d933a0d Small fixes
-Fixed: NavigableMap.keySet is now a NavigableSet instead of a sorted one.
-Started: Trying to fix wrappers.
2022-06-02 14:59:39 +02:00
Speiger 1e7da394a1 Fixed Bugs found with wrapper collections
-Fixed: AbstractCollection.Iterator was changing the pointer before validating if the element was added. (ImmutableLists)
-Fixed: EmptyCollections containsAll should return true if it is compared against a emptyCollection.
-Fixed: HashCode/Equals for the Lists/Sets implementations.
-Changed: Iterators.wrap(Array) allows now dynamic arrays.
2022-06-02 11:02:19 +02:00
Speiger 9eb220194f Small fixes.
-Fixed: SynchronizedList.addElements was calling itself.
-Fixed: UnmodifiableSet was missing implementations that were causing fails.
2022-06-02 00:47:05 +02:00
Speiger 0baf141e4b New Snapshot builds xD 2022-05-31 19:27:20 +02:00
Speiger 569d4f5c86 Small Fix
-Fixed: HashSet/Map.reduce was using size to iterate instead of array.length
2022-05-31 19:05:54 +02:00
Speiger 36f24731b0 Script Cleanup, Changelog Update and Version Bump.
Added a lot of Unit Tests (Roughly 7 Million) to Primitive Collections
(look Debug Branch) and found some really big bugs.
The Coverage was moved from 1.9% to 34.7% so far.
So there were a lot bugs found and at this point I need a break so this
is the first fixpatch until new tests are added.
2022-05-28 23:34:37 +02:00
Speiger ea5ace0166 Another Coverage Try 2022-05-28 20:32:15 +02:00
Speiger 663809ff27 another test 2022-05-28 20:11:00 +02:00
Speiger 5d6adb5446 Added Jacoco reports 2022-05-28 19:58:54 +02:00
Speiger 212ad1ace2 Add coverage test 2022-05-28 19:56:28 +02:00
Speiger 707827929a Updated version number 2022-05-27 21:21:11 +02:00
Speiger 27ad01657d More fixes from Unit tests.
-Fixed: ArrayList/LinkedList extractElements crashing when 0 or less elements are desired.
-Fixed: TreeMap pollFirst/LastKey should return the defaultMin/max value instead of a Empty value.
-Fixed: TreeMap keySet implementation was missing the class type implementations to pass keySet tests.
-Fixed: TreeMap.SubMap Iterator (primitive Keys) was crashing because a Null was set on to a primitive.
2022-05-27 16:35:41 +02:00
Speiger e7da7acc08 Started massive unit testing library these are the first fixes.
-Fixed: AbstractCollection.retainAll didn't push removed values through the consumer.
-Fixed: AbstractCollection.toArray wouldn't reset the last entry if the input array was larger then the elements in the collection.
-Fixed: SubList didn't check for ranges properly or didn't use parent list to validate changes.
-Fixed: ArrayList.addElements didn't check input array fully and used the wrong variable to move the elements around.
-Fixed: LinkedList.addElements(EmptyInput) would crash.
-Fixed: LinkedList.swapRemove didn't account for if the removed element was the prelast one.
-Fixed: LinkedList.removeElements would break the implementation if the list was almost empty and the middle element was removed.
-Fixed: LinkedHashSet.addAndMoveToFirst wouldn't move elements to the first place.
2022-05-22 15:13:29 +02:00
Speiger 72943cb22c Added AsyncBuilder for arrays 2022-05-17 18:10:07 +02:00
Speiger 068cc4a4f7 Fixed Bugs with Java Iterators not throwing the correct exception. 2022-05-17 10:45:05 +02:00
Speiger 31b34f5de1 Fixed a couple bugs.
-Fixed: TreeMap.subMap().entrySet().remove() wouldn't check primitives properly.
-Fixed: SortedMap.sub/tail/headMap were looping into themselves.
-Changed: LinkedList.addBulk variable definition was triggering a false positive.
2022-05-17 07:59:57 +02:00
Speiger 4bded1af80 Small Change to sorting
-Added: Array only sorting function return the inputed array. This was done to allow for static final references to use the method in one go without having to make lambda wrappers. Cleaner code.
2022-04-30 22:41:11 +02:00
Speiger 100c7fe260 Updated yml Scripts
-Updated: yml Scripts and ReadMe since the gradle setup no longer requires 2 commands to work properly.
2022-04-28 19:09:42 +02:00
289 changed files with 70143 additions and 39985 deletions
+33
View File
@@ -0,0 +1,33 @@
name: Latest Build
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
strategy:
fail-fast: false
matrix:
jdk: [8, 11, 16, 17, 18, 19, 20]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ matrix.jdk }}
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Build with Gradle
run: ./gradlew build
+84
View File
@@ -0,0 +1,84 @@
name: Unit Tests
on:
push:
branches: [ master ]
jobs:
build:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- 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 Test
run: |
./gradlew generateTestSource test jacocoTestReport --info -Dfull_test_suite=true
./gradlew --stop
- name: Publish Test Result
uses: EnricoMi/publish-unit-test-result-action@v2
id: test-results
if: always()
with:
junit_files: build/test-results/**/*.xml
fail_on: nothing
ignore_runs: true
json_thousands_separator: .
time_unit: milliseconds
- name: Create Badge Color
shell: bash
run: |
case ${{ fromJSON( steps.test-results.outputs.json ).conclusion }} in
success)
echo "BADGE_COLOR=31c653" >> $GITHUB_ENV
;;
failure)
echo "BADGE_COLOR=800000" >> $GITHUB_ENV
;;
neutral)
echo "BADGE_COLOR=696969" >> $GITHUB_ENV
;;
esac
- name: Create Test Badge
uses: emibcn/badge-action@v1.2.4
with:
label: Tests
status: '${{ fromJSON( steps.test-results.outputs.json ).conclusion }}, Passed: ${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.tests_succ }}, Skipped: ${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.tests_skip }}, Failed: ${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.tests_fail }}'
color: ${{ env.BADGE_COLOR }}
path: tests.svg
- name: Create Coverage Badge
id: jacoco
uses: cicirello/jacoco-badge-generator@v2
with:
jacoco-csv-file: build/reports/jacoco/test/jacocoTestReport.csv
badges-directory: null
intervals: 95 80 70 60 50 0
- name: Upload Test Badge
uses: exuanbo/actions-deploy-gist@v1
with:
token: ${{ secrets.GIST_TOKEN }}
gist_id: 280257cd19cbe1dda3789bebd4ff65cf
file_path: tests.svg
- name: Upload Coverage Badge
uses: exuanbo/actions-deploy-gist@v1
with:
token: ${{ secrets.GIST_TOKEN }}
gist_id: 280257cd19cbe1dda3789bebd4ff65cf
file_path: jacoco.svg
-38
View File
@@ -1,38 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Latest Build
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
strategy:
fail-fast: false
matrix:
jdk: [8, 11, 14, 16, 17]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.jdk }}
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Generate SourceCode with Gradle
run: ./gradlew generateGithubSource
- name: Build with Gradle
run: ./gradlew build
+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
@@ -0,0 +1,39 @@
name: Unit Tests
on:
pull_request:
branches: [ master ]
jobs:
build:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- 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 Test
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew generateTestSource test jacocoTestReport --info -Dfull_test_suite=true
- name: Publish Test Result
uses: EnricoMi/publish-unit-test-result-action@v2
id: test-results
if: always()
with:
junit_files: build/test-results/**/*.xml
fail_on: nothing
ignore_runs: true
json_thousands_separator: .
time_unit: milliseconds
+14
View File
@@ -30,5 +30,19 @@ gradle-app.setting
/src/main/java/speiger/src/collections/doubles/* /src/main/java/speiger/src/collections/doubles/*
/src/main/java/speiger/src/collections/objects/* /src/main/java/speiger/src/collections/objects/*
#Generated Tests
/src/test/java/speiger/src/testers/booleans/*
/src/test/java/speiger/src/testers/bytes/*
/src/test/java/speiger/src/testers/shorts/*
/src/test/java/speiger/src/testers/chars/*
/src/test/java/speiger/src/testers/ints/*
/src/test/java/speiger/src/testers/longs/*
/src/test/java/speiger/src/testers/floats/*
/src/test/java/speiger/src/testers/doubles/*
/src/test/java/speiger/src/testers/objects/*
/src/test/java/speiger/src/tests/*
#Cache result #Cache result
/src/builder/resources/speiger/assets/collections/cache.bin /src/builder/resources/speiger/assets/collections/cache.bin
/src/builder/resources/speiger/assets/testers/cache.bin
/src/builder/resources/speiger/assets/tests/cache.bin
+116
View File
@@ -1,5 +1,121 @@
# Changelog of versions # Changelog of versions
### Version 0.9.0
- 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.
- Breaking Change: Map.compute/IfAbsent/Present and Map.supplyIfAbsent if the value is a primitive it will no longer accept the defaultReturnValue() as "null" if that functionality is desired then use: computeNonDefault which contains the functionality!
### Version 0.8.1
- Added: getFirst/getLast/removeFirst/removeLast to List.class.
- Added: Dedicated Set toArray implementations.
- Added: ToArray/pushTop functions to Stack.class.
- Added: ComputeNonDefault functions which will contain the current behavior of the Compute function, while the Compute will be changed to be more java compliant!
- Added: List.reversed, which returns a SubList that has all elements in reversed order and also inserts reversed.
- Added: Iterators.infinite as an option that will create a Infinite Iterator based on the inputed one.
- Added: List.indexedIterator which allows you to create a iterator with a customized iteration indecies. Useful if you want to transform lists output.
- Added: PriorityQueue.contains is now a function
- Added: Iterators/Async Builders now support MapToPrimitiveType function on the object variant. So more processing can be done. (Will be expanded upon later versions)
- Fixed: SetValue wasn't working on forEach implementations.
- Fixed: Compute functions now perform with primitives more java compliant. Meaning that getDefaultReturnValue function no longer is seen as null.
- Fixed: Supplier was using the wrong dataType in their function name.
- Updated: SimpleCodeGenerator 1.3.0 is now being used which allows for iterative code support.
### Version 0.8.0
- Added: getFirst/getLast/removeFirst/removeLast to Lists
- Added: Dedicated implementations for toArray into TreeSets
- Fixed: forEach methods in Maps now can use "setValue" functions.
### Version 0.8.0
- Added: ISizeProvider interface (Optimization Helper)
- Added: ISizeProvider into most Iterable implementations (Distinct/Filter/FlatMap/ArrayFlatMap don't support it, for obvious reasons)
- Added: ToArray function into Iterable which uses ISizeProvider to reduce overhead of duplicating arrays.
- Added: Functions that have the same type, Int2IntFunction as example, have now a identity function.
- Added: Functions of a BooleanValue have now alwaysTrue/False function.
- Added: ForEachIndexed for all Iterable implementations
- Added: RandomGenerator support (Java17), though requires self compilation
- Added: Optimizations for HashUtils next power of function.
- Added: toArray() now returns a cached empty array if the collection is empty.
- Added: toArray function for AsyncBuilder
- Added: Modularization to the library where feature can be disabled as needed. (Requires Self-Compilation)
- Fixed: putIfAbsent now replaces defaultValues
- Fixed: OpenHashSet/Map and their Custom Variants no longer rely on List implementations.
- Fixed: ObjectCopyOnWriteList.of did create a ObjectArrayList instead of the CopyOnWrite variant.
- Removed: BooleanSet and Maps that start with a Boolean classes since they can not be used anyways.
- Breaking Change: Function classes now use the "apply/applyAs/test" format from Java itself, instead of the "get" format. This cleans up a lot of things. But will break existing function class implementations
- Breaking Change: Classes that used PrimitiveCollection functions now default to java functions where applicable, this is to increase compat.
- Breaking Change: Some function classes now get closer to javas terms. (Predicate/UnaryOperator etc)
### Version 0.7.0
- Added: Over 11 Million Unit Tests to this library to ensure quality.
- Added: ArrayList size constructor now throws IllegalStateException if the size parameter is negative
- Added: EnumMap specialized forEach implementation.
- Added: AbstractMap.remove now delegates to its primitive counterpart.
- Added: ConcurrentHashMap now implements ITrimmable
- Refactor: Removed a lot of disabled code from ArraySet.
- Removed: LinkedList.addAll(index, List) now delegates to LinkedList.addAll(index, Collection) due to no special optimization required.
- Fixed: AbstractList.SubList.get/set/swapRemove didn't calculate their List index Properly
- Fixed: AbstractList.SubList chains now properly if you create SubLists within SubLists.
- Fixed: AbstractList.Iterator.add now respects Immutable/UnmodifiableLists.
- Fixed: AbstractList.Iterator.skip/back now keep track of the last returned value for remove function to work properly.
- Fixed: CopyOnWriteArrayList.extract/removeElements(int, int) does now proper range checks and remove elements properly.
- Fixed: CopyOnWriteArrayList.SubList now works properly. (Reimplemented entirely)
- Fixed: CopyOnWriteArrayList.Iterator.previous() was returning the wrong values.
- Fixed: CopyOnWriteArrayList.Iterator.skip now skips the right amount of elements and stops where it should.
- Fixed: LinkedList.first/last/dequeue/dequeueLast now throws NoSuchElementException when empty instead of IllegalStateException.
- Fixed: LinkedList had an edge case where the entire reverse iterator would break if the wrong element was removed.
- Fixed: LinkedList.extractElement now returns the correct values.
- Fixed: AbstractMap.entrySet().remove(Object) now returns true if defaultReturnValue elements were removed.
- Fixed: ConcurrentHashMap.remove(Object, Object) checks if the type matches before comparing against null Values.
- Fixed: LinkedHashMap.clearAndTrim() was checking the wrong value for determining the full reset or clearing of a Map.
- Fixed: HashMap.trim/clearToTrim() was using the wrong value to determin if something should be done.
- Fixed: HashMap now compares empty values (0) against nullKeys when Object Variants of the type are used.
- Fixed: ImmutableMap now compares empty values (0) against nullKeys when Object Variants of the type are used.
- Fixed: ArrayMap.iterator(key) now throws NoSuchElementException when the element wasn't found.
- Fixed: Linked/EnumMap array constructor was creating the wrong size values array.
- Fixed: LinkedEnumMap.getAndMoveToFirst/Last was moving elements even if the element wasn't present.
- Fixed: AVL/RBTreeMap.getFirst/LastKey was not throwing a NoSuchElementException if the map was empty.
- Fixed: Map.Builder wasn't throwing a IllegalStateException when creating a negative size builder.
- Fixed: AVL/RBTreeSet.DecendingSet.subSet(from, fromInclusive, to, toInclusive) was creating a corrupt asending subset.
- Fixed: ArraySet throws now a IllegalStateException when trying to create it with a negative size.
- Fixed: ArraySet.addMoveToLast(key) was crashing when a key was already present.
- Fixed: Immutable/LinkedHashSet now keep track of their iteration index properly.
- Fixed: LinkedHashSet.moveToFirst/Last(key) would crash if the Set was empty.
- Fixed: LinkedHashSet.clearAndTrim() was checking the wrong value for determining the full reset or clearing of a Map.
- Fixed: HashSet.trim/clearToTrim() was using the wrong value to determin if something should be done.
### Version 0.6.2
- Added: Array only sorting function return the inputed array. This was done to allow for static final references to use the method in one go without having to make lambda wrappers. Cleaner code.
- Added: Iterator Wrappers are now a bit more in Compliance with Java Standards.
- Added: AsyncBuilders now Support Array Inputs to create cleaner code.
- Changed: LinkedList.addBulk variable definition was triggering a false positive.
- Fixed: TreeMap.subMap().entrySet().remove() wouldn't check primitives properly.
- Fixed: SortedMap.sub/tail/headMap were looping into themselves.
- Fixed: AbstractCollection.retainAll didn't push removed values through the consumer.
- Fixed: AbstractCollection.toArray wouldn't reset the last entry if the input array was larger then the elements in the collection.
- Fixed: SubList didn't check for ranges properly or didn't use parent list to validate changes.
- Fixed: ArrayList.addElements didn't check input array fully and used the wrong variable to move the elements around.
- Fixed: LinkedList.addElements(EmptyInput) would crash.
- Fixed: LinkedList.swapRemove didn't account for if the removed element was the prelast one.
- Fixed: LinkedList.removeElements would break the implementation if the list was almost empty and the middle element was removed.
- Fixed: LinkedHashSet.addAndMoveToFirst wouldn't move elements to the first place.
- Fixed: ArrayList/LinkedList extractElements crashing when 0 or less elements are desired.
- Fixed: TreeMap pollFirst/LastKey should return the defaultMin/max value instead of a Empty value.
- Fixed: TreeMap keySet implementation was missing the class type implementations to pass keySet tests.
- Fixed: TreeMap.SubMap Iterator (primitive Keys) was crashing because a Null was set on to a primitive.
### Version 0.6.1 ### Version 0.6.1
- Fixed: FIFO queue crashing when the last index is before the first index when peek is called. - Fixed: FIFO queue crashing when the last index is before the first index when peek is called.
- Fixed: FIFO queue only clears the array if it was in use. - Fixed: FIFO queue only clears the array if it was in use.
+44
View File
@@ -0,0 +1,44 @@
### Extra Features
Primitive Collections comes with a few extra features that are disabled by default.
These will be enabled as soon they become relevant or never at all.
But some of these can be already unlocked when the target version changes.
If you compile the library for yourself you will automatically gain access to said features.
### Java17 Exclusive Features
Java17 has some new features that can sadly not really be back-ported but the library still supports them if it is compiled with java17
- RandomGenerator: Java17 has added [RandomGenerator.class](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/random/RandomGenerator.html).
This allows to use custom random implementations without having to re-implement them yourselves.
### ModuleSettings
Primitive Collections is a huge library.
But maybe you only use like 5-10 different classes.
Normally you would use tools like "Proguard" to get rid of classes that you don't use.
But since a lot of classes have dependencies on each other this would only do so much.
This is where the [ModuleSettings](ModuleSettings.json) come into play.
It allows you to turn of implementations as you wish and adjusts the code that everything still works.
There is 3 layers of control inside of the ModuleSettings.
- Modules directly at the top that turn off everything.
- Type Specific configurations, where you can for example turn of everything thats "Long" based.
- And then there is each type specific module settings.
Allowing for greater control without having to edit hundreds of lines of code.
On top of that:
Any Setting that isn't "Present" can be defined as "Enabled" or "Disabled" using the "Default" argument.
If "Default" is missing, then it will just default to "Enabled".
So if you want to disable just 1 thing you can keep that 1 thing and delete the rest of the Setting.
It will still work as the same.
The default settings just come with everything so you can see what is controllable.
Note: If a global Module setting is disabled but a dependency needs said Module, it will enable only the required classes.
If a Module type (Float-Collection as example) is specifically disabled, the Dependency Resolver will throw errors telling you whats wrong.
How to compile the Code with the ModuleSettings enabled:
```
/gradlew.bat generateLimitSource build -x test
```
+2625
View File
File diff suppressed because it is too large Load Diff
+25 -35
View File
@@ -1,7 +1,12 @@
![build](https://github.com/Speiger/Primitive-Collections/actions/workflows/build_validator.yml/badge.svg) ![build](https://github.com/Speiger/Primitive-Collections/actions/workflows/build_action.yml/badge.svg)
[![Latest Release](https://jitpack.io/v/Speiger/Primitive-Collections.svg)](https://jitpack.io/#Speiger/Primitive-Collections) [![Latest Release](https://jitpack.io/v/Speiger/Primitive-Collections.svg)](https://jitpack.io/#Speiger/Primitive-Collections)
![Maven Central Version](https://img.shields.io/maven-central/v/io.github.speiger/Primitive-Collections)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
![GitHub commit activity](https://img.shields.io/github/commit-activity/m/Speiger/Primitive-Collections) ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/Speiger/Primitive-Collections)
![Unit Tests](https://github.com/Speiger/Primitive-Collections/actions/workflows/build_tests_action.yml/badge.svg)
![Coverage](https://gist.githubusercontent.com/Speiger/280257cd19cbe1dda3789bebd4ff65cf/raw/405abd1d2f6c19ac70f20b8b1772176f42d5c5d3/jacoco.svg)
[![codecov](https://codecov.io/gh/Speiger/Primitive-Collections/branch/debug/graph/badge.svg?token=WSTSNJM0EN)](https://codecov.io/gh/Speiger/Primitive-Collections)
![Tests Done](https://gist.githubusercontent.com/Speiger/280257cd19cbe1dda3789bebd4ff65cf/raw/405abd1d2f6c19ac70f20b8b1772176f42d5c5d3/tests.svg)
# Primitive-Collections # Primitive-Collections
This is a Simple Primitive Collections Library aimed to outperform Java's Collection Library and FastUtil. This is a Simple Primitive Collections Library aimed to outperform Java's Collection Library and FastUtil.
Both in Performance and Quality of Life Features. Both in Performance and Quality of Life Features.
@@ -13,6 +18,10 @@ Benchmarks can be found here: [[Charts]](https://github.com/Speiger/Primitive-Co
[Here](features.md) you find a set of features added to Primitive Collections. [Here](features.md) you find a set of features added to Primitive Collections.
These are designed to improve performance or to provide Quality of Life. These are designed to improve performance or to provide Quality of Life.
[Here](EXTRAS.md) you also find features that can be used when you compile the library for yourself.
These features are not used by default to have a wider range of compat, or require self compilation.
Such as pruning classes that are not needed in your code.
## Main Features: ## Main Features:
- ArrayLists / LinkedLists / CopyOnWriteLists - ArrayLists / LinkedLists / CopyOnWriteLists
- HashSets/Maps (Linked & HashControl) - HashSets/Maps (Linked & HashControl)
@@ -35,50 +44,28 @@ To ensure that problems can be dealt with even if it is breaking the current API
# How to install # How to install
Using Jitpack Gradle Using Jitpack Gradle
```gradle ```groovy
repositories { repositories {
maven { maven {
url = "https://jitpack.io" url = "https://jitpack.io"
} }
} }
dependencies { dependencies {
implementation 'com.github.Speiger:Primitive-Collections:0.6.1' implementation 'com.github.Speiger:Primitive-Collections:0.9.0'
} }
``` ```
Using Custom Gradle:
```gradle Using Maven Central
repositories { ```groovy
maven {
url = "https://maven.speiger.com/repository/main"
}
}
dependencies { dependencies {
implementation 'de.speiger:Primitive-Collections:0.6.1' implementation 'io.github.speiger:Primitive-Collections:0.9.0'
} }
``` ```
<details> # SourceCode
<summary>Direct: </summary> The generated Sourcecode can be automatically build,
<p> but if you want to just browse around in it.
Check out the [Debug Branch](https://github.com/Speiger/Primitive-Collections/tree/debug/src/main/java/speiger/src/collections), which has the entire up to date code.
| Version | Jar | Sources | Java Doc |
|--------- |------------------------------------------------------------------------------------------------------------------------------ |-------------------------------------------------------------------------------------------------------------------------------------- |-------------------------------------------------------------------------------------------------------------------------------------- |
| 0.6.1 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.1/Primitive-Collections-0.6.1.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.1/Primitive-Collections-0.6.1-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.1/Primitive-Collections-0.6.1-javadoc.jar) |
| 0.6.0 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.0/Primitive-Collections-0.6.0.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.0/Primitive-Collections-0.6.0-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.6.0/Primitive-Collections-0.6.0-javadoc.jar) |
| 0.5.3 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.3/Primitive-Collections-0.5.3.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.3/Primitive-Collections-0.5.3-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.3/Primitive-Collections-0.5.3-javadoc.jar) |
| 0.5.2 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.2/Primitive-Collections-0.5.2.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.2/Primitive-Collections-0.5.2-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.2/Primitive-Collections-0.5.2-javadoc.jar) |
| 0.5.1 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.1/Primitive-Collections-0.5.1.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.1/Primitive-Collections-0.5.1-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.1/Primitive-Collections-0.5.1-javadoc.jar) |
| 0.5.0 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.0/Primitive-Collections-0.5.0.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.0/Primitive-Collections-0.5.0-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.5.0/Primitive-Collections-0.5.0-javadoc.jar) |
| 0.4.5 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.5/Primitive-Collections-0.4.5.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.5/Primitive-Collections-0.4.5-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.5/Primitive-Collections-0.4.5-javadoc.jar) |
| 0.4.4 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.4/Primitive-Collections-0.4.4.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.4/Primitive-Collections-0.4.4-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.4/Primitive-Collections-0.4.4-javadoc.jar) |
| 0.4.3 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.3/Primitive-Collections-0.4.3.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.3/Primitive-Collections-0.4.3-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.3/Primitive-Collections-0.4.3-javadoc.jar) |
| 0.4.2 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.2/Primitive-Collections-0.4.2.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.2/Primitive-Collections-0.4.2-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.2/Primitive-Collections-0.4.2-javadoc.jar) |
| 0.4.1 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.1/Primitive-Collections-0.4.1.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.1/Primitive-Collections-0.4.1-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.1/Primitive-Collections-0.4.1-javadoc.jar) |
| 0.4.0 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.0/Primitive-Collections-0.4.0.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.0/Primitive-Collections-0.4.0-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.0/Primitive-Collections-0.4.0-javadoc.jar) |
| 0.3.6 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.3.6/Primitive-Collections-0.3.6.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.3.6/Primitive-Collections-0.3.6-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.3.6/Primitive-Collections-0.3.6-javadoc.jar) |
</p>
</details>
# Contributing # Contributing
If you want to contribute. If you want to contribute.
@@ -96,8 +83,11 @@ Please if you want to contribute follow the [Rule-Sheet](RuleSheet.md). It keeps
# How to Build # How to Build
The SourceCode can be generated via: The SourceCode can be generated via:
```
/gradlew.bat generateSource /gradlew.bat generateSource
```
to build the jar: to generate SourceCode and build the jar:
```
/gradlew.bat build /gradlew.bat build
do not combine the commands because they can not be executed at the same time. ```
+15
View File
@@ -0,0 +1,15 @@
# Security Policy
## Supported Versions
Due to how the releases work, only the latest versions will be supported.
## Reporting a Vulnerability
If you have discovered a security vulnerability in this project, please report it privately.
**Please refrain from posting in public issues.**
This gives me time to process issues that are being found, and reduces the possiblity of abuse while patches are being created.
Please disclose it [here](https://github.com/Speiger/Primitive-Collections/security/advisories/new).
Please consider that this project is developed by a single person.
So please provide a reasonable timeframe when reporting.
+252 -22
View File
@@ -1,5 +1,7 @@
plugins { plugins {
id 'java-library' id 'java-library'
id "jacoco"
// id "com.vanniktech.maven.publish" version "0.28.0"
} }
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
@@ -9,6 +11,7 @@ tasks.withType(JavaCompile) {
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
apply plugin: 'signing'
repositories { repositories {
mavenCentral() mavenCentral()
@@ -18,12 +21,17 @@ repositories {
} }
archivesBaseName = 'Primitive Collections' archivesBaseName = 'Primitive Collections'
version = '0.6.1'; version = RELEASE_VERSION;
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaVersion.current(); sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaVersion.current();
System.out.println("Java Version: "+compileJava.sourceCompatibility) System.out.println("Java Version: "+compileJava.sourceCompatibility)
java {
withJavadocJar()
withSourcesJar()
}
javadoc { javadoc {
options.tags = [ "implSpec", "note" ] options.tags = [ "implSpec", "note" ]
} }
@@ -44,7 +52,8 @@ configurations {
} }
dependencies { dependencies {
builderImplementation 'de.speiger:Simple-Code-Generator:1.0.7' builderImplementation 'com.google.code.gson:gson:2.10'
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'
@@ -62,7 +71,7 @@ task generateGithubSource(type: JavaExec) {
description = 'Builds the sourcecode for Github Actions' description = 'Builds the sourcecode for Github Actions'
classpath = sourceSets.builder.runtimeClasspath classpath = sourceSets.builder.runtimeClasspath
main = 'speiger.src.builder.PrimitiveCollectionsBuilder' main = 'speiger.src.builder.PrimitiveCollectionsBuilder'
args = ['false', 'true'] args = ['silent']
} }
task forceGenerateSource(type: JavaExec) { task forceGenerateSource(type: JavaExec) {
@@ -70,17 +79,31 @@ task forceGenerateSource(type: JavaExec) {
description = 'Builds the sourcecode forceful' description = 'Builds the sourcecode forceful'
classpath = sourceSets.builder.runtimeClasspath classpath = sourceSets.builder.runtimeClasspath
main = 'speiger.src.builder.PrimitiveCollectionsBuilder' main = 'speiger.src.builder.PrimitiveCollectionsBuilder'
args = ['true'] args = ['force']
} }
task javadocJar(type: Jar) { task generateTestSource(type: JavaExec) {
from javadoc group = 'internal'
classifier = 'javadoc' description = 'Builds the sourcecode for the Tests'
classpath = sourceSets.builder.runtimeClasspath
main = 'speiger.src.builder.PrimitiveCollectionsBuilder'
args = ['tests', 'silent']
} }
task srcJar(type: Jar) { task forceGenerateTestSource(type: JavaExec) {
from sourceSets.main.allSource group = 'internal'
classifier = 'sources' description = 'Builds the sourcecode for the Tests'
classpath = sourceSets.builder.runtimeClasspath
main = 'speiger.src.builder.PrimitiveCollectionsBuilder'
args = ['tests', 'silent', 'force']
}
task generateLimitSource(type: JavaExec) {
group = 'internal'
description = 'Builds the Sourcecode with the ModuleSettings.json applied'
classpath = sourceSets.builder.runtimeClasspath
main = 'speiger.src.builder.PrimitiveCollectionsBuilder'
args = ['silent', 'load']
} }
compileJava.dependsOn generateGithubSource compileJava.dependsOn generateGithubSource
@@ -89,22 +112,159 @@ javadoc.failOnError = false
javadoc.options.memberLevel = JavadocMemberLevel.PUBLIC javadoc.options.memberLevel = JavadocMemberLevel.PUBLIC
javadoc.options.quiet() javadoc.options.quiet()
artifacts {
archives javadocJar task testBooleans(type: Test) {
archives srcJar group 'tests'
description 'Tests all Boolean Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.booleans.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
}
task testBytes(type: Test) {
group 'tests'
description 'Tests all Byte Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.bytes.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
maxParallelForks = testThreads as Integer
}
task testShorts(type: Test) {
group 'tests'
description 'Tests all Short Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.shorts.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
maxParallelForks = testThreads as Integer
}
task testChars(type: Test) {
group 'tests'
description 'Tests all Character Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.chars.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
maxParallelForks = testThreads as Integer
}
task testInts(type: Test) {
group 'tests'
description 'Tests all Int Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.ints.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
maxParallelForks = testThreads as Integer
}
task testLongs(type: Test) {
group 'tests'
description 'Tests all Long Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.longs.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
maxParallelForks = testThreads as Integer
}
task testFloats(type: Test) {
group 'tests'
description 'Tests all Float Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.floats.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
maxParallelForks = testThreads as Integer
}
task testDoubles(type: Test) {
group 'tests'
description 'Tests all Double Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.doubles.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
maxParallelForks = testThreads as Integer
}
task testObjects(type: Test) {
group 'tests'
description 'Tests all Object Collections'
filter {
excludeTestsMatching "speiger.src.testers.**.*"
includeTestsMatching "speiger.src.tests.objects.**.*"
}
useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
maxParallelForks = testThreads as Integer
}
if(System.getProperty("full_test_suite", "false").toBoolean()) {
test.dependsOn testBooleans
test.dependsOn testBytes
test.dependsOn testShorts
test.dependsOn testChars
test.dependsOn testInts
test.dependsOn testLongs
test.dependsOn testFloats
test.dependsOn testDoubles
test.dependsOn testObjects
} }
test { test {
filter {
excludeTestsMatching "speiger.src.testers.**.*"
excludeTestsMatching "speiger.src.tests.**.*"
excludeTestsMatching "tests.**.*"
}
useJUnit() useJUnit()
ignoreFailures = true
maxHeapSize = maxMemory
} }
publishing { jacocoTestReport {
Properties props = new Properties() executionData fileTree(project.buildDir.absolutePath).include("jacoco/*.exec")
if(file("$buildDir/credentials.properties").exists()) { reports {
props.load(new FileInputStream("$buildDir/credentials.properties")) xml.required = true
html.required = true
csv.required = true
} }
}
publishing {
publications { publications {
mavenJava(MavenPublication) { personal(MavenPublication) {
pom { pom {
name = 'Primitive Collections' name = 'Primitive Collections'
description = 'A Primitive Collection library that reduces memory usage and improves performance' description = 'A Primitive Collection library that reduces memory usage and improves performance'
@@ -113,8 +273,6 @@ publishing {
artifactId = project.archivesBaseName.replace(" ", "-") artifactId = project.archivesBaseName.replace(" ", "-")
groupId = 'de.speiger' groupId = 'de.speiger'
from components.java from components.java
artifact tasks.srcJar
artifact tasks.javadocJar
licenses { licenses {
license { license {
name = 'The Apache License, Version 2.0' name = 'The Apache License, Version 2.0'
@@ -139,11 +297,83 @@ publishing {
} }
repositories { repositories {
maven { maven {
name = "Speiger_Maven"
def auth = System.getenv("Speiger_Maven_Auth")?.split(';');
url version.endsWith('SNAPSHOT') ? "https://maven.speiger.com/repository/debug" : "https://maven.speiger.com/repository/main" url version.endsWith('SNAPSHOT') ? "https://maven.speiger.com/repository/debug" : "https://maven.speiger.com/repository/main"
credentials(PasswordCredentials) { credentials(PasswordCredentials) {
username props.mavenUser username auth?[0]
password props.mavenPassword password auth?[1]
} }
} }
} }
} }
tasks.withType(PublishToMavenRepository) {
def predicate = provider {
(repository == publishing.repositories.mavenCentral && publication == publishing.publications.maven) ||
(repository != publishing.repositories.mavenCentral && publication != publishing.publications.maven)
}
onlyIf("publishing binary to the external repository, or binary and sources to the internal one") {
predicate.get()
}
}
tasks.withType(PublishToMavenLocal) {
def predicate = provider {
publication == publishing.publications.personal
}
onlyIf("publishing binary and sources") {
predicate.get()
}
}
//Maven central Start
//Disabling due to java8 incompat, only needed to manually publishing anyways
//signing.useGpgCmd()
//
//import com.vanniktech.maven.publish.SonatypeHost
//import com.vanniktech.maven.publish.JavaLibrary
//import com.vanniktech.maven.publish.JavadocJar
//
//mavenPublishing {
// configure(new JavaLibrary(new JavadocJar.None(), true))
//}
//
//mavenPublishing {
// publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
//
// signAllPublications()
// pom {
// name = 'Primitive Collections'
// description = 'A Primitive Collection library that reduces memory usage and improves performance'
// url = 'https://github.com/Speiger/Primitive-Collections'
// version = project.version
// group = 'io.github.speiger'
// licenses {
// license {
// name = 'The Apache License, Version 2.0'
// url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
// }
// }
//
// developers {
// developer {
// id = 'speiger'
// name = 'Speiger'
// }
// }
//
// scm {
// connection = 'scm:git:git://github.com/Speiger/Primitive-Collections.git'
// developerConnection = 'scm:git:ssh://github.com:Speiger/Primitive-Collections.git'
// url = 'https://github.com/Speiger/Primitive-Collections'
// }
//
// issueManagement {
// system = 'github'
// url = 'https://github.com/Speiger/Primitive-Collections/issues'
// }
// }
//}
//
+5
View File
@@ -1 +1,6 @@
org.gradle.jvmargs=-Xmx3G org.gradle.jvmargs=-Xmx3G
maxMemory = 1024m
testThreads = 4
RELEASE_VERSION = 0.9.0
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
-1
View File
@@ -2,6 +2,5 @@ jdk:
- openjdk9 - openjdk9
install: install:
- chmod +x ./gradlew - chmod +x ./gradlew
- ./gradlew generateGithubSource
- ./gradlew build publishToMavenLocal - ./gradlew build publishToMavenLocal
@@ -3,15 +3,15 @@ package speiger.src.builder;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public enum ClassType public enum ClassType
{ {
BOOLEAN("boolean", "Boolean", "Boolean", "booleans", "BOOLEAN", "false"), BOOLEAN("boolean", "Boolean", "Boolean", "booleans", "BOOLEAN", "false", "false"),
BYTE("byte", "Byte", "Byte", "bytes", "BYTE", "(byte)0"), BYTE("byte", "Byte", "Byte", "bytes", "BYTE", "(byte)0", "(byte)-1"),
SHORT("short", "Short", "Short", "shorts", "SHORT", "(short)0"), SHORT("short", "Short", "Short", "shorts", "SHORT", "(short)0", "(short)-1"),
CHAR("char", "Character", "Char", "chars", "CHAR", "(char)0"), CHAR("char", "Character", "Char", "chars", "CHAR", "(char)0", "(char)-1"),
INT("int", "Integer", "Int", "ints", "INT", "0"), INT("int", "Integer", "Int", "ints", "INT", "0", "-1"),
LONG("long", "Long", "Long", "longs", "LONG", "0L"), LONG("long", "Long", "Long", "longs", "LONG", "0L", "-1L"),
FLOAT("float", "Float", "Float", "floats", "FLOAT", "0F"), FLOAT("float", "Float", "Float", "floats", "FLOAT", "0F", "-1F"),
DOUBLE("double", "Double", "Double", "doubles", "DOUBLE", "0D"), DOUBLE("double", "Double", "Double", "doubles", "DOUBLE", "0D", "-1D"),
OBJECT("T", "T", "Object", "objects", "OBJECT", "null"); OBJECT("T", "T", "Object", "objects", "OBJECT", "null", "null");
String keyType; String keyType;
String classType; String classType;
@@ -19,8 +19,9 @@ public enum ClassType
String pathType; String pathType;
String capType; String capType;
String emptyValue; String emptyValue;
String invalidValue;
private ClassType(String keyType, String classType, String fileType, String pathType, String capType, String emptyValue) private ClassType(String keyType, String classType, String fileType, String pathType, String capType, String emptyValue, String invalidValue)
{ {
this.keyType = keyType; this.keyType = keyType;
this.classType = classType; this.classType = classType;
@@ -28,6 +29,7 @@ public enum ClassType
this.pathType = pathType; this.pathType = pathType;
this.capType = capType; this.capType = capType;
this.emptyValue = emptyValue; this.emptyValue = emptyValue;
this.invalidValue = invalidValue;
} }
public String getKeyType() public String getKeyType()
@@ -50,6 +52,11 @@ public enum ClassType
return classType; return classType;
} }
public String getClassPath()
{
return this == OBJECT ? "Object" : classType;
}
public String getClassType(boolean value) public String getClassType(boolean value)
{ {
return value && this == OBJECT ? "V" : classType; return value && this == OBJECT ? "V" : classType;
@@ -90,6 +97,11 @@ public enum ClassType
return emptyValue; return emptyValue;
} }
public String getInvalidValue()
{
return invalidValue;
}
public boolean isObject() public boolean isObject()
{ {
return this == OBJECT; return this == OBJECT;
@@ -102,7 +114,7 @@ public enum ClassType
public boolean needsCustomJDKType() public boolean needsCustomJDKType()
{ {
return this == BYTE || this == SHORT || this == CHAR || this == FLOAT; return this == BOOLEAN || this == BYTE || this == SHORT || this == CHAR || this == FLOAT;
} }
public boolean needsCast() public boolean needsCast()
@@ -121,6 +133,12 @@ public enum ClassType
} }
} }
public String getApply(ClassType other) {
if(other == BOOLEAN) return "test";
if(other == ClassType.OBJECT) return "apply";
return "applyAs"+other.getFileType();
}
public String getEquals(boolean not) public String getEquals(boolean not)
{ {
switch(this) switch(this)
@@ -1,452 +0,0 @@
package speiger.src.builder;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.UnaryOperator;
import speiger.src.builder.mappers.ArgumentMapper;
import speiger.src.builder.mappers.IMapper;
import speiger.src.builder.mappers.InjectMapper;
import speiger.src.builder.mappers.LineMapper;
import speiger.src.builder.mappers.SimpleMapper;
import speiger.src.builder.processor.TemplateProcess;
@SuppressWarnings("javadoc")
public class GlobalVariables
{
List<IMapper> operators = new ArrayList<>();
Set<String> flags = new LinkedHashSet<>();
ClassType type;
ClassType valueType;
public GlobalVariables(ClassType type, ClassType subType)
{
this.type = type;
valueType = subType;
}
public GlobalVariables createVariables()
{
addSimpleMapper("VALUE_PACKAGE", valueType.getPathType());
addSimpleMapper("PACKAGE", type.getPathType());
addSimpleMapper("CLASS_TYPE", type.getClassType());
addSimpleMapper("CLASS_VALUE_TYPE", valueType.getClassValueType());
addSimpleMapper("KEY_TYPE", type.getKeyType());
addSimpleMapper("KEY_SPECIAL_TYPE", type.isObject() ? "E" : type.getKeyType());
addSimpleMapper("VALUE_TYPE", valueType.getValueType());
addSimpleMapper("VALUE_SPECIAL_TYPE", valueType.isObject() ? "E" : valueType.getKeyType());
addSimpleMapper("EMPTY_KEY_VALUE", type.getEmptyValue());
addSimpleMapper("EMPTY_VALUE", valueType.getEmptyValue());
addSimpleMapper(" KEY_GENERIC_TYPE", type.isObject() ? "<"+type.getKeyType()+">" : "");
addSimpleMapper(" KEY_KEY_GENERIC_TYPE", type.isObject() ? "<"+type.getKeyType()+", "+type.getKeyType()+">" : "");
addSimpleMapper(" VALUE_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+">" : "");
addSimpleMapper(" VALUE_VALUE_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : "");
addSimpleMapper(" KEY_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+">" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+">" : ""));
addSimpleMapper(" KEY_VALUE_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+", "+valueType.getValueType()+">" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : ""));
addSimpleMapper(" NO_GENERIC_TYPE", type.isObject() ? "<?>" : "");
addSimpleMapper(" NO_KV_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<?, ?>" : "<?>") : valueType.isObject() ? "<?>" : "");
addSimpleMapper(" KEY_COMPAREABLE_TYPE", type.isObject() ? "<"+type.getKeyType()+" extends Comparable<T>>" : "");
addSimpleMapper(" KEY_SUPER_GENERIC_TYPE", type.isObject() ? "<? super "+type.getKeyType()+">" : "");
addSimpleMapper(" VALUE_SUPER_GENERIC_TYPE", valueType.isObject() ? "<? super "+valueType.getValueType()+">" : "");
addSimpleMapper(" KEY_VALUE_SUPER_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<? super "+type.getKeyType()+", ? super "+valueType.getValueType()+">" : "<? super "+type.getKeyType()+">") : (valueType.isObject() ? "<? super "+valueType.getValueType()+">" : ""));
addSimpleMapper(" KEY_ENUM_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+" extends Enum<"+type.getKeyType()+">, "+valueType.getValueType()+">" : "<"+type.getKeyType()+" extends Enum<"+type.getKeyType()+">>") : (valueType.isObject() ? "<"+valueType.getValueType()+">" : ""));
addSimpleMapper(" KEY_VALUE_ENUM_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+" extends Enum<"+valueType.getValueType()+">>" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+" extends Enum<"+valueType.getValueType()+">>" : ""));
addInjectMapper(" KEY_SPECIAL_GENERIC_TYPE", type.isObject() ? "<%s>" : "").removeBraces().setBraceType("<>");
addInjectMapper(" VALUE_SPECIAL_GENERIC_TYPE", valueType.isObject() ? "<%s>" : "").removeBraces().setBraceType("<>");
addInjectMapper(" KSK_GENERIC_TYPE", type.isObject() ? "<%s, "+type.getKeyType()+">" : "<%s>").removeBraces().setBraceType("<>");
addInjectMapper(" KKS_GENERIC_TYPE", type.isObject() ? "<"+type.getKeyType()+", %s>" : "<%s>").removeBraces().setBraceType("<>");
addArgumentMapper(" KSS_GENERIC_TYPE", type.isObject() ? "<%1$s, %2$s>" : "<%2$s>").removeBraces().setBraceType("<>");
addInjectMapper(" VSV_GENERIC_TYPE", valueType.isObject() ? "<%s, "+valueType.getValueType()+">" : "<%s>").removeBraces().setBraceType("<>");
addInjectMapper(" VVS_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+", %s>" : "<%s>").removeBraces().setBraceType("<>");
addArgumentMapper(" VSS_GENERIC_TYPE", valueType.isObject() ? "<%1$s, %2$s>" : "<%2$s>").removeBraces().setBraceType("<>");
addSimpleMapper(" GENERIC_KEY_BRACES", type.isObject() ? " <"+type.getKeyType()+">" : "");
addSimpleMapper(" GENERIC_VALUE_BRACES", valueType.isObject() ? " <"+valueType.getValueType()+">" : "");
addInjectMapper(" GENERIC_SPECIAL_KEY_BRACES", type.isObject() ? " <%s>" : "").removeBraces().setBraceType("<>");
addInjectMapper(" GENERIC_SPECIAL_VALUE_BRACES", valueType.isObject() ? " <%s>" : "").removeBraces().setBraceType("<>");
addSimpleMapper(" GENERIC_KEY_ENUM_VALUE_BRACES", type.isObject() ? (valueType.isObject() ? " <"+type.getKeyType()+" extends Enum<"+type.getKeyType()+">, "+valueType.getValueType()+">" : " <"+type.getKeyType()+" extends Enum<"+type.getKeyType()+">>") : (valueType.isObject() ? " <"+valueType.getValueType()+">" : ""));
addInjectMapper(" GENERIC_KEY_SPECIAL_BRACES", type.isObject() ? " <"+type.getKeyType()+", %s>" : " <%s>").removeBraces().setBraceType("<>");
addInjectMapper(" GENERIC_VALUE_SPECIAL_BRACES", valueType.isObject() ? " <"+valueType.getKeyType()+", %s>" : " <%s>").removeBraces().setBraceType("<>");
addSimpleMapper(" GENERIC_KEY_VALUE_BRACES", type.isObject() ? (valueType.isObject() ? " <"+type.getKeyType()+", "+valueType.getValueType()+">" : " <"+type.getKeyType()+">") : (valueType.isObject() ? " <"+valueType.getValueType()+">" : ""));
addSimpleMapper(" COMPAREABLE_KEY_BRACES", type.isObject() ? " <"+type.getKeyType()+" extends Comparable<T>>" : "");
addSimpleMapper("KV_BRACES", type.isObject() || valueType.isObject() ? "<>" : "");
addSimpleMapper("BRACES", type.isObject() ? "<>" : "");
if(type.needsCustomJDKType())
{
addSimpleMapper("JAVA_TYPE", type.getCustomJDKType().getKeyType());
addSimpleMapper("SANITY_CAST", "castTo"+type.getFileType());
}
addSimpleMapper("JAVA_CLASS", type.getCustomJDKType().getClassType());
if(valueType.needsCustomJDKType())
{
addSimpleMapper("SANITY_CAST_VALUE", "castTo"+valueType.getFileType());
}
addComment("@ArrayType", "@param <%s> the type of array that the operation should be applied");
addComment("@Type", "@param <%s> the type of elements maintained by this Collection");
addValueComment("@ValueArrayType", "@param <%s> the type of array that the operation should be applied");
addValueComment("@ValueType", "@param <%s> the type of elements maintained by this Collection");
addAnnontion("@PrimitiveOverride", "@Override");
addSimpleMapper("@PrimitiveDoc", "");
addAnnontion("@Primitive", "@Deprecated");
addValueAnnontion("@ValuePrimitiveOverride", "@Override");
addValueAnnontion("@ValuePrimitive", "@Deprecated");
return this;
}
public GlobalVariables createHelperVariables()
{
createHelperVars(type, false, "KEY");
createHelperVars(valueType, true, "VALUE");
return this;
}
private void createHelperVars(ClassType type, boolean value, String fix)
{
addArgumentMapper("EQUALS_"+fix+"_TYPE", "Objects.equals(%2$s, "+(type.isObject() ? "%1$s" : fix+"_TO_OBJ(%1$s)")+")").removeBraces();
addInjectMapper(fix+"_EQUALS_NOT_NULL", type.getComparableValue()+" != "+(type.isPrimitiveBlocking() || type.needsCast() ? type.getEmptyValue() : "0")).removeBraces();
addInjectMapper(fix+"_EQUALS_NULL", type.getComparableValue()+" == "+(type.isPrimitiveBlocking() || type.needsCast() ? type.getEmptyValue() : "0")).removeBraces();
addArgumentMapper(fix+"_EQUALS_NOT", type.getEquals(true)).removeBraces();
addArgumentMapper(fix+"_EQUALS", type.getEquals(false)).removeBraces();
addArgumentMapper("COMPAREABLE_TO_"+fix, type.isObject() ? "((Comparable<"+type.getKeyType(value)+">)%1$s).compareTo(("+type.getKeyType(value)+")%2$s)" : type.getClassType(value)+".compare(%1$s, %2$s)").removeBraces();
addArgumentMapper("COMPARE_TO_"+fix, type.isObject() ? "%1$s.compareTo(%2$s)" : type.getClassType(value)+".compare(%1$s, %2$s)").removeBraces();
addInjectMapper(fix+"_TO_OBJ", type.isObject() ? "%s" : type.getClassType(value)+".valueOf(%s)").removeBraces();
addInjectMapper("OBJ_TO_"+fix, type.isObject() ? "%s" : "%s."+type.getKeyType(value)+"Value()").removeBraces();
addInjectMapper("CLASS_TO_"+fix, type.isObject() ? "("+type.getKeyType(value)+")%s" : "(("+type.getClassType(value)+")%s)."+type.getKeyType(value)+"Value()").removeBraces();
addInjectMapper(fix+"_TO_HASH", type.isObject() ? "Objects.hashCode(%s)" : type.getClassType(value)+".hashCode(%s)").removeBraces();
addInjectMapper(fix+"_TO_STRING", type.isObject() ? "Objects.toString(%s)" : type.getClassType(value)+".toString(%s)").removeBraces();
addSimpleMapper("CAST_"+fix+"_ARRAY ", type.isObject() ? "("+fix+"_TYPE[])" : "");
addSimpleMapper("EMPTY_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])ARRAYS.EMPTY_ARRAY" : "ARRAYS.EMPTY_ARRAY");
addInjectMapper("NEW_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])new Object[%s]" : "new "+fix+"_TYPE[%s]").removeBraces();
addInjectMapper("NEW_SPECIAL_"+fix+"_ARRAY", type.isObject() ? "(E[])new Object[%s]" : "new "+fix+"_TYPE[%s]").removeBraces();
addInjectMapper("NEW_CLASS"+(value ? "_VALUE" : "")+"_ARRAY", type.isObject() ? "(CLASS_TYPE[])new Object[%s]" : "new CLASS_TYPE[%s]").removeBraces();
}
public GlobalVariables createPreFunctions()
{
addSimpleMapper("ENTRY_SET", type.getFileType().toLowerCase()+"2"+valueType.getFileType()+"EntrySet");
return this;
}
public GlobalVariables createClassTypes()
{
addSimpleMapper("JAVA_PREDICATE", type.isPrimitiveBlocking() ? "" : type.getCustomJDKType().getFileType()+"Predicate");
addSimpleMapper("JAVA_CONSUMER", type.isPrimitiveBlocking() ? "" : "java.util.function."+type.getCustomJDKType().getFileType()+"Consumer");
addSimpleMapper("JAVA_SUPPLIER", type.isPrimitiveBlocking() ? "" : "java.util.function."+type.getCustomJDKType().getFileType()+"Supplier");
addSimpleMapper("JAVA_FUNCTION", type.getFunctionClass(valueType));
addSimpleMapper("JAVA_BINARY_OPERATOR", type == ClassType.BOOLEAN ? "" : (type.isObject() ? "java.util.function.BinaryOperator" : "java.util.function."+type.getCustomJDKType().getFileType()+"BinaryOperator"));
addSimpleMapper("JAVA_UNARY_OPERATOR", type.isObject() ? "BinaryOperator" : type == ClassType.BOOLEAN ? "" : type.getCustomJDKType().getFileType()+"UnaryOperator");
addSimpleMapper("JAVA_SPLIT_ITERATOR", type.isPrimitiveBlocking() ? "Spliterator" : "Of"+type.getCustomJDKType().getFileType());
addSimpleMapper("JAVA_STREAM", type.isPrimitiveBlocking() ? "" : type.getCustomJDKType().getFileType()+"Stream");
addSimpleMapper("JAVA_BUFFER", type.getFileType()+"Buffer");
//Final Classes
addClassMapper("ARRAY_LIST", "ArrayList");
addAbstractMapper("COPY_ON_WRITE_LIST", "CopyOnWrite%sArrayList");
addClassMapper("ASYNC_BUILDER", "AsyncBuilder");
addClassMapper("LINKED_LIST", "LinkedList");
addAbstractMapper("IMMUTABLE_LIST", "Immutable%sList");
addClassMapper("ARRAY_FIFO_QUEUE", "ArrayFIFOQueue");
addClassMapper("ARRAY_PRIORITY_QUEUE", "ArrayPriorityQueue");
addClassMapper("HEAP_PRIORITY_QUEUE", "HeapPriorityQueue");
addClassMapper("LINKED_CUSTOM_HASH_SET", "LinkedOpenCustomHashSet");
addClassMapper("LINKED_HASH_SET", "LinkedOpenHashSet");
addAbstractMapper("IMMUTABLE_HASH_SET", "Immutable%sOpenHashSet");
addClassMapper("CUSTOM_HASH_SET", "OpenCustomHashSet");
addClassMapper("HASH_SET", "OpenHashSet");
addAbstractBiMapper("IMMUTABLE_HASH_MAP", "Immutable%sOpenHashMap", "2");
addBiClassMapper("LINKED_CUSTOM_HASH_MAP", "LinkedOpenCustomHashMap", "2");
addBiClassMapper("LINKED_HASH_MAP", "LinkedOpenHashMap", "2");
addBiClassMapper("CUSTOM_HASH_MAP", "OpenCustomHashMap", "2");
addBiClassMapper("CONCURRENT_HASH_MAP", "ConcurrentOpenHashMap", "2");
addBiClassMapper("AVL_TREE_MAP", "AVLTreeMap", "2");
addBiClassMapper("RB_TREE_MAP", "RBTreeMap", "2");
addFunctionValueMappers("LINKED_ENUM_MAP", valueType.isObject() ? "LinkedEnum2ObjectMap" : "LinkedEnum2%sMap");
addFunctionValueMappers("ENUM_MAP", valueType.isObject() ? "Enum2ObjectMap" : "Enum2%sMap");
addBiClassMapper("HASH_MAP", "OpenHashMap", "2");
addBiClassMapper("ARRAY_MAP", "ArrayMap", "2");
addBiClassMapper("IMMUTABLE_PAIR", "ImmutablePair", "");
addBiClassMapper("MUTABLE_PAIR", "MutablePair", "");
addClassMapper("RB_TREE_SET", "RBTreeSet");
addClassMapper("AVL_TREE_SET", "AVLTreeSet");
addClassMapper("ARRAY_SET", "ArraySet");
//Abstract Classes
addAbstractMapper("ABSTRACT_COLLECTION", "Abstract%sCollection");
addAbstractMapper("ABSTRACT_PRIORITY_QUEUE", "Abstract%sPriorityQueue");
addAbstractMapper("ABSTRACT_SET", "Abstract%sSet");
addAbstractMapper("ABSTRACT_LIST", "Abstract%sList");
addAbstractBiMapper("ABSTRACT_MAP", "Abstract%sMap", "2");
addClassMapper("SUB_LIST", "SubList");
addAbstractMapper("BASE_TASK", "Base%sTask");
//Helper Classes
addClassMapper("LISTS", "Lists");
addClassMapper("SETS", "Sets");
addClassMapper("COLLECTIONS", "Collections");
addClassMapper("ARRAYS", "Arrays");
addClassMapper("PRIORITY_QUEUES", "PriorityQueues");
addClassMapper("SPLIT_ITERATORS", "Splititerators");
addClassMapper("ITERATORS", "Iterators");
addClassMapper("ITERABLES", "Iterables");
addBiClassMapper("MAPS", "Maps", "2");
//Interfaces
addClassMapper("LIST_ITERATOR", "ListIterator");
addClassMapper("BI_ITERATOR", "BidirectionalIterator");
addBiClassMapper("BI_CONSUMER", "Consumer", "");
addClassMapper("BI_TO_OBJECT_CONSUMER", "ObjectConsumer");
addAbstractMapper("BI_FROM_OBJECT_CONSUMER", "Object%sConsumer");
addClassMapper("SPLIT_ITERATOR", "Splititerator");
addClassMapper("ITERATOR", "Iterator");
addClassMapper("ITERABLE", "Iterable");
addClassMapper("COLLECTION", "Collection");
addClassMapper("TO_OBJECT_FUNCTION", "2ObjectFunction");
addBiClassMapper("FUNCTION", "Function", "2");
addClassMapper("LIST_ITER", "ListIter");
addClassMapper("LIST", "List");
addBiClassMapper("NAVIGABLE_MAP", "NavigableMap", "2");
addBiClassMapper("ORDERED_MAP", "OrderedMap", "2");
addBiClassMapper("SORTED_MAP", "SortedMap", "2");
addBiClassMapper("CONCURRENT_MAP", "ConcurrentMap", "2");
addBiClassMapper("MAP", "Map", "2");
addClassMapper("NAVIGABLE_SET", "NavigableSet");
addBiClassMapper("PAIR", "Pair", "");
addClassMapper("PRIORITY_QUEUE", "PriorityQueue");
addClassMapper("PRIORITY_DEQUEUE", "PriorityDequeue");
addClassMapper("PREDICATE", "2BooleanFunction");
addClassMapper("SORTED_SET", "SortedSet");
addClassMapper("ORDERED_SET", "OrderedSet");
addClassMapper("SET", "Set");
addClassMapper("STRATEGY", "Strategy");
addClassMapper("STACK", "Stack");
addClassMapper("SUPPLIER", "Supplier");
addAbstractMapper("SINGLE_UNARY_OPERATOR", "%1$s%1$sUnaryOperator");
addClassMapper("TASK", "Task");
addBiClassMapper("UNARY_OPERATOR", "UnaryOperator", "");
if(type.isObject())
{
if(!valueType.isObject()) addSimpleMapper("VALUE_CONSUMER", valueType.getFileType()+"Consumer");
else addSimpleMapper("VALUE_CONSUMER", "Consumer");
addSimpleMapper("CONSUMER", "Consumer");
addSimpleMapper("COMPARATOR", "Comparator");
addSimpleMapper("IARRAY", "IObjectArray");
}
else
{
if(valueType.isObject())
{
addSimpleMapper("VALUE_CONSUMER", "Consumer");
addSimpleMapper("CONSUMER", type.getFileType()+"Consumer");
}
else addClassMapper("CONSUMER", "Consumer");
addClassMapper("COMPARATOR", "Comparator");
addFunctionMappers("IARRAY", "I%sArray");
}
return this;
}
public GlobalVariables createFunctions()
{
addSimpleMapper("APPLY_KEY_VALUE", type.isObject() ? "apply" : "applyAs"+type.getNonFileType());
addSimpleMapper("APPLY_VALUE", valueType.isObject() ? "apply" : "applyAs"+valueType.getNonFileType());
addSimpleMapper("APPLY_CAST", "applyAs"+type.getCustomJDKType().getNonFileType());
addSimpleMapper("APPLY", type.isObject() ? "apply" : "applyAs"+type.getNonFileType());
addFunctionValueMapper("BULK_MERGE", "mergeAll");
addFunctionValueMappers("COMPUTE_IF_ABSENT", "compute%sIfAbsent");
addFunctionValueMappers("COMPUTE_IF_PRESENT", "compute%sIfPresent");
addFunctionValueMapper("COMPUTE", "compute");
addFunctionMapper("DEQUEUE_LAST", "dequeueLast");
addFunctionMapper("DEQUEUE", "dequeue");
addFunctionMappers("POLL_FIRST_ENTRY_KEY", "pollFirst%sKey");
addFunctionMappers("POLL_LAST_ENTRY_KEY", "pollLast%sKey");
addFunctionMapper("POLL_FIRST_KEY", "pollFirst");
addFunctionMapper("POLL_LAST_KEY", "pollLast");
addFunctionMappers("FIRST_ENTRY_KEY", "first%sKey");
addFunctionValueMappers("FIRST_ENTRY_VALUE", "first%sValue");
addFunctionMapper("FIRST_KEY", "first");
addFunctionMappers("LAST_ENTRY_KEY", "last%sKey");
addFunctionValueMappers("LAST_ENTRY_VALUE", "last%sValue");
addFunctionMappers("ENTRY_KEY", "get%sKey");
addFunctionValueMappers("ENTRY_VALUE", "get%sValue");
addFunctionMappers("KEY_ENTRY", "set%sKey");
addFunctionValueMappers("VALUE_ENTRY", "set%sValue");
addFunctionMapper("GET_KEY", "get");
if(type.isObject()) addFunctionValueMapper("GET_VALUE", valueType.isObject() ? "getObject" : "get");
else addSimpleMapper("GET_VALUE", "get");
addSimpleMapper("GET_JAVA", type.isObject() ? "get" : "getAs"+type.getCustomJDKType().getNonFileType());
addFunctionMapper("LAST_KEY", "last");
addFunctionValueMapper("MERGE", "merge");
addFunctionMapper("NEXT", "next");
addFunctionMapper("PREVIOUS", "previous");
addFunctionMapper("REMOVE_SWAP", "swapRemove");
if(type.isObject()) addFunctionMapper("REMOVE_VALUE", "rem");
else addSimpleMapper("REMOVE_VALUE", "remove");
addFunctionMapper("REMOVE_KEY", "rem");
addFunctionMapper("REMOVE_LAST", "removeLast");
addFunctionMapper("REMOVE", "remove");
addFunctionValueMappers("REPLACE_VALUES", valueType.isObject() ? "replaceObjects" : "replace%ss");
addFunctionMappers("REPLACE", type.isObject() ? "replaceObjects" : "replace%ss");
addFunctionMappers("SORT", "sort%ss");
addFunctionValueMappers("SUPPLY_IF_ABSENT", "supply%sIfAbsent");
addSimpleMapper("VALUE_TEST_VALUE", valueType.isObject() ? "getBoolean" : "get");
addSimpleMapper("TEST_VALUE", type.isObject() ? "getBoolean" : "get");
addSimpleMapper("NEW_STREAM", type.isPrimitiveBlocking() ? "" : type.getCustomJDKType().getKeyType()+"Stream");
addSimpleMapper("TO_ARRAY", "to"+type.getNonFileType()+"Array");
addSimpleMapper("[SPACE]", " ");
return this;
}
public GlobalVariables createFlags()
{
flags.add("TYPE_"+type.getCapType());
flags.add("VALUE_"+valueType.getCapType());
if(type == valueType) flags.add("SAME_TYPE");
if(type.hasFunction(valueType)) flags.add("JDK_FUNCTION");
if(!type.needsCustomJDKType()) flags.add("JDK_TYPE");
if(!type.isPrimitiveBlocking()) flags.add("PRIMITIVES");
if(!valueType.isPrimitiveBlocking()) flags.add("VALUE_PRIMITIVES");
if(valueType.needsCustomJDKType()) flags.add("JDK_VALUE");
return this;
}
public TemplateProcess create(String fileName, String splitter, boolean valueOnly)
{
TemplateProcess process = new TemplateProcess(String.format(fileName+".java", (splitter != null ? type.getFileType()+splitter+valueType.getFileType() : (valueOnly ? valueType : type).getFileType())));
process.setPathBuilder(new PathBuilder(type.getPathType()));
process.addFlags(flags);
process.addMappers(operators);
return process;
}
public ClassType getType()
{
return type;
}
private void addClassMapper(String pattern, String replacement)
{
operators.add(new SimpleMapper(type.name()+"[VALUE_"+pattern+"]", "VALUE_"+pattern, valueType.getFileType()+replacement));
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, type.getFileType()+replacement));
}
private void addBiClassMapper(String pattern, String replacement, String splitter)
{
operators.add(new SimpleMapper(type.name()+"[KEY_"+pattern+"]", "KEY_"+pattern, type.getFileType()+splitter+type.getFileType()+replacement));
operators.add(new SimpleMapper(type.name()+"[VALUE_"+pattern+"]", "VALUE_"+pattern, valueType.getFileType()+splitter+valueType.getFileType()+replacement));
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, type.getFileType()+splitter+valueType.getFileType()+replacement));
}
private void addAbstractMapper(String pattern, String replacement)
{
operators.add(new SimpleMapper(type.name()+"[VALUE_"+pattern+"]", "VALUE_"+pattern, String.format(replacement, valueType.getFileType())));
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, type.getFileType())));
}
private void addAbstractBiMapper(String pattern, String replacement, String splitter)
{
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, type.getFileType()+splitter+valueType.getFileType())));
}
private void addFunctionMapper(String pattern, String replacement)
{
operators.add(new SimpleMapper(type.name()+"[VALUE_"+pattern+"]", "VALUE_"+pattern, replacement+valueType.getNonFileType()));
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, replacement+type.getNonFileType()));
}
private void addFunctionValueMapper(String pattern, String replacement)
{
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, replacement+valueType.getNonFileType()));
}
private void addFunctionMappers(String pattern, String replacement)
{
operators.add(new SimpleMapper(type.name()+"[VALUE_"+pattern+"]", "VALUE_"+pattern, String.format(replacement, valueType.getNonFileType())));
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, type.getNonFileType())));
}
private void addFunctionValueMappers(String pattern, String replacement)
{
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, valueType.getNonFileType())));
}
private void addSimpleMapper(String pattern, String replacement)
{
operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, replacement));
}
private void addAnnontion(String pattern, String value)
{
if(type == ClassType.OBJECT) operators.add(new LineMapper(type.name()+"["+pattern+"]", pattern));
else operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, value));
}
private void addValueAnnontion(String pattern, String value)
{
if(valueType == ClassType.OBJECT) operators.add(new LineMapper(valueType.name()+"["+pattern+"]", pattern));
else operators.add(new SimpleMapper(valueType.name()+"["+pattern+"]", pattern, value));
}
private void addComment(String pattern, String value)
{
if(type == ClassType.OBJECT) operators.add(new InjectMapper(type.name()+"["+pattern+"]", pattern, value).removeBraces());
else operators.add(new LineMapper(type.name()+"["+pattern+"]", pattern));
}
private void addValueComment(String pattern, String value)
{
if(valueType == ClassType.OBJECT) operators.add(new InjectMapper(valueType.name()+"["+pattern+"]", pattern, value).removeBraces());
else operators.add(new LineMapper(valueType.name()+"["+pattern+"]", pattern));
}
private InjectMapper addInjectMapper(String pattern, String replacement)
{
InjectMapper mapper = new InjectMapper(type.name()+"["+pattern+"]", pattern, replacement);
operators.add(mapper);
return mapper;
}
private ArgumentMapper addArgumentMapper(String pattern, String replacement)
{
return addArgumentMapper(pattern, replacement, ", ");
}
private ArgumentMapper addArgumentMapper(String pattern, String replacement, String splitter)
{
ArgumentMapper mapper = new ArgumentMapper(type.name()+"["+pattern+"]", pattern, replacement, splitter);
operators.add(mapper);
return mapper;
}
class PathBuilder implements UnaryOperator<Path>
{
String before;
public PathBuilder(String before)
{
this.before = before;
}
@Override
public Path apply(Path t)
{
return t.subpath(0, 6).resolve(before).resolve(t.subpath(6, t.getNameCount()));
}
}
}
@@ -0,0 +1,155 @@
package speiger.src.builder;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import speiger.src.builder.mappers.IMapper;
import speiger.src.builder.processor.TemplateProcess;
@SuppressWarnings("javadoc")
public class ModulePackage
{
private static final BiConsumer<String, RequiredType> VOID = (K, V) -> {};
public static final ClassType[] TYPE = ClassType.values();
final ClassType keyType;
final ClassType valueType;
Set<String> blocked = new HashSet<>();
Map<String, String> nameRemapper = new HashMap<>();
Map<String, String> splitters = new HashMap<>();
List<Predicate<String>> blockedFilters = new ArrayList<>();
List<IMapper> mappers = new ArrayList<>();
Set<String> flags = new LinkedHashSet<>();
Set<String> globalFlags;
Map<String, Integer> flaggedValues = new HashMap<>();
BiConsumer<String, RequiredType> requirements = VOID;
public ModulePackage(Set<String> globalFlags, ClassType keyType, ClassType valueType) {
this.globalFlags = globalFlags;
this.keyType = keyType;
this.valueType = valueType;
}
public void finish() {
requirements = VOID;
mappers.sort(Comparator.comparing(IMapper::getSearchValue, Comparator.comparingInt(String::length).reversed()));
mappers.sort(Comparator.comparing(IMapper::getSearchValue, this::sort));
}
public void setRequirements(BiConsumer<String, RequiredType> requirements) {
this.requirements = requirements;
}
public boolean isSame() {
return keyType == valueType;
}
public boolean isEnumValid() {
return keyType == ClassType.OBJECT;
}
public ClassType getKeyType() {
return keyType;
}
public ClassType getValueType() {
return valueType;
}
public void addFlag(String flag) {
flags.add(flag);
}
public void addGlobalFlag(String flag) {
globalFlags.add(flag);
}
public void addValue(String key, int value) {
flaggedValues.put(key, value);
}
public void addRequirement(String fileName, RequiredType type) {
requirements.accept(fileName, type);
}
public void addMapper(IMapper mapper) {
mappers.add(mapper);
}
public void addBlockedFilter(Predicate<String> filter) {
blockedFilters.add(filter);
}
public void addBlockedFiles(String... names) {
blocked.addAll(Arrays.asList(names));
}
public void addSplitter(String fileName, String splitter) {
splitters.put(fileName, splitter);
}
public void addRemapper(String fileName, String actualName) {
nameRemapper.put(fileName, actualName);
}
public void process(String fileName, Consumer<TemplateProcess> result) {
if(isBlocked(fileName)) return;
String splitter = String.format(splitters.getOrDefault(fileName, keyType.getFileType()), keyType.getFileType(), valueType.getFileType());
String newName = String.format(nameRemapper.getOrDefault(fileName, "%s"+fileName), splitter);
TemplateProcess process = new TemplateProcess(newName+".java");
process.setPathBuilder(new PathBuilder(keyType.getPathType()));
process.addFlags(flags);
process.addFlags(globalFlags);
process.addMappers(mappers);
process.addValues(flaggedValues);
result.accept(process);
}
private boolean isBlocked(String fileName) {
if(blocked.contains(fileName)) return true;
for(int i = 0,m=blockedFilters.size();i<m;i++) {
if(blockedFilters.get(i).test(fileName)) return true;
}
return false;
}
public static List<ModulePackage> createPackages(Set<String> globalFlags) {
List<ModulePackage> list = new ArrayList<>();
for(ClassType key : TYPE) {
for(ClassType value : TYPE) {
list.add(new ModulePackage(globalFlags, key, value));
}
}
return list;
}
private int sort(String key, String value) {
if(value.contains(key)) return 1;
else if(key.contains(value)) return -1;
return 0;
}
class PathBuilder implements UnaryOperator<Path> {
String before;
public PathBuilder(String before) {
this.before = before;
}
@Override
public Path apply(Path t) {
return t.subpath(0, 6).resolve(before).resolve(t.subpath(6, t.getNameCount()));
}
}
}
@@ -6,7 +6,8 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -16,177 +17,157 @@ import java.util.StringJoiner;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Stream; import java.util.stream.Stream;
import speiger.src.builder.modules.AsyncModule;
import speiger.src.builder.modules.BaseModule;
import speiger.src.builder.modules.CollectionModule;
import speiger.src.builder.modules.FunctionModule;
import speiger.src.builder.modules.JavaModule;
import speiger.src.builder.modules.ListModule;
import speiger.src.builder.modules.MapModule;
import speiger.src.builder.modules.PairModule;
import speiger.src.builder.modules.PrioQueueModule;
import speiger.src.builder.modules.SetModule;
import speiger.src.builder.processor.TemplateProcess; import speiger.src.builder.processor.TemplateProcess;
import speiger.src.builder.processor.TemplateProcessor; import speiger.src.builder.processor.TemplateProcessor;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public class PrimitiveCollectionsBuilder extends TemplateProcessor public class PrimitiveCollectionsBuilder extends TemplateProcessor
{ {
Map<String, EnumSet<ClassType>> blocked = new HashMap<>(); private static final int SPECIAL = 0x1; //Detects if the Builder is generating tests
Map<String, String> nameRemapper = new HashMap<>(); private static final int LOAD = 0x2; //If Configs should be loaded
Map<String, String> biRequired = new HashMap<>(); private static final int ANTI_SAVE = SPECIAL | LOAD; //If save should be disabled since load/save shouldn't happen at the same time.
Set<String> enumRequired = new HashSet<>(); private static final int SAVE = 0x4; //if the configuration should be created
public static final ClassType[] TYPE = ClassType.values(); Set<String> globalFlags = new HashSet<>();
List<GlobalVariables> variables = new ArrayList<>(); List<ModulePackage> simplePackages = new ArrayList<>();
List<GlobalVariables> biVariables = new ArrayList<>(); List<ModulePackage> biPackages = new ArrayList<>();
List<GlobalVariables> enumVariables = new ArrayList<>(); List<ModulePackage> enumPackages = new ArrayList<>();
Map<String, RequiredType> requirements = new HashMap<>();
SettingsManager manager = new SettingsManager();
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);
} }
@Override private PrimitiveCollectionsBuilder setFlags(int flags) {
protected boolean isFileValid(Path fileName) this.flags = flags;
{ if((flags & ANTI_SAVE) != 0) {
return true; this.flags &= ~SAVE;
}
return this;
}
private static PrimitiveCollectionsBuilder createTests(boolean silent, int flags) {
return new PrimitiveCollectionsBuilder(silent,
Paths.get("src/builder/resources/speiger/assets/tests/templates/"),
Paths.get("src/test/java/speiger/src/tests/"),
Paths.get("src/builder/resources/speiger/assets/tests/")).setFlags(flags | SPECIAL);
}
private static PrimitiveCollectionsBuilder createTesters(boolean silent, int flags) {
return new PrimitiveCollectionsBuilder(silent,
Paths.get("src/builder/resources/speiger/assets/testers/templates/"),
Paths.get("src/test/java/speiger/src/testers/"),
Paths.get("src/builder/resources/speiger/assets/testers/")).setFlags(flags | SPECIAL);
} }
@Override @Override
protected boolean relativePackages() 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 debugUnusedMappers() protected void afterFinish() {
{ if((flags & SPECIAL) == 0 && getVersion() > 8) {
return false;
}
@Override
protected void afterFinish()
{
if(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() {
List<BaseModule> modules = new ArrayList<>();
modules.add(JavaModule.INSTANCE);
modules.add(FunctionModule.INSTANCE);
modules.add(CollectionModule.INSTANCE);
modules.add(PrioQueueModule.INSTANCE);
modules.add(ListModule.INSTANCE);
modules.add(SetModule.INSTANCE);
modules.add(MapModule.INSTANCE);
modules.add(PairModule.INSTANCE);
modules.add(AsyncModule.INSTANCE);
return modules;
}
@Override
protected void init() {
prepPackages();
//Init Modules here
addModules(createModules());
finishPackages();
}
public void addModules(List<BaseModule> modules) {
for(int i = 0,m=modules.size();i<m;i++) {
modules.get(i).setManager(manager);
}
manager.resolve();
for(int i = 0,m=modules.size();i<m;i++) {
biPackages.forEach(modules.get(i)::init);
}
modules.forEach(BaseModule::cleanup);
}
private void finishPackages() {
biPackages.forEach(ModulePackage::finish);
if((flags & SAVE) != 0) manager.save();
}
private void prepPackages() {
if((flags & LOAD) != 0) manager.load();
for(ModulePackage entry : ModulePackage.createPackages(globalFlags)) {
entry.setRequirements(requirements::put);
biPackages.add(entry);
if(entry.isSame()) simplePackages.add(entry);
if(entry.isEnumValid()) enumPackages.add(entry);
}
} }
@Override @Override
protected void init() public void createProcesses(String fileName, Consumer<TemplateProcess> process) {
{ List<ModulePackage> packages = getPackagesByRequirement(requirements.get(fileName));
variables.clear(); for(int i = 0,m=packages.size();i<m;i++) {
for(ClassType clzType : TYPE) packages.get(i).process(fileName, process);
{
for(ClassType subType : TYPE)
{
create(clzType, subType);
}
}
enumRequired.add("EnumMap");
enumRequired.add("LinkedEnumMap");
biRequired.put("BiConsumer", "");
biRequired.put("UnaryOperator", "");
biRequired.put("Pair", "");
biRequired.put("MutablePair", "");
biRequired.put("ImmutablePair", "");
addBiClass("Function", "Maps", "Map", "SortedMap", "OrderedMap", "NavigableMap", "ConcurrentMap", "AbstractMap", "ConcurrentOpenHashMap", "ImmutableOpenHashMap", "OpenHashMap", "LinkedOpenHashMap", "OpenCustomHashMap", "LinkedOpenCustomHashMap", "ArrayMap", "RBTreeMap", "AVLTreeMap");
nameRemapper.put("BiConsumer", "%sConsumer");
nameRemapper.put("IArray", "I%sArray");
nameRemapper.put("AbstractMap", "Abstract%sMap");
nameRemapper.put("AbstractCollection", "Abstract%sCollection");
nameRemapper.put("AbstractPriorityQueue", "Abstract%sPriorityQueue");
nameRemapper.put("AbstractSet", "Abstract%sSet");
nameRemapper.put("AbstractList", "Abstract%sList");
nameRemapper.put("EnumMap", "Enum2%sMap");
nameRemapper.put("LinkedEnumMap", "LinkedEnum2%sMap");
nameRemapper.put("ImmutableList", "Immutable%sList");
nameRemapper.put("CopyOnWriteList", "CopyOnWrite%sArrayList");
nameRemapper.put("ImmutableOpenHashSet", "Immutable%sOpenHashSet");
nameRemapper.put("ImmutableOpenHashMap", "Immutable%sOpenHashMap");
addBlockage(ClassType.OBJECT, "Consumer", "Comparator", "Stack");
addBlockage(ClassType.BOOLEAN, "ArraySet", "AVLTreeSet", "RBTreeSet", "SortedSet", "OrderedSet", "NavigableSet", "OpenHashSet", "OpenCustomHashSet", "LinkedOpenHashSet", "LinkedOpenCustomHashSet");
addBlockage(ClassType.BOOLEAN, "ConcurrentOpenHashMap", "ImmutableOpenHashMap", "ImmutableOpenHashSet", "SortedMap", "OrderedMap", "NavigableMap", "ConcurrentMap", "OpenHashMap", "LinkedOpenHashMap", "OpenCustomHashMap", "LinkedOpenCustomHashMap", "ArrayMap", "RBTreeMap", "AVLTreeMap");
}
protected void create(ClassType mainType, ClassType subType)
{
GlobalVariables type = new GlobalVariables(mainType, subType);
type.createFlags();
type.createHelperVariables();
type.createVariables();
type.createPreFunctions();
type.createClassTypes();
type.createFunctions();
if(mainType == subType) variables.add(type);
biVariables.add(type);
if(mainType.isObject()) enumVariables.add(type);
}
protected void addBiClass(String...classNames)
{
for(String s : classNames)
{
biRequired.put(s, "2");
} }
} }
protected void addBlockage(ClassType type, String...args) protected List<ModulePackage> getPackagesByRequirement(RequiredType type) {
{ if(type == null) return simplePackages;
for(String s : args) if(type == RequiredType.BI_CLASS) return biPackages;
{ if(type == RequiredType.ENUM) return enumPackages;
EnumSet<ClassType> set = blocked.get(s); return Collections.emptyList();
if(set == null)
{
set = EnumSet.noneOf(ClassType.class);
blocked.put(s, set);
}
set.add(type);
}
}
@Override
public void createProcesses(String name, Consumer<TemplateProcess> acceptor)
{
String splitter = biRequired.get(name);
boolean valueRequired = enumRequired.contains(name);
List<GlobalVariables> vars = getVariablesByClass(name, splitter != null);
EnumSet<ClassType> types = blocked.get(name);
for(int i = 0,m=vars.size();i<m;i++)
{
GlobalVariables type = vars.get(i);
if(types == null || !types.contains(type.getType()))
{
acceptor.accept(type.create(nameRemapper.getOrDefault(name, "%s"+name), splitter, valueRequired));
}
}
}
protected List<GlobalVariables> getVariablesByClass(String name, boolean bi) {
if(enumRequired.contains(name)) return enumVariables;
if(bi) return biVariables;
return variables;
} }
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)
@@ -194,8 +175,7 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
.map(this::sanitize) .map(this::sanitize)
.forEach(T -> joiner.add("\texports "+T+";")); .forEach(T -> joiner.add("\texports "+T+";"));
} }
catch(Exception e) catch(Exception e) {
{
e.printStackTrace(); e.printStackTrace();
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -206,58 +186,43 @@ 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
{ {
if(args.length == 0) { Set<String> flags = new HashSet<>(Arrays.asList(args));
new PrimitiveCollectionsBuilder().process(false); boolean silent = flags.contains("silent");
} else if(args.length == 1) { boolean force = flags.contains("force");
new PrimitiveCollectionsBuilder().process(Boolean.parseBoolean(args[0])); boolean tests = flags.contains("tests");
} else if(args.length == 2) { boolean forceTests = flags.contains("force-tests");
new PrimitiveCollectionsBuilder(Boolean.parseBoolean(args[1])).process(Boolean.parseBoolean(args[0])); boolean load = flags.contains("load");
} else if(args.length == 3) { boolean save = flags.contains("save");
new PrimitiveCollectionsBuilder(Paths.get(args[0]), Paths.get(args[1]), Paths.get(args[2])).process(false); int flag = (load ? LOAD : 0) | (save ? SAVE : 0);
} else if(args.length == 4) { new PrimitiveCollectionsBuilder(silent).setFlags(flag).process(force);
new PrimitiveCollectionsBuilder(false, Paths.get(args[0]), Paths.get(args[1]), Paths.get(args[2])).process(Boolean.parseBoolean(args[3])); if(tests) {
} else if(args.length == 4) { createTests(silent, flag).process(force || forceTests);
new PrimitiveCollectionsBuilder(Boolean.parseBoolean(args[4]), Paths.get(args[0]), Paths.get(args[1]), Paths.get(args[2])).process(Boolean.parseBoolean(args[3])); createTesters(silent, flag).process(force || forceTests);
} else {
System.out.println("Invalid argument count passed in");
System.exit(1);
} }
} }
catch(InterruptedException e) catch(InterruptedException | IOException e)
{
e.printStackTrace();
}
catch(IOException e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
@@ -0,0 +1,8 @@
package speiger.src.builder;
@SuppressWarnings("javadoc")
public enum RequiredType
{
BI_CLASS,
ENUM
}
@@ -0,0 +1,217 @@
package speiger.src.builder;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonWriter;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.IDependency.LoadingState;
import speiger.src.builder.modules.BaseModule;
@SuppressWarnings("javadoc")
public class SettingsManager
{
boolean loaded;
Map<String, LoadingState> parsedData = new TreeMap<>();
JsonObject data = new JsonObject();
Set<String> moduleNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
Set<IDependency> allDependencies = new LinkedHashSet<>();
public void resolve() {
if(!loaded) return;
Set<IDependency> roots = new LinkedHashSet<>();
Set<IDependency> leafs = new LinkedHashSet<>();
for(IDependency entry : allDependencies) {
if(entry.isRoot()) {
roots.add(entry);
}
if(entry.isLeaf()) {
leafs.add(entry);
}
}
/**
* This has to be 2 iteration passes.
* Due to Key Value Pairs, first pass does all initials keys, and the second pass processes the values.
* May require more passes but extremely unlikely
*/
for(int i = 0;i<2;i++) {
for(ClassType keyType : ModulePackage.TYPE) {
for(ClassType valueType : ModulePackage.TYPE) {
for(IDependency entry : roots) {
entry.resolveRequirements(keyType, valueType);
}
}
}
}
List<String> errors = new ArrayList<>();
for(ClassType keyType : ModulePackage.TYPE) {
for(ClassType valueType : ModulePackage.TYPE) {
for(IDependency entry : leafs) {
entry.validateDependency(errors::add, keyType, valueType);
}
}
}
if(errors.size() > 0) {
throw new IllegalStateException("Issues with dependencies found: "+String.join("\n", errors));
}
}
public void addModule(BaseModule module) {
if(loaded) {
if(module.isBiModule()) {
for(ClassType keyType : ModulePackage.TYPE) {
for(ClassType valueType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, valueType)) continue;
for(IDependency dependency : module.getDependencies(keyType, valueType)) {
dependency.set(parsedData);
allDependencies.add(dependency);
}
}
}
return;
}
for(ClassType keyType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, keyType)) continue;
for(IDependency dependency : module.getDependencies(keyType, keyType)) {
dependency.set(parsedData);
allDependencies.add(dependency);
}
}
return;
}
String moduleName = module.getModuleName();
moduleNames.add(moduleName);
data.addProperty(moduleName, true);
if(module.isBiModule()) {
for(ClassType keyType : ModulePackage.TYPE) {
for(ClassType valueType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, valueType)) continue;
JsonObject obj = new JsonObject();
for(IDependency dependency : module.getDependencies(keyType, valueType)) {
String key = dependency.getName();
if(key != null) obj.addProperty(key, true);
}
addModule(keyType, valueType, true, moduleName, obj);
}
}
return;
}
for(ClassType keyType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, keyType)) continue;
JsonObject obj = new JsonObject();
for(IDependency dependency : module.getDependencies(keyType, keyType)) {
String key = dependency.getName();
if(key != null) obj.addProperty(key, true);
}
addModule(keyType, keyType, false, moduleName, obj);
}
}
public void printModuleSettings(List<BaseModule> modules) {
JsonObject data = new JsonObject();
for(BaseModule module : modules) {
String moduleName = module.getModuleName();
if(module.isBiModule()) {
for(ClassType keyType : ModulePackage.TYPE) {
for(ClassType valueType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, valueType)) continue;
JsonObject obj = new JsonObject();
for(IDependency dependency : module.getDependencies(keyType, valueType)) {
String key = dependency.getName();
if(key != null) obj.addProperty(key, dependency.isLoaded(keyType, valueType).getJsonResult());
}
addModule(data, keyType, valueType, true, moduleName, obj);
}
}
continue;
}
for(ClassType keyType : ModulePackage.TYPE) {
if(!module.isModuleValid(keyType, keyType)) continue;
JsonObject obj = new JsonObject();
for(IDependency dependency : module.getDependencies(keyType, keyType)) {
String key = dependency.getName();
if(key != null) obj.addProperty(key, dependency.isLoaded(keyType, keyType).getJsonResult());
}
addModule(data, keyType, keyType, false, moduleName, obj);
}
}
try {
System.out.println();
JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));
writer.setIndent("\t");
Streams.write(data, writer);
writer.flush();
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
public void load() {
try(BufferedReader reader = Files.newBufferedReader(Paths.get("ModulSettings.json"))) {
data = JsonParser.parseReader(reader).getAsJsonObject();
loaded = true;
IDependency.flatten("", false, data, parsedData);
JsonElement element = data.get("Default");
LoadingState.setOptionalResolver(LoadingState.of(element == null ? true : element.getAsBoolean()));
}
catch(Exception e) { e.printStackTrace(); }
}
public void save() {
data.asMap().keySet().removeAll(moduleNames);
JsonObject result = new JsonObject();
for(String s : moduleNames) {
result.addProperty(s, true);
}
result.asMap().putAll(data.asMap());
try(JsonWriter writer = new JsonWriter(Files.newBufferedWriter(Paths.get("ModulSettings.json")))) {
writer.setIndent("\t");
Streams.write(result, writer);
}
catch(Exception e) { e.printStackTrace(); }
}
private void addModule(JsonObject data, ClassType keyType, ClassType valueType, boolean bi, String moduleName, JsonObject obj) {
JsonObject result = getObject(data, keyType.getClassPath(), true);
if(bi) {
result = getObject(result, valueType.getClassPath(), true);
}
result.add(moduleName, obj);
}
private void addModule(ClassType keyType, ClassType valueType, boolean bi, String moduleName, JsonObject obj) {
JsonObject result = getObject(data, keyType.getClassPath(), true);
if(bi) {
result = getObject(result, valueType.getClassPath(), true);
}
result.add(moduleName, obj);
}
private JsonObject getObject(JsonObject data, String name, boolean create) {
JsonObject obj = data.getAsJsonObject(name);
if(obj == null) {
obj = new JsonObject();
data.add(name, obj);
if(create) obj.addProperty("Enabled", true);
}
return obj;
}
}
@@ -0,0 +1,137 @@
package speiger.src.builder.dependencies;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeSet;
import java.util.function.Consumer;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.Requirements.Requirement;
@SuppressWarnings("javadoc")
public abstract class BaseDependency implements IDependency {
protected static boolean FETCH_FAILURES = false;
protected static Set<String> FAILURE_KEYS = new TreeSet<>();
protected final String name;
protected final boolean biType;
protected Map<String, LoadingState> dependencies;
protected List<IDependency> children = new ArrayList<>();
protected List<Requirement> requirements = new ArrayList<>();
protected ClassType keyType;
protected ClassType valueType;
public BaseDependency(String name, boolean biType) {
this.name = name;
this.biType = biType;
}
@Override
public String toString() {
return name;
}
@Override
public void set(Map<String, LoadingState> dependency) {
dependencies = dependency;
}
@Override
public IDependency addDependency(Requirement require) {
requirements.add(require);
require.dependency.addChild(this);
return this;
}
@Override
public void addChild(IDependency child) {
children.add(child);
}
@Override
public boolean isLeaf() {
return children.isEmpty();
}
@Override
public boolean isRoot() {
return requirements.isEmpty();
}
protected LoadingState getGlobalState() {
return dependencies.getOrDefault(name, LoadingState.OPTIONAL);
}
@Override
public String getLocalStateKey(ClassType keyType, ClassType valueType) {
return (biType ? keyType.getClassPath()+"-"+valueType.getClassPath() : keyType.getClassPath())+"-"+name;
}
protected LoadingState getLocalState(ClassType keyType, ClassType valueType) {
return dependencies.getOrDefault(getLocalStateKey(keyType, valueType), LoadingState.OPTIONAL);
}
protected LoadingState getReqirementState(ClassType keyType, ClassType valueType) {
LoadingState state = requirements.isEmpty() ? LoadingState.REQUIRED : LoadingState.OPTIONAL;
for(int i = 0,m=requirements.size();i<m;i++) {
state = state.merge(requirements.get(i).test(keyType, valueType));
}
return state.resolveIfUndefined();
}
@Override
public void resolveRequirements(ClassType keyType, ClassType valueType) {
if(!children.isEmpty()) {
for(IDependency child : children) {
if(child == this) continue;
child.resolveRequirements(keyType, valueType);
}
}
if(getLocalState(keyType, valueType) == LoadingState.REQUIRED) {
for(Requirement req : requirements) {
dependencies.putIfAbsent(req.key(keyType, valueType), LoadingState.REQUIRED);
}
}
}
@Override
public void validateDependency(Consumer<String> result, ClassType keyType, ClassType valueType) {
if(getLocalState(keyType, valueType) == LoadingState.REQUIRED) {
FETCH_FAILURES = true;
for(Requirement req : requirements) {
req.test(keyType, valueType);
}
FETCH_FAILURES = false;
if(FAILURE_KEYS.size() > 0) {
int size = FAILURE_KEYS.size();
StringJoiner joiner = new StringJoiner("], [", "[", "]");
FAILURE_KEYS.forEach(joiner::add);
FAILURE_KEYS.clear();
String joins = size > 1 ? "["+joiner.toString()+"]" : joiner.toString();
result.accept("["+getLocalStateKey(keyType, valueType)+"] Requires "+joins+" but it specifically has been disabled!");
}
}
}
@Override
public void set(ClassType key, ClassType value) {
this.keyType = key;
this.valueType = value;
}
@Override
public boolean isEnabled() {
if(keyType == null || keyType == null) return false;
return isLoaded(keyType, valueType).getJsonResult();
}
@Override
public String getName() {
return name;
}
}
@@ -0,0 +1,29 @@
package speiger.src.builder.dependencies;
import speiger.src.builder.ClassType;
@SuppressWarnings("javadoc")
public class FunctionDependency extends BaseDependency {
ModuleDependency owner;
public FunctionDependency(ModuleDependency owner, String name) {
super(name, owner.biType);
this.owner = owner;
}
@Override
public LoadingState isLoaded(ClassType key, ClassType value) {
if(dependencies == null) return LoadingState.REQUIRED;
LoadingState result = getLocalState(key, value);
if(FETCH_FAILURES && result == LoadingState.REJECTED) {
FAILURE_KEYS.add(getLocalStateKey(key, value));
}
return result.resolveIfUndefined().merge(getReqirementState(key, value));
}
@Override
public String getLocalStateKey(ClassType keyType, ClassType valueType) {
return (biType ? keyType.getClassPath()+"-"+valueType.getClassPath() : keyType.getClassPath())+"-"+owner.getName()+"-"+name;
}
}
@@ -0,0 +1,104 @@
package speiger.src.builder.dependencies;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Consumer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.Requirements.Requirement;
@SuppressWarnings("javadoc")
public interface IDependency {
public void set(Map<String, LoadingState> dependency);
public void set(ClassType key, ClassType value);
public LoadingState isLoaded(ClassType key, ClassType value);
public String getLocalStateKey(ClassType keyType, ClassType valueType);
public boolean isEnabled();
public boolean isLeaf();
public boolean isRoot();
public String getName();
public void validateDependency(Consumer<String> result, ClassType keyType, ClassType valueType);
public void resolveRequirements(ClassType keyType, ClassType valueType);
public void addChild(IDependency child);
public <T extends IDependency> T addDependency(Requirement require);
public default <T extends IDependency> T addKeyDependency(IDependency dependency) { return addDependency(new Requirement(dependency, Requirements.KEY_TEST, Requirements.KEY_GETTER)); }
public default <T extends IDependency> T addValueDependency(IDependency dependency) { return addDependency(new Requirement(dependency, Requirements.VALUE_TEST, Requirements.VALUE_GETTER)); }
public default <T extends IDependency> T addEntryDependency(IDependency dependency) { return addDependency(new Requirement(dependency, Requirements.ENTRY_TEST, Requirements.ENTRY_GETTER)); }
public default <T extends IDependency> T addTypeDependency(IDependency dependency, ClassType type) { return addDependency(new Requirement(dependency, Requirements.typedTest(type), Requirements.typedKey(type))); }
public default <T extends IDependency> T addOptionalTypeDependency(IDependency dependency, ClassType type, boolean key) { return addDependency(new Requirement(dependency, Requirements.optionalTest(type, key), Requirements.optionalKey(type, key))); }
public default <T extends IDependency> T addOptionalTypeDependency(ClassType type, boolean key) { return addDependency(new Requirement(this, Requirements.optionalTest(type, key), Requirements.optionalKey(type, key))); }
public static void flatten(String prefix, boolean applyMiddle, JsonObject object, Map<String, LoadingState> result) {
if(applyMiddle) prefix+="-";
for(Entry<String, JsonElement> entry : object.entrySet()) {
String key = entry.getKey();
JsonElement value = entry.getValue();
if(value instanceof JsonPrimitive) {
String entryKey = prefix+key;
if("Enabled".equalsIgnoreCase(key)) {
entryKey = prefix.substring(0, prefix.length()-1);
}
result.put(entryKey, LoadingState.of(((JsonPrimitive)value).getAsBoolean()));
}
if(value instanceof JsonObject) {
flatten(prefix+key, true, (JsonObject)value, result);
}
}
}
public static enum LoadingState {
OPTIONAL,
REQUIRED,
REJECTED;
private static LoadingState RESOLVED = LoadingState.REQUIRED;
public static LoadingState of(boolean value) {
return value ? REQUIRED : REJECTED;
}
public LoadingState merge(LoadingState merge) {
return ordinal() > merge.ordinal() ? this : merge;
}
public LoadingState replaceIfUndefined(LoadingState state) {
return this == OPTIONAL ? state : this;
}
public LoadingState resolveIfUndefined() {
return this == OPTIONAL ? RESOLVED : this;
}
public LoadingState mergeDown(LoadingState merge) {
if(merge == REJECTED || ordinal() > merge.ordinal()) {
return this;
}
return merge;
}
public LoadingState mergeUp(LoadingState merge) {
if(merge == REQUIRED || ordinal() > merge.ordinal()) {
return this;
}
return merge;
}
public static void setOptionalResolver(LoadingState state) {
RESOLVED = state;
}
public boolean getJsonResult() {
LoadingState state = this == OPTIONAL ? RESOLVED : this;
return state == REQUIRED;
}
}
}
@@ -0,0 +1,31 @@
package speiger.src.builder.dependencies;
import speiger.src.builder.ClassType;
import speiger.src.builder.modules.BaseModule;
@SuppressWarnings("javadoc")
public class ModuleDependency extends BaseDependency {
BaseModule owner;
public ModuleDependency(BaseModule owner, boolean biType) {
super(owner.getModuleName(), biType);
this.owner = owner;
}
public FunctionDependency createDependency(String name) {
FunctionDependency result = new FunctionDependency(this, name);
if(biType) result.addEntryDependency(this);
else result.addKeyDependency(this);
return result;
}
@Override
public LoadingState isLoaded(ClassType key, ClassType value) {
if(dependencies == null) return LoadingState.REQUIRED;
LoadingState result = getLocalState(key, value);
if(FETCH_FAILURES && result == LoadingState.REJECTED) {
FAILURE_KEYS.add(getLocalStateKey(key, value));
}
return result.replaceIfUndefined(getGlobalState()).resolveIfUndefined().merge(getReqirementState(key, value));
}
}
@@ -0,0 +1,68 @@
package speiger.src.builder.dependencies;
import java.util.function.Consumer;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.IDependency.LoadingState;
@SuppressWarnings("javadoc")
public class Requirements {
public static final RequirementTest KEY_TEST = (T, K, V) -> T.isLoaded(K, K);
public static final RequirementTest VALUE_TEST = (T, K, V) -> T.isLoaded(V, V);
public static final RequirementTest ENTRY_TEST = (T, K, V) -> T.isLoaded(K, V);
public static RequirementTest typedTest(ClassType type) {
return (T, K, V) -> T.isLoaded(type, type);
}
public static RequirementTest optionalTest(ClassType type, boolean key) {
return (T, K, V) -> (key ? K : V) != type ? T.isLoaded(type, type) : LoadingState.REQUIRED;
}
public static final RequirementKey KEY_GETTER = (T, K, V) -> T.getLocalStateKey(K, K);
public static final RequirementKey VALUE_GETTER = (T, K, V) -> T.getLocalStateKey(V, V);
public static final RequirementKey ENTRY_GETTER = (T, K, V) -> T.getLocalStateKey(K, V);
public static RequirementKey typedKey(ClassType type) {
return (T, K, V) -> T.getLocalStateKey(type, type);
}
public static RequirementKey optionalKey(ClassType type, boolean key) {
return (T, K, V) -> (key ? K : V) != type ? T.getLocalStateKey(type, type) : "";
}
public interface RequirementTest {
public LoadingState test(IDependency test, ClassType keyType, ClassType valueType);
}
public static interface RequirementKey {
public String key(IDependency test, ClassType keyType, ClassType valueType);
}
public static interface RequirementResolver {
public void resolve(IDependency test, Consumer<String> result, ClassType keyType, ClassType valueType);
}
public static class Requirement {
IDependency dependency;
RequirementTest test;
RequirementKey key;
public Requirement(IDependency dependency, RequirementTest test, RequirementKey key) {
this.dependency = dependency;
this.test = test;
this.key = key;
}
public LoadingState test(ClassType keyType, ClassType valueType) {
return test.test(dependency, keyType, valueType);
}
public String key(ClassType keyType, ClassType valueType) {
return key.key(dependency, keyType, valueType);
}
}
}
@@ -0,0 +1,53 @@
package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class AsyncModule extends BaseModule
{
public static final BaseModule INSTANCE = new AsyncModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(JavaModule.MODULE);
@Override
public String getModuleName() { return "Async"; }
@Override
protected void loadVariables() {}
@Override
protected void loadRemappers() {}
@Override
protected void loadTestClasses() {}
@Override
protected void loadFunctions() {}
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE); }
@Override
protected void loadBlockades() {
if(!MODULE.isEnabled()) {
addBlockedFiles("AsyncBuilder", "Task");
}
}
@Override
protected void loadFlags() {
if(MODULE.isEnabled()) {
addKeyFlag("ASYNC_MODULE");
}
}
@Override
protected void loadClasses()
{
//Implementation Classes
addClassMapper("ASYNC_BUILDER", "AsyncBuilder");
//Abstract Classes
addAbstractMapper("BASE_TASK", "Base%sTask");
//Interfaces
addClassMapper("TASK", "Task");
}
}
@@ -0,0 +1,198 @@
package speiger.src.builder.modules;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import speiger.src.builder.ClassType;
import speiger.src.builder.ModulePackage;
import speiger.src.builder.RequiredType;
import speiger.src.builder.SettingsManager;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.mappers.ArgumentMapper;
import speiger.src.builder.mappers.InjectMapper;
import speiger.src.builder.mappers.LineMapper;
import speiger.src.builder.mappers.SimpleMapper;
@SuppressWarnings("javadoc")
public abstract class BaseModule
{
SettingsManager manager;
ModulePackage entry;
protected ClassType keyType;
protected ClassType valueType;
public final void setManager(SettingsManager manager) {
this.manager = manager;
manager.addModule(this);
}
public final void init(ModulePackage entry) {
this.entry = entry;
keyType = entry.getKeyType();
valueType = entry.getValueType();
for(IDependency dependency : getDependencies(keyType, valueType)) {
dependency.set(keyType, valueType);
}
loadVariables();
loadClasses();
loadTestClasses();
loadFunctions();
loadRemappers();
loadBlockades();
loadFlags();
}
public final void cleanup() {
entry = null;
keyType = null;
valueType = null;
manager = null;
}
protected abstract void loadVariables();
protected abstract void loadClasses();
protected abstract void loadTestClasses();
protected abstract void loadFunctions();
protected abstract void loadRemappers();
protected abstract void loadBlockades();
protected abstract void loadFlags();
public abstract String getModuleName();
public boolean isBiModule() { return false; }
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Collections.emptyList(); }
public boolean isModuleValid(ClassType keyType, ClassType valueType) { return true; }
public ClassType keyType() { return keyType; }
public ClassType valueType() { return valueType; }
protected void addFlag(String name) {
entry.addFlag(name);
}
protected void addValue(String name, int value) {
entry.addValue(name, value);
}
protected void addKeyFlag(String name) {
entry.addFlag(name);
entry.addGlobalFlag(keyType.getCapType()+"_"+name);
}
protected void addBiRequirement(String fileName) {
entry.addRequirement(fileName, RequiredType.BI_CLASS);
entry.addSplitter(fileName, "%1$s2%2$s");
}
protected void addEnumRequirement(String fileName) {
entry.addRequirement(fileName, RequiredType.ENUM);
entry.addSplitter(fileName, "%2$s");
}
protected void addBiRequirement(String fileName, String splitter) {
entry.addRequirement(fileName, RequiredType.BI_CLASS);
entry.addSplitter(fileName, "%1$s"+splitter+"%2$s");
}
protected void addRequirement(String fileName, String splitter, RequiredType type) {
entry.addRequirement(fileName, type);
entry.addSplitter(fileName, splitter);
}
protected void addRemapper(String fileName, String actualName) {
entry.addRemapper(fileName, actualName);
}
protected void addBlockedFiles(String... name) {
entry.addBlockedFiles(name);
}
protected void addBlockedFilter(Predicate<String> filter) {
entry.addBlockedFilter(filter);
}
protected void addClassMapper(String pattern, String replacement) {
entry.addMapper(new SimpleMapper("VALUE_"+pattern, "VALUE_"+pattern, valueType.getFileType()+replacement));
entry.addMapper(new SimpleMapper(pattern, pattern, keyType.getFileType()+replacement));
}
protected void addBiClassMapper(String pattern, String replacement, String splitter) {
entry.addMapper(new SimpleMapper("KEY_"+pattern, "KEY_"+pattern, keyType.getFileType()+splitter+keyType.getFileType()+replacement));
entry.addMapper(new SimpleMapper("VALUE_"+pattern, "VALUE_"+pattern, valueType.getFileType()+splitter+valueType.getFileType()+replacement));
entry.addMapper(new SimpleMapper(pattern, pattern, keyType.getFileType()+splitter+valueType.getFileType()+replacement));
}
protected void addAbstractMapper(String pattern, String replacement) {
entry.addMapper(new SimpleMapper("VALUE_"+pattern, "VALUE_"+pattern, String.format(replacement, valueType.getFileType())));
entry.addMapper(new SimpleMapper(pattern, pattern, String.format(replacement, keyType.getFileType())));
}
protected void addAbstractBiMapper(String pattern, String replacement, String splitter) {
entry.addMapper(new SimpleMapper(pattern, pattern, String.format(replacement, keyType.getFileType()+splitter+valueType.getFileType())));
}
protected void addFunctionMapper(String pattern, String replacement) {
entry.addMapper(new SimpleMapper("VALUE_"+pattern, "VALUE_"+pattern, replacement+valueType.getNonFileType()));
entry.addMapper(new SimpleMapper(pattern, pattern, replacement+keyType.getNonFileType()));
}
protected void addFunctionValueMapper(String pattern, String replacement) {
entry.addMapper(new SimpleMapper(pattern, pattern, replacement+valueType.getNonFileType()));
}
protected void addFunctionMappers(String pattern, String replacement) {
entry.addMapper(new SimpleMapper("VALUE_"+pattern, "VALUE_"+pattern, String.format(replacement, valueType.getNonFileType())));
entry.addMapper(new SimpleMapper(pattern, pattern, String.format(replacement, keyType.getNonFileType())));
}
protected void addFunctionValueMappers(String pattern, String replacement) {
entry.addMapper(new SimpleMapper(pattern, pattern, String.format(replacement, valueType.getNonFileType())));
}
protected void addSimpleMapper(String pattern, String replacement) {
entry.addMapper(new SimpleMapper(pattern, pattern, replacement));
}
protected void addAnnontion(String pattern, String value) {
if(keyType == ClassType.OBJECT) entry.addMapper(new LineMapper(pattern, pattern));
else entry.addMapper(new SimpleMapper(pattern, pattern, value));
}
protected void addValueAnnontion(String pattern, String value) {
if(valueType == ClassType.OBJECT) entry.addMapper(new LineMapper(pattern, pattern));
else entry.addMapper(new SimpleMapper(pattern, pattern, value));
}
protected void addComment(String pattern, String value) {
if(keyType == ClassType.OBJECT) entry.addMapper(new InjectMapper(pattern, pattern, value).removeBraces());
else entry.addMapper(new LineMapper(pattern, pattern));
}
protected void addValueComment(String pattern, String value) {
if(valueType == ClassType.OBJECT) entry.addMapper(new InjectMapper(pattern, pattern, value).removeBraces());
else entry.addMapper(new LineMapper(pattern, pattern));
}
protected InjectMapper addInjectMapper(String pattern, String replacement) {
InjectMapper mapper = new InjectMapper(pattern, pattern, replacement);
entry.addMapper(mapper);
return mapper;
}
protected ArgumentMapper addArgumentMapper(String pattern, String replacement) {
return addArgumentMapper(pattern, replacement, ", ");
}
protected ArgumentMapper addArgumentMapper(String pattern, String replacement, String splitter) {
ArgumentMapper mapper = new ArgumentMapper(pattern, pattern, replacement, splitter);
entry.addMapper(mapper);
return mapper;
}
public static <T> T make(T input, Consumer<T> processor) {
processor.accept(input);
return input;
}
}
@@ -0,0 +1,135 @@
package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class CollectionModule extends BaseModule
{
public static final BaseModule INSTANCE = new CollectionModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false)
.addKeyDependency(FunctionModule.MODULE)
.addOptionalTypeDependency(FunctionModule.MODULE, ClassType.OBJECT, true)
.addOptionalTypeDependency(FunctionModule.MODULE, ClassType.INT, true)
.addOptionalTypeDependency(ClassType.OBJECT, true);
public static final FunctionDependency STREAMS = MODULE.createDependency("Streams");
public static final FunctionDependency SPLIT_ITERATORS = MODULE.createDependency("Splititerators").addKeyDependency(STREAMS);
public static final FunctionDependency IARRAY = MODULE.createDependency("IArray");
public static final FunctionDependency STRATEGY = MODULE.createDependency("Strategy");
@Override
public String getModuleName() { return "Collection"; }
@Override
protected void loadVariables() {}
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, STREAMS, SPLIT_ITERATORS, IARRAY, STRATEGY); }
@Override
protected void loadFlags() {
if(MODULE.isEnabled()) addKeyFlag("COLLECTION_MODULE");
if(STREAMS.isEnabled()) addKeyFlag("STREAM_FEATURE");
if(SPLIT_ITERATORS.isEnabled()) addKeyFlag("SPLIT_ITERATOR_FEATURE");
if(IARRAY.isEnabled()) addKeyFlag("IARRAY_FEATURE");
}
@Override
protected void loadBlockades() {
if(!MODULE.isEnabled()) {
addBlockedFiles("Iterable", "Iterables", "Iterator", "Iterators", "BidirectionalIterator", "ListIterator");
addBlockedFiles("Arrays", "Collection", "AbstractCollection", "Collections", "Stack");
}
if(!SPLIT_ITERATORS.isEnabled()) addBlockedFiles("Splititerator", "Splititerators");
if(!IARRAY.isEnabled()) addBlockedFiles("IArray");
if(!STRATEGY.isEnabled()) addBlockedFiles("Strategy");
if(keyType.isObject())
{
addBlockedFiles("Stack");
addBlockedFiles("CollectionStreamTester");
}
if(keyType == ClassType.BOOLEAN)
{
addBlockedFiles("CollectionRemoveIfTester", "CollectionStreamTester");
addBlockedFilter(T -> T.endsWith("Tester") && T.startsWith("Iterable"));
}
}
@Override
protected void loadRemappers()
{
//Main Classes
addRemapper("IArray", "I%sArray");
addRemapper("AbstractCollection", "Abstract%sCollection");
//Test Classes
addRemapper("AbstractIteratorTester", "Abstract%sIteratorTester");
addRemapper("MinimalCollection", "Minimal%sCollection");
addRemapper("TestCollectionGenerator", "Test%sCollectionGenerator");
addRemapper("AbstractContainerTester", "Abstract%sContainerTester");
addRemapper("AbstractCollectionTester", "Abstract%sCollectionTester");
addRemapper("SimpleTestGenerator", "Simple%sTestGenerator");
}
@Override
protected void loadFunctions()
{
addFunctionMapper("NEXT", "next");
addSimpleMapper("NEW_STREAM", keyType.isPrimitiveBlocking() ? "" : keyType.getCustomJDKType().getKeyType()+"Stream");
addFunctionMapper("PREVIOUS", "previous");
addFunctionMapper("REMOVE_KEY", "rem");
addSimpleMapper("TO_ARRAY", "to"+keyType.getNonFileType()+"Array");
addSimpleMapper("VALUE_TO_ARRAY", "to"+valueType.getNonFileType()+"Array");
}
@Override
protected void loadClasses()
{
//Abstract Classes
addAbstractMapper("ABSTRACT_COLLECTION", "Abstract%sCollection");
//Helper Classes
addClassMapper("ARRAYS", "Arrays");
addClassMapper("COLLECTIONS", "Collections");
addClassMapper("ITERABLES", "Iterables");
addClassMapper("SPLIT_ITERATORS", "Splititerators");
addClassMapper("ITERATORS", "Iterators");
//Interfaces
addClassMapper("COLLECTION", "Collection");
addClassMapper("ITERABLE", "Iterable");
addClassMapper("SPLIT_ITERATOR", "Splititerator");
addClassMapper("LIST_ITERATOR", "ListIterator");
addClassMapper("BI_ITERATOR", "BidirectionalIterator");
addClassMapper("ITERATOR", "Iterator");
if(keyType.isObject()) addSimpleMapper("STACK", "Stack");
else addClassMapper("STACK", "Stack");
addClassMapper("STRATEGY", "Strategy");
}
@Override
protected void loadTestClasses()
{
//Implementation Classes
addAbstractMapper("MINIMAL_COLLECTION", "Minimal%sCollection");
addClassMapper("BIDIRECTIONAL_ITERATOR_TESTER", "BidirectionalteratorTester");
addClassMapper("LIST_ITERATOR_TESTER", "ListIteratorTester");
addClassMapper("ITERATOR_TESTER", "IteratorTester");
addClassMapper("COLLECTION_TEST_BUILDER", "CollectionTestSuiteBuilder");
addClassMapper("COLLECTION_CONSTRUCTOR_TESTS", "CollectionConstructorTests");
//Abstract Classes
addAbstractMapper("ABSTRACT_COLLECTION_TESTER", "Abstract%sCollectionTester");
addAbstractMapper("ABSTRACT_CONTAINER_TESTER", "Abstract%sContainerTester");
addAbstractMapper("ABSTRACT_ITERATOR_TESTER", "Abstract%sIteratorTester");
//Helper Classes
addAbstractMapper("TEST_COLLECTION_GENERATOR", "Test%sCollectionGenerator");
addAbstractMapper("SIMPLE_TEST_GENERATOR", "Simple%sTestGenerator");
}
}
@@ -0,0 +1,119 @@
package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.RequiredType;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class FunctionModule extends BaseModule
{
public static final BaseModule INSTANCE = new FunctionModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(JavaModule.MODULE);
@Override
public String getModuleName() { return "Function"; }
@Override
public boolean isBiModule() { return true; }
@Override
protected void loadVariables() {}
@Override
protected void loadFlags() {}
@Override
protected void loadTestClasses() {}
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) {
return Arrays.asList(MODULE);
}
@Override
protected void loadBlockades()
{
if(keyType.isObject()) addBlockedFiles("Consumer", "Comparator");
if(!MODULE.isEnabled()) addBlockedFiles("Consumer", "BiConsumer", "Comparator", "Supplier", "Function", "UnaryOperator");
}
@Override
protected void loadRemappers()
{
addBiRequirement("BiConsumer", "");
addBiRequirement("UnaryOperator", "");
if(valueType == ClassType.BOOLEAN) {
addRequirement("Function", "%1$s", RequiredType.BI_CLASS);
addRemapper("Function", (keyType.isObject() ? "" : "%s")+"Predicate");
}
else if(keyType.isObject() && !valueType.isObject()) {
addRequirement("Function", "%2$s", RequiredType.BI_CLASS);
addRemapper("Function", "To%sFunction");
}
else if(keyType == valueType) {
addRequirement("Function", "%1$s", RequiredType.BI_CLASS);
addRemapper("Function", (keyType.isObject() ? "" : "%s")+"UnaryOperator");
}
else if(valueType.isObject()) {
addRequirement("Function", "%1$s", RequiredType.BI_CLASS);
addRemapper("Function", "%sFunction");
}
else addBiRequirement("Function");
addRemapper("BiConsumer", "%sConsumer");
}
@Override
protected void loadFunctions()
{
addSimpleMapper("APPLY", keyType.getApply(valueType));
addSimpleMapper("SUPPLY_GET", keyType.isObject() ? "get" : "getAs"+keyType.getNonFileType());
addSimpleMapper("VALUE_SUPPLY_GET", valueType.isObject() ? "get" : "getAs"+valueType.getNonFileType());
}
@Override
protected void loadClasses()
{
//Interfaces
addBiClassMapper("BI_CONSUMER", "Consumer", "");
addClassMapper("BI_TO_OBJECT_CONSUMER", "ObjectConsumer");
addAbstractMapper("BI_FROM_OBJECT_CONSUMER", "Object%sConsumer");
addAbstractMapper("BI_FROM_INT_CONSUMER", "Int%sConsumer");
if(keyType.isObject()) {
addSimpleMapper("TO_OBJECT_FUNCTION", keyType.getNonFileType()+"UnaryOperator");
addSimpleMapper("VALUE_TO_OBJECT_FUNCTION", valueType.isObject() ? "UnaryOperator" : valueType.getFileType()+"Function");
}
else {
addSimpleMapper("TO_OBJECT_FUNCTION", keyType.getNonFileType()+"Function");
addSimpleMapper("VALUE_TO_OBJECT_FUNCTION", valueType.isObject() ? "UnaryOperator" : valueType.getFileType()+"Function");
}
if(valueType == ClassType.BOOLEAN) addFunctionMappers("FUNCTION", "%sPredicate");
else if(keyType.isObject() && !valueType.isObject()) addFunctionValueMappers("FUNCTION", "To%sFunction");
else if(keyType == valueType) addFunctionMappers("FUNCTION", "%sUnaryOperator");
else if(valueType.isObject()) addFunctionMappers("FUNCTION", "%sFunction");
else addBiClassMapper("FUNCTION", "Function", "2");
addFunctionMappers("PREDICATE", "%sPredicate");
addClassMapper("SUPPLIER", "Supplier");
addAbstractMapper("SINGLE_UNARY_OPERATOR", "%1$s%1$sUnaryOperator");
addBiClassMapper("UNARY_OPERATOR", "UnaryOperator", "");
if(keyType.isObject())
{
if(!valueType.isObject()) addSimpleMapper("VALUE_CONSUMER", valueType.getFileType()+"Consumer");
else addSimpleMapper("VALUE_CONSUMER", "Consumer");
addSimpleMapper("CONSUMER", "Consumer");
addSimpleMapper("IARRAY", "IObjectArray");
}
else
{
if(valueType.isObject())
{
addSimpleMapper("VALUE_CONSUMER", "Consumer");
addSimpleMapper("CONSUMER", keyType.getFileType()+"Consumer");
}
else addClassMapper("CONSUMER", "Consumer");
addFunctionMappers("IARRAY", "I%sArray");
}
addSimpleMapper("VALUE_COMPARATOR", valueType.isObject() ? "Comparator" : String.format("%sComparator", valueType.getNonFileType()));
addSimpleMapper("COMPARATOR", keyType.isObject() ? "Comparator" : String.format("%sComparator", keyType.getNonFileType()));
}
}
@@ -0,0 +1,232 @@
package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class JavaModule extends BaseModule
{
public static final BaseModule INSTANCE = new JavaModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false);
@Override
public String getModuleName() { return "Base"; }
@Override
protected void loadVariables()
{
createHelperVars(keyType, false, "KEY");
createHelperVars(valueType, true, "VALUE");
loadBaseVariables();
}
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) {
return Arrays.asList(MODULE);
}
@Override
protected void loadFlags()
{
addFlag("TYPE_"+keyType.getCapType());
addFlag("VALUE_"+valueType.getCapType());
addValue("JAVA_VERSION", getVersion());
if(keyType == valueType) addFlag("SAME_TYPE");
if(keyType.hasFunction(valueType)) addFlag("JDK_FUNCTION");
if(!keyType.needsCustomJDKType()) addFlag("JDK_TYPE");
if(!keyType.isPrimitiveBlocking()) addFlag("PRIMITIVES");
if(!valueType.isPrimitiveBlocking()) addFlag("VALUE_PRIMITIVES");
if(!valueType.needsCustomJDKType()) addFlag("JDK_VALUE");
}
private int getVersion() {
String version = System.getProperty("java.version");
if(version.startsWith("1.")) return Integer.parseInt(version.substring(2, 3));
int dot = version.indexOf(".");
return Integer.parseInt(dot != -1 ? version.substring(0, dot) : version);
}
@Override
protected void loadRemappers() {}
@Override
protected void loadBlockades() {}
@Override
protected void loadFunctions()
{
addSimpleMapper("APPLY_KEY_VALUE", keyType.isObject() ? "apply" : "applyAs"+keyType.getNonFileType());
addSimpleMapper("APPLY_VALUE", valueType.isObject() ? "apply" : "applyAs"+valueType.getNonFileType());
addSimpleMapper("APPLY_CAST", "applyAs"+keyType.getCustomJDKType().getNonFileType());
//Shared by Maps and Pairs so moved to java.
addFunctionMappers("ENTRY_KEY", "get%sKey");
addFunctionValueMappers("ENTRY_VALUE", "get%sValue");
addFunctionMappers("KEY_ENTRY", "set%sKey");
addFunctionValueMappers("VALUE_ENTRY", "set%sValue");
}
@Override
protected void loadClasses()
{
if(getVersion() >= 17) addSimpleMapper("RANDOM", "RandomGenerator");
else addSimpleMapper("RANDOM", "Random");
addSimpleMapper("JAVA_PREDICATE", keyType.isPrimitiveBlocking() ? "" : keyType.getCustomJDKType().getFileType()+"Predicate");
addSimpleMapper("JAVA_CONSUMER", keyType.isPrimitiveBlocking() ? "" : "java.util.function."+keyType.getCustomJDKType().getFileType()+"Consumer");
addSimpleMapper("JAVA_SUPPLIER", keyType.isPrimitiveBlocking() ? "" : "java.util.function."+keyType.getCustomJDKType().getFileType()+"Supplier");
addSimpleMapper("JAVA_FUNCTION", keyType.getFunctionClass(valueType));
addSimpleMapper("JAVA_BINARY_OPERATOR", keyType == ClassType.BOOLEAN ? "" : (keyType.isObject() ? "java.util.function.BinaryOperator" : "java.util.function."+keyType.getCustomJDKType().getFileType()+"BinaryOperator"));
addSimpleMapper("JAVA_UNARY_OPERATOR", keyType.isObject() ? "BinaryOperator" : keyType == ClassType.BOOLEAN ? "" : keyType.getCustomJDKType().getFileType()+"UnaryOperator");
addSimpleMapper("JAVA_SPLIT_ITERATOR", keyType.isPrimitiveBlocking() ? "Spliterator" : "Of"+keyType.getCustomJDKType().getFileType());
addSimpleMapper("JAVA_STREAM", keyType.isPrimitiveBlocking() ? "" : keyType.getCustomJDKType().getFileType()+"Stream");
addSimpleMapper("JAVA_BUFFER", keyType.getFileType()+"Buffer");
}
@Override
protected void loadTestClasses()
{
addClassMapper("HELPERS", "Helpers");
addClassMapper("SAMPLE_ELEMENTS", "Samples");
}
private void loadBaseVariables()
{
addSimpleMapper("VALUE_PACKAGE", valueType.getPathType());
addSimpleMapper("PACKAGE", keyType.getPathType());
addSimpleMapper("CLASS_TYPE", keyType.getClassType());
addSimpleMapper("CLASS_VALUE_TYPE", valueType.getClassValueType());
addSimpleMapper("KEY_TYPE", keyType.getKeyType());
addSimpleMapper("KEY_OBJECT_TYPE", keyType.isObject() ? "Object" : keyType.getKeyType());
addSimpleMapper("KEY_STRING_TYPE", keyType.isObject() ? "String" : keyType.getKeyType());
addSimpleMapper("KEY_SPECIAL_TYPE", keyType.isObject() ? "E" : keyType.getKeyType());
addSimpleMapper("CLASS_OBJECT_TYPE", keyType.getClassType());
addSimpleMapper("CLASS_OBJECT_VALUE_TYPE", valueType.getClassValueType());
addSimpleMapper("CLASS_STRING_TYPE", keyType.isObject() ? "String" : keyType.getClassType());
addSimpleMapper("CLASS_STRING_VALUE_TYPE", valueType.isObject() ? "String" : valueType.getClassValueType());
addSimpleMapper("VALUE_TYPE", valueType.getValueType());
addSimpleMapper("VALUE_OBJECT_TYPE", valueType.isObject() ? "Object" : valueType.getValueType());
addSimpleMapper("VALUE_STRING_TYPE", valueType.isObject() ? "String" : valueType.getValueType());
addSimpleMapper("VALUE_SPECIAL_TYPE", valueType.isObject() ? "E" : valueType.getKeyType());
addSimpleMapper("KEY_JAVA_TYPE", keyType.getCustomJDKType().getKeyType());
addSimpleMapper("VALUE_JAVA_TYPE", keyType.getCustomJDKType().getKeyType());
addSimpleMapper("EMPTY_KEY_VALUE", keyType.getEmptyValue());
addSimpleMapper("EMPTY_VALUE", valueType.getEmptyValue());
addSimpleMapper("INVALID_KEY_VALUE", keyType.getInvalidValue());
addSimpleMapper("INVALID_VALUE", valueType.getInvalidValue());
addSimpleMapper(" KEY_STRING_GENERIC_TYPE", keyType.isObject() ? "<String>" : "");
addSimpleMapper(" VALUE_STRING_GENERIC_TYPE", valueType.isObject() ? "<String>" : "");
addSimpleMapper(" KEY_VALUE_STRING_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<String, String>" : "<String>") : (valueType.isObject() ? "<String>" : ""));
addSimpleMapper(" KEY_SAME_GENERIC_TYPE", keyType.isObject() ? "<T, T>" : "");
addSimpleMapper(" VALUE_SAME_GENERIC_TYPE", keyType.isObject() ? "<V, V>" : "");
addSimpleMapper(" KEY_GENERIC_TYPE", keyType.isObject() ? "<"+keyType.getKeyType()+">" : "");
addSimpleMapper(" KEY_KEY_GENERIC_TYPE", keyType.isObject() ? "<"+keyType.getKeyType()+", "+keyType.getKeyType()+">" : "");
addSimpleMapper(" KEY_CLASS_GENERIC_TYPE", keyType.isObject() ? "<"+keyType.getClassType()+">" : "");
addSimpleMapper(" VALUE_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+">" : "");
addSimpleMapper(" VALUE_VALUE_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : "");
addSimpleMapper(" VALUE_CLASS_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getClassValueType()+">" : "");
addSimpleMapper(" KEY_VALUE_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<"+keyType.getKeyType()+", "+valueType.getValueType()+">" : "<"+keyType.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+">" : ""));
addSimpleMapper(" KEY_VALUE_VALUE_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<"+keyType.getKeyType()+", "+valueType.getValueType()+", "+valueType.getValueType()+">" : "<"+keyType.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : ""));
addInjectMapper(" KEY_VALUE_SPECIAL_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<"+keyType.getKeyType()+", "+valueType.getValueType()+", %s>" : "<"+keyType.getKeyType()+", %s>") : (valueType.isObject() ? "<"+valueType.getValueType()+", %s>" : "<%s>")).setBraceType("<>").removeBraces();
addSimpleMapper(" NO_GENERIC_TYPE", keyType.isObject() ? "<?>" : "");
addSimpleMapper(" NO_KV_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<?, ?>" : "<?>") : valueType.isObject() ? "<?>" : "");
addSimpleMapper(" KEY_COMPAREABLE_TYPE", keyType.isObject() ? "<"+keyType.getKeyType()+" extends Comparable<T>>" : "");
addSimpleMapper(" KEY_SUPER_GENERIC_TYPE", keyType.isObject() ? "<? super "+keyType.getKeyType()+">" : "");
addSimpleMapper(" VALUE_SUPER_GENERIC_TYPE", valueType.isObject() ? "<? super "+valueType.getValueType()+">" : "");
addSimpleMapper(" KEY_VALUE_SUPER_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<? super "+keyType.getKeyType()+", ? super "+valueType.getValueType()+">" : "<? super "+keyType.getKeyType()+">") : (valueType.isObject() ? "<? super "+valueType.getValueType()+">" : ""));
addSimpleMapper(" KEY_UNKNOWN_GENERIC_TYPE", keyType.isObject() ? "<? extends "+keyType.getKeyType()+">" : "");
addSimpleMapper(" VALUE_UNKNOWN_GENERIC_TYPE", valueType.isObject() ? "<? extends "+valueType.getValueType()+">" : "");
addSimpleMapper(" KEY_VALUE_UNKNOWN_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<? extends "+keyType.getKeyType()+", ? extends "+valueType.getValueType()+">" : "<? extends "+keyType.getKeyType()+">") : (valueType.isObject() ? "<? extends "+valueType.getValueType()+">" : ""));
addSimpleMapper(" KEY_ENUM_VALUE_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<"+keyType.getKeyType()+" extends Enum<"+keyType.getKeyType()+">, "+valueType.getValueType()+">" : "<"+keyType.getKeyType()+" extends Enum<"+keyType.getKeyType()+">>") : (valueType.isObject() ? "<"+valueType.getValueType()+">" : ""));
addSimpleMapper(" KEY_VALUE_ENUM_GENERIC_TYPE", keyType.isObject() ? (valueType.isObject() ? "<"+keyType.getKeyType()+", "+valueType.getValueType()+" extends Enum<"+valueType.getValueType()+">>" : "<"+keyType.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+" extends Enum<"+valueType.getValueType()+">>" : ""));
addInjectMapper(" KEY_SPECIAL_GENERIC_TYPE", keyType.isObject() ? "<%s>" : "").removeBraces().setBraceType("<>");
addInjectMapper(" VALUE_SPECIAL_GENERIC_TYPE", valueType.isObject() ? "<%s>" : "").removeBraces().setBraceType("<>");
addInjectMapper(" KSK_GENERIC_TYPE", keyType.isObject() ? "<%s, "+keyType.getKeyType()+">" : "<%s>").removeBraces().setBraceType("<>");
addInjectMapper(" KKS_GENERIC_TYPE", keyType.isObject() ? "<"+keyType.getKeyType()+", %s>" : "<%s>").removeBraces().setBraceType("<>");
addArgumentMapper(" KSS_GENERIC_TYPE", keyType.isObject() ? "<%1$s, %2$s>" : "<%2$s>").removeBraces().setBraceType("<>");
addInjectMapper(" SK_GENERIC_TYPE", keyType.isObject() ? "<%s, "+keyType.getKeyType()+">" : "").removeBraces().setBraceType("<>");
addInjectMapper(" KS_GENERIC_TYPE", keyType.isObject() ? "<"+keyType.getKeyType()+", %s>" : "").removeBraces().setBraceType("<>");
addInjectMapper(" VSV_GENERIC_TYPE", valueType.isObject() ? "<%s, "+valueType.getValueType()+">" : "<%s>").removeBraces().setBraceType("<>");
addInjectMapper(" VVS_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+", %s>" : "<%s>").removeBraces().setBraceType("<>");
addArgumentMapper(" VSS_GENERIC_TYPE", valueType.isObject() ? "<%1$s, %2$s>" : "<%2$s>").removeBraces().setBraceType("<>");
addInjectMapper(" SV_GENERIC_TYPE", valueType.isObject() ? "<%s, "+valueType.getValueType()+">" : "").removeBraces().setBraceType("<>");
addInjectMapper(" VS_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+", %s>" : "").removeBraces().setBraceType("<>");
addSimpleMapper(" GENERIC_KEY_BRACES", keyType.isObject() ? " <"+keyType.getKeyType()+">" : "");
addSimpleMapper(" GENERIC_VALUE_BRACES", valueType.isObject() ? " <"+valueType.getValueType()+">" : "");
addInjectMapper(" GENERIC_SPECIAL_KEY_BRACES", keyType.isObject() ? " <%s>" : "").removeBraces().setBraceType("<>");
addInjectMapper(" GENERIC_SPECIAL_VALUE_BRACES", valueType.isObject() ? " <%s>" : "").removeBraces().setBraceType("<>");
addSimpleMapper(" GENERIC_KEY_ENUM_VALUE_BRACES", keyType.isObject() ? (valueType.isObject() ? " <"+keyType.getKeyType()+" extends Enum<"+keyType.getKeyType()+">, "+valueType.getValueType()+">" : " <"+keyType.getKeyType()+" extends Enum<"+keyType.getKeyType()+">>") : (valueType.isObject() ? " <"+valueType.getValueType()+">" : ""));
addInjectMapper(" GENERIC_KEY_SPECIAL_BRACES", keyType.isObject() ? " <"+keyType.getKeyType()+", %s>" : " <%s>").removeBraces().setBraceType("<>");
addInjectMapper(" GENERIC_VALUE_SPECIAL_BRACES", valueType.isObject() ? " <"+valueType.getKeyType()+", %s>" : " <%s>").removeBraces().setBraceType("<>");
addSimpleMapper(" GENERIC_KEY_VALUE_BRACES", keyType.isObject() ? (valueType.isObject() ? " <"+keyType.getKeyType()+", "+valueType.getValueType()+">" : " <"+keyType.getKeyType()+">") : (valueType.isObject() ? " <"+valueType.getValueType()+">" : ""));
addSimpleMapper(" COMPAREABLE_KEY_BRACES", keyType.isObject() ? " <"+keyType.getKeyType()+" extends Comparable<T>>" : "");
addSimpleMapper("KV_BRACES", keyType.isObject() || valueType.isObject() ? "<>" : "");
addSimpleMapper("VALUE_BRACES", valueType.isObject() ? "<>" : "");
addSimpleMapper("BRACES", keyType.isObject() ? "<>" : "");
if(keyType.needsCustomJDKType())
{
addSimpleMapper("JAVA_TYPE", keyType.getCustomJDKType().getKeyType());
addSimpleMapper("SANITY_CAST", "castTo"+keyType.getFileType());
}
addSimpleMapper("JAVA_CLASS", keyType.getCustomJDKType().getClassType());
if(valueType.needsCustomJDKType())
{
addSimpleMapper("SANITY_CAST_VALUE", "castTo"+valueType.getFileType());
}
addSimpleMapper("[SPACE]", " ");
addComment("@ArrayType", "@param <%s> the keyType of array that the operation should be applied");
addComment("@Type", "@param <%s> the keyType of elements maintained by this Collection");
addValueComment("@ValueArrayType", "@param <%s> the keyType of array that the operation should be applied");
addValueComment("@ValueType", "@param <%s> the keyType of elements maintained by this Collection");
addAnnontion("@PrimitiveOverride", "@Override");
addSimpleMapper("@PrimitiveDoc", "");
addAnnontion("@Primitive", "@Deprecated");
addValueAnnontion("@ValuePrimitiveOverride", "@Override");
addValueAnnontion("@ValuePrimitive", "@Deprecated");
}
private void createHelperVars(ClassType type, boolean value, String fix)
{
addArgumentMapper("EQUALS_"+fix+"_TYPE", "Objects.equals(%2$s, "+(type.isObject() ? "%1$s" : fix+"_TO_OBJ(%1$s)")+")").removeBraces();
addInjectMapper(fix+"_EQUALS_NOT_NULL", type.getComparableValue()+" != "+(type.isPrimitiveBlocking() || type.needsCast() ? type.getEmptyValue() : "0")).removeBraces();
addInjectMapper(fix+"_EQUALS_NULL", type.getComparableValue()+" == "+(type.isPrimitiveBlocking() || type.needsCast() ? type.getEmptyValue() : "0")).removeBraces();
addArgumentMapper(fix+"_EQUALS_NOT", type.getEquals(true)).removeBraces();
addArgumentMapper(fix+"_EQUALS", type.getEquals(false)).removeBraces();
addSimpleMapper("FILE_"+fix+"_TYPE", type.getFileType());
addArgumentMapper("COMPAREABLE_TO_"+fix, type.isObject() ? "((Comparable<"+type.getKeyType(value)+">)%1$s).compareTo(("+type.getKeyType(value)+")%2$s)" : type.getClassType(value)+".compare(%1$s, %2$s)").removeBraces();
addArgumentMapper("COMPARE_TO_"+fix, type.isObject() ? "%1$s.compareTo(%2$s)" : type.getClassType(value)+".compare(%1$s, %2$s)").removeBraces();
addInjectMapper(fix+"_TO_OBJ", type.isObject() ? "%s" : type.getClassType(value)+".valueOf(%s)").removeBraces();
addInjectMapper("OBJ_TO_"+fix, type.isObject() ? "%s" : "%s."+type.getKeyType(value)+"Value()").removeBraces();
addInjectMapper("CLASS_TO_"+fix, type.isObject() ? "("+type.getKeyType(value)+")%s" : "(("+type.getClassType(value)+")%s)."+type.getKeyType(value)+"Value()").removeBraces();
addInjectMapper(fix+"_TO_HASH", type.isObject() ? "Objects.hashCode(%s)" : type.getClassType(value)+".hashCode(%s)").removeBraces();
addInjectMapper(fix+"_TO_STRING", type.isObject() ? "Objects.toString(%s)" : type.getClassType(value)+".toString(%s)").removeBraces();
addSimpleMapper("CAST_"+fix+"_ARRAY ", type.isObject() ? "("+fix+"_TYPE[])" : "");
addSimpleMapper("EMPTY_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])ARRAYS.EMPTY_ARRAY" : "ARRAYS.EMPTY_ARRAY");
addInjectMapper("NEW_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])new Object[%s]" : "new "+fix+"_TYPE[%s]").removeBraces();
addInjectMapper("NEW_SPECIAL_"+fix+"_ARRAY", type.isObject() ? "(E[])new Object[%s]" : "new "+fix+"_TYPE[%s]").removeBraces();
if(value) addInjectMapper("NEW_CLASS_VALUE_ARRAY", type.isObject() ? "(CLASS_VALUE_TYPE[])new Object[%s]" : "new CLASS_VALUE_TYPE[%s]").removeBraces();
else addInjectMapper("NEW_CLASS_ARRAY", type.isObject() ? "(CLASS_TYPE[])new Object[%s]" : "new CLASS_TYPE[%s]").removeBraces();
}
}
@@ -0,0 +1,120 @@
package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class ListModule extends BaseModule
{
public static final BaseModule INSTANCE = new ListModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(CollectionModule.MODULE).addKeyDependency(CollectionModule.SPLIT_ITERATORS);
public static final FunctionDependency IMPLEMENTATION = MODULE.createDependency("Implementations");
public static final FunctionDependency WRAPPERS = MODULE.createDependency("Wrappers");
public static final FunctionDependency ARRAY_LIST = MODULE.createDependency("ArrayList").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_LIST = MODULE.createDependency("LinkedList").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency IMMUTABLE_LIST = MODULE.createDependency("ImmutableList").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency COPY_ON_WRITE_LIST = MODULE.createDependency("CopyOnWriteList").addKeyDependency(IMPLEMENTATION);
@Override
public String getModuleName() { return "List"; }
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, IMPLEMENTATION, WRAPPERS, ARRAY_LIST, LINKED_LIST, IMMUTABLE_LIST, COPY_ON_WRITE_LIST); }
@Override
protected void loadVariables() {}
@Override
protected void loadFlags() {
if(MODULE.isEnabled()) addKeyFlag("LIST_MODULE");
if(WRAPPERS.isEnabled()) addKeyFlag("LISTS_FEATURE");
if(ARRAY_LIST.isEnabled()) addKeyFlag("ARRAY_LIST_FEATURE");
if(LINKED_LIST.isEnabled()) addKeyFlag("LINKED_LIST_FEATURE");
if(IMMUTABLE_LIST.isEnabled()) addKeyFlag("IMMUTABLE_LIST_FEATURE");
if(COPY_ON_WRITE_LIST.isEnabled()) addKeyFlag("COPY_ON_WRITE_LIST_FEATURE");
}
@Override
protected void loadBlockades()
{
if(!WRAPPERS.isEnabled()) addBlockedFiles("Lists");
if(!ARRAY_LIST.isEnabled()) addBlockedFiles("ArrayList");
if(!LINKED_LIST.isEnabled()) addBlockedFiles("LinkedList");
if(!IMMUTABLE_LIST.isEnabled()) addBlockedFiles("ImmutableList");
if(!COPY_ON_WRITE_LIST.isEnabled()) addBlockedFiles("CopyOnWriteList");
if(!MODULE.isEnabled()) addBlockedFiles("List", "AbstractList");
if(keyType.isObject()) addBlockedFiles("ListFillBufferTester");
if(keyType == ClassType.BOOLEAN) addBlockedFiles("ListFillBufferTester", "ListReplaceAllTester");
}
@Override
protected void loadRemappers()
{
//Main Classes
addRemapper("AbstractList", "Abstract%sList");
addRemapper("ImmutableList", "Immutable%sList");
addRemapper("CopyOnWriteList", "CopyOnWrite%sArrayList");
//Test Classes
addRemapper("AbstractListTester", "Abstract%sListTester");
addRemapper("AbstractListIndexOfTester", "Abstract%sListIndexOfTester");
addRemapper("TestListGenerator", "Test%sListGenerator");
}
@Override
protected void loadFunctions()
{
addFunctionMapper("GET_KEY", "get");
addFunctionMapper("GET_FIRST_KEY", "getFirst");
addFunctionMapper("GET_LAST_KEY", "getLast");
addFunctionMapper("REMOVE_FIRST_KEY", "removeFirst");
addFunctionMapper("REMOVE_LAST_KEY", "removeLast");
addFunctionMapper("REMOVE_SWAP", "swapRemove");
addFunctionMappers("REPLACE", keyType.isObject() ? "replaceObjects" : "replace%ss");
addFunctionMappers("SORT", "sort%ss");
}
@Override
protected void loadClasses()
{
//Implementation Classes
addClassMapper("ARRAY_LIST", "ArrayList");
addAbstractMapper("COPY_ON_WRITE_LIST", "CopyOnWrite%sArrayList");
addClassMapper("LINKED_LIST", "LinkedList");
addAbstractMapper("IMMUTABLE_LIST", "Immutable%sList");
//Abstract Classes
addAbstractMapper("ABSTRACT_LIST", "Abstract%sList");
//SubClasses
addClassMapper("SUB_LIST", "SubList");
addClassMapper("LIST_ITER", "ListIter");
//Helper Classes
addClassMapper("LISTS", "Lists");
//Interfaces
addClassMapper("LIST", "List");
}
@Override
protected void loadTestClasses()
{
//Implementation Classes
addClassMapper("LIST_TEST_BUILDER", "ListTestSuiteBuilder");
addClassMapper("LIST_TESTS", "ListTests");
//Abstract Classes
addAbstractMapper("ABSTRACT_LIST_INDEX_OF_TESTER", "Abstract%sListIndexOfTester");
addAbstractMapper("ABSTRACT_LIST_TESTER", "Abstract%sListTester");
//Helper classes
addAbstractMapper("TEST_LIST_GENERATOR", "Test%sListGenerator");
}
}
@@ -0,0 +1,290 @@
package speiger.src.builder.modules;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class MapModule extends BaseModule
{
public static final BaseModule INSTANCE = new MapModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, true)
.addKeyDependency(SetModule.MODULE)
.addValueDependency(CollectionModule.MODULE)
.addEntryDependency(SetModule.MODULE)
.addTypeDependency(SetModule.MODULE, ClassType.OBJECT);
public static final FunctionDependency IMPLEMENTATION = MODULE.createDependency("Implementations");
public static final FunctionDependency WRAPPERS = MODULE.createDependency("Wrappers").addKeyDependency(SetModule.WRAPPERS).addOptionalTypeDependency(SetModule.WRAPPERS, ClassType.OBJECT, true);
public static final FunctionDependency ORDERED_MAP = MODULE.createDependency("OrderedMap").addKeyDependency(SetModule.ORDERED_SET).addOptionalTypeDependency(SetModule.ORDERED_SET, ClassType.OBJECT, true);
public static final FunctionDependency SORTED_MAP = MODULE.createDependency("SortedMap").addKeyDependency(SetModule.SORTED_SET).addOptionalTypeDependency(SetModule.SORTED_SET, ClassType.OBJECT, true);
public static final FunctionDependency ARRAY_MAP = MODULE.createDependency("ArrayMap").addEntryDependency(ORDERED_MAP).addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency IMMUTABLE_MAP = MODULE.createDependency("ImmutableMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency HASH_MAP = MODULE.createDependency("HashMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_MAP = MODULE.createDependency("LinkedHashMap").addEntryDependency(HASH_MAP).addEntryDependency(ORDERED_MAP);
public static final FunctionDependency CUSTOM_MAP = MODULE.createDependency("CustomHashMap").addEntryDependency(IMPLEMENTATION).addKeyDependency(CollectionModule.STRATEGY);
public static final FunctionDependency LINKED_CUSTOM_MAP = MODULE.createDependency("LinkedCustomHashMap").addEntryDependency(CUSTOM_MAP).addEntryDependency(ORDERED_MAP);
public static final FunctionDependency ENUM_MAP = MODULE.createDependency("EnumMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_ENUM_MAP = MODULE.createDependency("LinkedEnumMap").addEntryDependency(ENUM_MAP).addEntryDependency(ORDERED_MAP);
public static final FunctionDependency CONCURRENT_MAP = MODULE.createDependency("ConcurrentMap").addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency AVL_TREE_MAP = MODULE.createDependency("AVLTreeMap").addEntryDependency(SORTED_MAP).addEntryDependency(IMPLEMENTATION);
public static final FunctionDependency RB_TREE_MAP = MODULE.createDependency("RBTreeMap").addEntryDependency(SORTED_MAP).addEntryDependency(IMPLEMENTATION);
@Override
public String getModuleName() { return "Map"; }
@Override
public boolean isBiModule() { return true; }
@Override
protected void loadVariables() {}
@Override
public boolean isModuleValid(ClassType keyType, ClassType valueType) { return keyType != ClassType.BOOLEAN; }
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) {
List<IDependency> dependencies = new ArrayList<>(Arrays.asList(MODULE, ORDERED_MAP, SORTED_MAP, IMPLEMENTATION, WRAPPERS, ARRAY_MAP, IMMUTABLE_MAP, HASH_MAP, LINKED_MAP, CUSTOM_MAP, LINKED_CUSTOM_MAP, CONCURRENT_MAP, AVL_TREE_MAP, RB_TREE_MAP));
if(keyType == ClassType.OBJECT) dependencies.addAll(Arrays.asList(ENUM_MAP, LINKED_ENUM_MAP));
return dependencies;
}
@Override
protected void loadFlags()
{
if(MODULE.isEnabled()) addFlag("MAP_MODULE");
if(WRAPPERS.isEnabled()) addFlag("MAPS_FEATURE");
if(ORDERED_MAP.isEnabled()) addFlag("ORDERED_MAP_FEATURE");
if(ARRAY_MAP.isEnabled()) addFlag("ARRAY_MAP_FEATURE");
if(LINKED_MAP.isEnabled()) addFlag("LINKED_MAP_FEATURE");
if(LINKED_CUSTOM_MAP.isEnabled()) addFlag("LINKED_CUSTOM_MAP_FEATURE");
if(LINKED_ENUM_MAP.isEnabled()) addFlag("LINKED_ENUM_MAP_FEATURE");
if(SORTED_MAP.isEnabled()) addFlag("SORTED_MAP_FEATURE");
if(AVL_TREE_MAP.isEnabled()) addFlag("AVL_TREE_MAP_FEATURE");
if(RB_TREE_MAP.isEnabled()) addFlag("RB_TREE_MAP_FEATURE");
if(CONCURRENT_MAP.isEnabled()) addFlag("CONCURRENT_MAP_FEATURE");
if(IMMUTABLE_MAP.isEnabled()) addFlag("IMMUTABLE_MAP_FEATURE");
if(HASH_MAP.isEnabled()) addFlag("MAP_FEATURE");
if(CUSTOM_MAP.isEnabled()) addFlag("CUSTOM_MAP_FEATURE");
if(ENUM_MAP.isEnabled()) addFlag("ENUM_MAP_FEATURE");
}
@Override
protected void loadBlockades()
{
if(!MODULE.isEnabled()) addBlockedFiles("Map", "AbstractMap");
if(!WRAPPERS.isEnabled()) addBlockedFiles("Maps");
if(!IMMUTABLE_MAP.isEnabled()) addBlockedFiles("ImmutableOpenHashMap");
if(!CONCURRENT_MAP.isEnabled()) addBlockedFiles("ConcurrentMap", "ConcurrentOpenHashMap");
if(!ORDERED_MAP.isEnabled()) addBlockedFiles("OrderedMap");
if(!HASH_MAP.isEnabled()) addBlockedFiles("OpenHashMap");
if(!LINKED_MAP.isEnabled()) addBlockedFiles("LinkedOpenHashMap");
if(!CUSTOM_MAP.isEnabled()) addBlockedFiles("OpenCustomHashMap");
if(!LINKED_CUSTOM_MAP.isEnabled()) addBlockedFiles("LinkedOpenCustomHashMap");
if(!ENUM_MAP.isEnabled()) addBlockedFiles("EnumMap");
if(!LINKED_ENUM_MAP.isEnabled()) addBlockedFiles("LinkedEnumMap");
if(!ARRAY_MAP.isEnabled()) addBlockedFiles("ArrayMap");
if(!SORTED_MAP.isEnabled()) addBlockedFiles("SortedMap", "NavigableMap");
if(!AVL_TREE_MAP.isEnabled()) addBlockedFiles("AVLTreeMap");
if(!RB_TREE_MAP.isEnabled()) addBlockedFiles("RBTreeMap");
if(keyType == ClassType.BOOLEAN)
{
//Main Classes
addBlockedFiles("SortedMap", "NavigableMap", "RBTreeMap", "AVLTreeMap");
addBlockedFiles("OrderedMap", "ArrayMap", "LinkedOpenHashMap", "LinkedOpenCustomHashMap");
addBlockedFiles("ConcurrentMap", "ConcurrentOpenHashMap");
addBlockedFiles("Map", "Maps", "AbstractMap", "ImmutableOpenHashMap", "OpenHashMap", "OpenCustomHashMap");
//Test Classes
addBlockedFiles("TestMap", "MapTests", "MapTestSuiteBuilder", "MapConstructorTests", "TestMapGenerator", "SimpleMapTestGenerator", "DerivedMapGenerators", "AbstractMapTester");
addBlockedFiles("TestSortedMapGenerator", "OrderedMapTestSuiteBuilder", "NavigableMapTestSuiteBuilder", "SortedMapTestSuiteBuilder");
addBlockedFiles("TestOrderedMapGenerator");
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
protected void loadRemappers()
{
//Main Classes
addBiRequirement("Map");
addBiRequirement("SortedMap");
addBiRequirement("OrderedMap");
addBiRequirement("NavigableMap");
addBiRequirement("ConcurrentMap");
addBiRequirement("AbstractMap");
addEnumRequirement("EnumMap");
addEnumRequirement("LinkedEnumMap");
addBiRequirement("ConcurrentOpenHashMap");
addBiRequirement("ImmutableOpenHashMap");
addBiRequirement("OpenHashMap");
addBiRequirement("LinkedOpenHashMap");
addBiRequirement("OpenCustomHashMap");
addBiRequirement("LinkedOpenCustomHashMap");
addBiRequirement("ArrayMap");
addBiRequirement("RBTreeMap");
addBiRequirement("AVLTreeMap");
addBiRequirement("Maps");
addRemapper("AbstractMap", "Abstract%sMap");
addRemapper("EnumMap", "Enum2%sMap");
addRemapper("LinkedEnumMap", "LinkedEnum2%sMap");
addRemapper("ImmutableOpenHashMap", "Immutable%sOpenHashMap");
//Test Classes
addBiRequirement("TestMapGenerator");
addBiRequirement("TestSortedMapGenerator");
addBiRequirement("TestOrderedMapGenerator");
addBiRequirement("SimpleMapTestGenerator");
addBiRequirement("DerivedMapGenerators");
addBiRequirement("AbstractMapTester");
addBiRequirement("MapTestSuiteBuilder");
addBiRequirement("SortedMapTestSuiteBuilder");
addBiRequirement("NavigableMapTestSuiteBuilder");
addBiRequirement("OrderedMapTestSuiteBuilder");
addBiRequirement("MapTests");
addBiRequirement("MapConstructorTests");
addBiRequirement("TestMap");
addBiRequirement("MapAddToTester");
addBiRequirement("MapSubFromTester");
addBiRequirement("MapClearTester");
addBiRequirement("MapComputeIfAbsentTester");
addBiRequirement("MapComputeIfPresentTester");
addBiRequirement("MapComputeTester");
addBiRequirement("MapComputeIfAbsentNonDefaultTester");
addBiRequirement("MapComputeIfPresentNonDefaultTester");
addBiRequirement("MapComputeNonDefaultTester");
addBiRequirement("MapCopyTester");
addBiRequirement("MapContainsTester");
addBiRequirement("MapContainsKeyTester");
addBiRequirement("MapContainsValueTester");
addBiRequirement("MapCreatorTester");
addBiRequirement("MapEntrySetTester");
addBiRequirement("MapEqualsTester");
addBiRequirement("MapForEachTester");
addBiRequirement("MapGetOrDefaultTester");
addBiRequirement("MapGetTester");
addBiRequirement("MapHashCodeTester");
addBiRequirement("MapIsEmptyTester");
addBiRequirement("MapMergeTester");
addBiRequirement("MapMergeBulkTester");
addBiRequirement("MapPutAllArrayTester");
addBiRequirement("MapPutAllTester");
addBiRequirement("MapPutIfAbsentTester");
addBiRequirement("MapPutTester");
addBiRequirement("MapRemoveEntryTester");
addBiRequirement("MapRemoveOrDefaultTester");
addBiRequirement("MapRemoveTester");
addBiRequirement("MapReplaceAllTester");
addBiRequirement("MapReplaceEntryTester");
addBiRequirement("MapReplaceTester");
addBiRequirement("MapSizeTester");
addBiRequirement("MapSupplyIfAbsentTester");
addBiRequirement("MapSupplyIfAbsentNonDefaultTester");
addBiRequirement("MapToStringTester");
addBiRequirement("NavigableMapNavigationTester");
addBiRequirement("SortedMapNavigationTester");
addBiRequirement("OrderedMapNavigationTester");
addBiRequirement("OrderedMapMoveTester");
addBiRequirement("MapConstructorTester");
addRemapper("TestMapGenerator", "Test%sMapGenerator");
addRemapper("TestSortedMapGenerator", "Test%sSortedMapGenerator");
addRemapper("TestOrderedMapGenerator", "Test%sOrderedMapGenerator");
addRemapper("SimpleMapTestGenerator", "Simple%sMapTestGenerator");
addRemapper("DerivedMapGenerators", "Derived%sMapGenerators");
addRemapper("AbstractMapTester", "Abstract%sMapTester");
addRemapper("TestMap", "Test%sMap");
}
@Override
protected void loadFunctions()
{
addFunctionValueMapper("BULK_MERGE", "mergeAll");
addFunctionValueMappers("COMPUTE_IF_ABSENT", "compute%sIfAbsent");
addFunctionValueMappers("COMPUTE_IF_PRESENT", "compute%sIfPresent");
addFunctionValueMapper("COMPUTE", "compute");
addFunctionMapper("DEQUEUE_LAST", "dequeueLast");
addFunctionMapper("DEQUEUE", "dequeue");
addSimpleMapper("ENTRY_SET", keyType.getFileType().toLowerCase()+"2"+valueType.getFileType()+"EntrySet");
addFunctionMappers("FIRST_ENTRY_KEY", "first%sKey");
addFunctionValueMappers("FIRST_ENTRY_VALUE", "first%sValue");
if(keyType.isObject()) addFunctionValueMapper("GET_VALUE", valueType.isObject() ? "getObject" : "get");
else addSimpleMapper("GET_VALUE", "get");
addFunctionMappers("LAST_ENTRY_KEY", "last%sKey");
addFunctionValueMappers("LAST_ENTRY_VALUE", "last%sValue");
addFunctionValueMapper("MERGE", "merge");
addFunctionMappers("POLL_FIRST_ENTRY_KEY", "pollFirst%sKey");
addFunctionMappers("POLL_LAST_ENTRY_KEY", "pollLast%sKey");
if(keyType.isObject()) addFunctionMapper("REMOVE_VALUE", "rem");
else addSimpleMapper("REMOVE_VALUE", "remove");
addFunctionMapper("REMOVE", "remove");
addFunctionValueMappers("REPLACE_VALUES", valueType.isObject() ? "replaceObjects" : "replace%ss");
addFunctionValueMappers("SUPPLY_IF_ABSENT", "supply%sIfAbsent");
}
@Override
protected void loadClasses()
{
//Implementation Classes
addAbstractBiMapper("IMMUTABLE_HASH_MAP", "Immutable%sOpenHashMap", "2");
addBiClassMapper("LINKED_CUSTOM_HASH_MAP", "LinkedOpenCustomHashMap", "2");
addBiClassMapper("LINKED_HASH_MAP", "LinkedOpenHashMap", "2");
addBiClassMapper("CUSTOM_HASH_MAP", "OpenCustomHashMap", "2");
addBiClassMapper("CONCURRENT_HASH_MAP", "ConcurrentOpenHashMap", "2");
addBiClassMapper("AVL_TREE_MAP", "AVLTreeMap", "2");
addBiClassMapper("RB_TREE_MAP", "RBTreeMap", "2");
addFunctionValueMappers("LINKED_ENUM_MAP", valueType.isObject() ? "LinkedEnum2ObjectMap" : "LinkedEnum2%sMap");
addFunctionValueMappers("ENUM_MAP", valueType.isObject() ? "Enum2ObjectMap" : "Enum2%sMap");
addBiClassMapper("HASH_MAP", "OpenHashMap", "2");
addBiClassMapper("ARRAY_MAP", "ArrayMap", "2");
//Abstract Classes
addAbstractBiMapper("ABSTRACT_MAP", "Abstract%sMap", "2");
//Helper Classes
addBiClassMapper("MAPS", "Maps", "2");
//Interfaces
addBiClassMapper("NAVIGABLE_MAP", "NavigableMap", "2");
addBiClassMapper("ORDERED_MAP", "OrderedMap", "2");
addBiClassMapper("SORTED_MAP", "SortedMap", "2");
addBiClassMapper("CONCURRENT_MAP", "ConcurrentMap", "2");
addBiClassMapper("MAP", "Map", "2");
}
@Override
protected void loadTestClasses()
{
//Implementation Classes
addAbstractBiMapper("SIMPLE_TEST_MAP", "Test%sMap", "2");
addBiClassMapper("MAP_TESTS", "MapTests", "2");
addAbstractBiMapper("NAVIGABLE_MAP_TEST_BUILDER", "%sNavigableMapTestSuiteBuilder", "2");
addAbstractBiMapper("SORTED_MAP_TEST_BUILDER", "%sSortedMapTestSuiteBuilder", "2");
addAbstractBiMapper("ORDERED_MAP_TEST_BUILDER", "%sOrderedMapTestSuiteBuilder", "2");
addAbstractBiMapper("MAP_TEST_BUILDER", "%sMapTestSuiteBuilder", "2");
//Abstract Classes
addAbstractBiMapper("ABSTRACT_MAP_TESTER", "Abstract%sMapTester", "2");
//Helper Classes
addAbstractBiMapper("MAP_CONSTRUCTOR_TESTS", "%sMapConstructorTests", "2");
addAbstractBiMapper("SIMPLE_MAP_TEST_GENERATOR", "Simple%sMapTestGenerator", "2");
addAbstractBiMapper("DERIVED_MAP_GENERATORS", "Derived%sMapGenerators", "2");
addAbstractBiMapper("TEST_ORDERED_MAP_GENERATOR", "Test%sOrderedMapGenerator", "2");
addAbstractBiMapper("TEST_SORTED_MAP_GENERATOR", "Test%sSortedMapGenerator", "2");
addAbstractBiMapper("TEST_MAP_GENERATOR", "Test%sMapGenerator", "2");
}
}
@@ -0,0 +1,71 @@
package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class PairModule extends BaseModule
{
public static final BaseModule INSTANCE = new PairModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, true).addKeyDependency(JavaModule.MODULE);
public static final FunctionDependency IMMUTABLE = MODULE.createDependency("Immutable");
public static final FunctionDependency MUTABLE = MODULE.createDependency("Mutable");
// public static final DependencyModule MODULE = new BiTypeModule(INSTANCE);
// public static final DependencyFunction IMMUTABLE = MODULE.createFunction("Immutable");
// public static final DependencyFunction MUTABLE = MODULE.createFunction("Mutable");
@Override
public String getModuleName() { return "Pair"; }
@Override
public boolean isBiModule() { return true; }
@Override
protected void loadVariables() {}
@Override
protected void loadFunctions() {}
@Override
protected void loadTestClasses() {}
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, IMMUTABLE, MUTABLE); }
@Override
protected void loadFlags() {
if(MODULE.isEnabled()) addFlag("PAIR_MODULE");
if(MUTABLE.isEnabled()) addFlag("MUTABLE_PAIR");
if(IMMUTABLE.isEnabled()) addFlag("IMMUTABLE_PAIR");
}
@Override
protected void loadBlockades() {
if(!MODULE.isEnabled()) addBlockedFiles("Pair");
if(!MUTABLE.isEnabled()) addBlockedFiles("MutablePair");
if(!IMMUTABLE.isEnabled()) addBlockedFiles("ImmutablePair");
}
@Override
protected void loadRemappers() {
//Main Classes
addBiRequirement("Pair", "");
addBiRequirement("MutablePair", "");
addBiRequirement("ImmutablePair", "");
//Test Classes
addBiRequirement("PairTester", "");
}
@Override
protected void loadClasses() {
//Implementations
addBiClassMapper("IMMUTABLE_PAIR", "ImmutablePair", "");
addBiClassMapper("MUTABLE_PAIR", "MutablePair", "");
//Interfaces
addBiClassMapper("PAIR", "Pair", "");
}
}
@@ -0,0 +1,102 @@
package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class PrioQueueModule extends BaseModule
{
public static final BaseModule INSTANCE = new PrioQueueModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(CollectionModule.MODULE);
public static final FunctionDependency IMPLEMENTATION = MODULE.createDependency("Implementations");
public static final FunctionDependency WRAPPERS = MODULE.createDependency("Wrappers");
public static final FunctionDependency DEQUEUE = MODULE.createDependency("Dequeue");
public static final FunctionDependency FIFO_QUEUE = MODULE.createDependency("FiFoQueue").addKeyDependency(DEQUEUE).addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency HEAP_QUEUE = MODULE.createDependency("HeapQueue").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency ARRAY_PRIO_QUEUE = MODULE.createDependency("ArrayPrioQueue").addKeyDependency(IMPLEMENTATION);
@Override
public String getModuleName() { return "PriorityQueue"; }
@Override
protected void loadVariables() {}
@Override
protected void loadFunctions() {}
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, WRAPPERS, IMPLEMENTATION, DEQUEUE, FIFO_QUEUE, HEAP_QUEUE, ARRAY_PRIO_QUEUE); }
@Override
protected void loadFlags() {
if(MODULE.isEnabled()) addFlag("QUEUE_MODULE");
if(WRAPPERS.isEnabled()) addKeyFlag("QUEUES_FEATURE");
if(DEQUEUE.isEnabled()) addKeyFlag("DEQUEUE_FEATURE");
if(FIFO_QUEUE.isEnabled()) addKeyFlag("FIFO_QUEUE_FEATURE");
if(HEAP_QUEUE.isEnabled()) addKeyFlag("HEAP_QUEUE_FEATURE");
if(ARRAY_PRIO_QUEUE.isEnabled()) addKeyFlag("ARRAY_QUEUE_FEATURE");
}
@Override
protected void loadBlockades() {
if(!MODULE.isEnabled()) addBlockedFiles("PriorityQueue", "AbstractPriorityQueue");
if(!WRAPPERS.isEnabled()) addBlockedFiles("PriorityQueues");
if(!DEQUEUE.isEnabled()) addBlockedFiles("PriorityDequeue");
if(!FIFO_QUEUE.isEnabled()) addBlockedFiles("ArrayFIFOQueue");
if(!HEAP_QUEUE.isEnabled()) addBlockedFiles("HeapPriorityQueue");
if(!ARRAY_PRIO_QUEUE.isEnabled()) addBlockedFiles("ArrayPriorityQueue");
if(keyType == ClassType.BOOLEAN) {
addBlockedFiles("QueueTests");
}
}
@Override
protected void loadRemappers() {
//Main Classes
addRemapper("AbstractPriorityQueue", "Abstract%sPriorityQueue");
//Test Classes
addRemapper("TestQueueGenerator", "Test%sQueueGenerator");
addRemapper("AbstractQueueTester", "Abstract%sQueueTester");
addRemapper("SimpleQueueTestGenerator", "Simple%sQueueTestGenerator");
}
@Override
protected void loadClasses() {
//Implementation Classes
addClassMapper("ARRAY_FIFO_QUEUE", "ArrayFIFOQueue");
addClassMapper("ARRAY_PRIORITY_QUEUE", "ArrayPriorityQueue");
addClassMapper("HEAP_PRIORITY_QUEUE", "HeapPriorityQueue");
//Abstract Classes
addAbstractMapper("ABSTRACT_PRIORITY_QUEUE", "Abstract%sPriorityQueue");
//Helper Classes
addClassMapper("PRIORITY_QUEUES", "PriorityQueues");
//Interfaces
addClassMapper("PRIORITY_QUEUE", "PriorityQueue");
addClassMapper("PRIORITY_DEQUEUE", "PriorityDequeue");
}
@Override
protected void loadTestClasses()
{
//Implementation Classes
addClassMapper("DEQUEUE_TEST_BUILDER", "DequeueTestSuiteBuilder");
addClassMapper("QUEUE_TEST_BUILDER", "QueueTestSuiteBuilder");
addClassMapper("QUEUE_TESTS", "QueueTests");
//Abstract Classes
addAbstractMapper("ABSTRACT_QUEUE_TESTER", "Abstract%sQueueTester");
//Helper Classes
addAbstractMapper("SIMPLE_QUEUE_TEST_GENERATOR", "Simple%sQueueTestGenerator");
addAbstractMapper("TEST_QUEUE_GENERATOR", "Test%sQueueGenerator");
}
}
@@ -0,0 +1,161 @@
package speiger.src.builder.modules;
import java.util.Arrays;
import java.util.List;
import speiger.src.builder.ClassType;
import speiger.src.builder.dependencies.FunctionDependency;
import speiger.src.builder.dependencies.IDependency;
import speiger.src.builder.dependencies.ModuleDependency;
@SuppressWarnings("javadoc")
public class SetModule extends BaseModule
{
public static final BaseModule INSTANCE = new SetModule();
public static final ModuleDependency MODULE = new ModuleDependency(INSTANCE, false).addKeyDependency(CollectionModule.MODULE).addKeyDependency(CollectionModule.SPLIT_ITERATORS);
public static final FunctionDependency IMPLEMENTATION = MODULE.createDependency("Implementations");
public static final FunctionDependency WRAPPERS = MODULE.createDependency("Wrappers");
public static final FunctionDependency ORDERED_SET = MODULE.createDependency("OrderedSet");
public static final FunctionDependency SORTED_SET = MODULE.createDependency("SortedSet");
public static final FunctionDependency ARRAY_SET = MODULE.createDependency("ArraySet").addKeyDependency(ORDERED_SET).addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency IMMUTABLE_SET = MODULE.createDependency("ImmutableSet").addKeyDependency(ORDERED_SET).addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency HASH_SET = MODULE.createDependency("HashSet").addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency LINKED_SET = MODULE.createDependency("LinkedHashSet").addKeyDependency(ORDERED_SET).addKeyDependency(HASH_SET);
public static final FunctionDependency CUSTOM_SET = MODULE.createDependency("CustomHashSet").addKeyDependency(IMPLEMENTATION).addKeyDependency(CollectionModule.STRATEGY);
public static final FunctionDependency LINKED_CUSTOM_SET = MODULE.createDependency("LinkedCustomHashSet").addKeyDependency(ORDERED_SET).addKeyDependency(CUSTOM_SET);
public static final FunctionDependency AVL_TREE_SET = MODULE.createDependency("AVLTreeSet").addKeyDependency(SORTED_SET).addKeyDependency(IMPLEMENTATION);
public static final FunctionDependency RB_TREE_SET = MODULE.createDependency("RBTreeSet").addKeyDependency(SORTED_SET).addKeyDependency(IMPLEMENTATION);
@Override
public String getModuleName() { return "Set"; }
@Override
protected void loadVariables() {}
@Override
public boolean isModuleValid(ClassType keyType, ClassType valueType) { return keyType != ClassType.BOOLEAN; }
@Override
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) { return Arrays.asList(MODULE, WRAPPERS, ORDERED_SET, SORTED_SET, IMPLEMENTATION, ARRAY_SET, IMMUTABLE_SET, HASH_SET, LINKED_SET, CUSTOM_SET, LINKED_CUSTOM_SET, AVL_TREE_SET, RB_TREE_SET); }
@Override
protected void loadFlags()
{
if(MODULE.isEnabled()) addFlag("SET_MODULE");
if(WRAPPERS.isEnabled()) addFlag("SETS_FEATURE");
if(ORDERED_SET.isEnabled()) addFlag("ORDERED_SET_FEATURE");
if(SORTED_SET.isEnabled()) addFlag("SORTED_SET_FEATURE");
if(IMMUTABLE_SET.isEnabled()) addFlag("IMMUTABLE_SET_FEATURE");
if(ARRAY_SET.isEnabled()) addFlag("ARRAY_SET_FEATURE");
if(HASH_SET.isEnabled()) addFlag("HASH_SET_FEATURE");
if(LINKED_SET.isEnabled()) addFlag("LINKED_SET_FEATURE");
if(CUSTOM_SET.isEnabled()) addFlag("CUSTOM_HASH_SET_FEATURE");
if(LINKED_CUSTOM_SET.isEnabled()) addFlag("LINKED_CUSTOM_SET_FEATURE");
if(AVL_TREE_SET.isEnabled()) addFlag("AVL_TREE_SET_FEATURE");
if(RB_TREE_SET.isEnabled()) addFlag("RB_TREE_SET_FEATURE");
}
@Override
protected void loadBlockades()
{
if(!MODULE.isEnabled()) addBlockedFiles("Set", "AbstractSet");
if(!WRAPPERS.isEnabled()) addBlockedFiles("Sets");
if(!IMMUTABLE_SET.isEnabled()) addBlockedFiles("ImmutableOpenHashSet");
if(!ORDERED_SET.isEnabled()) addBlockedFiles("OrderedSet");
if(!HASH_SET.isEnabled()) addBlockedFiles("OpenHashSet");
if(!LINKED_SET.isEnabled()) addBlockedFiles("LinkedOpenHashSet");
if(!CUSTOM_SET.isEnabled()) addBlockedFiles("OpenCustomHashSet");
if(!LINKED_CUSTOM_SET.isEnabled()) addBlockedFiles("LinkedOpenCustomHashSet");
if(!ARRAY_SET.isEnabled()) addBlockedFiles("ArraySet");
if(!SORTED_SET.isEnabled()) addBlockedFiles("SortedSet", "NavigableSet");
if(!AVL_TREE_SET.isEnabled()) addBlockedFiles("AVLTreeSet");
if(!RB_TREE_SET.isEnabled()) addBlockedFiles("RBTreeSet");
if(keyType == ClassType.BOOLEAN)
{
//Main Classes
addBlockedFiles("SortedSet", "NavigableSet", "AVLTreeSet", "RBTreeSet");
addBlockedFiles("OrderedSet", "ArraySet", "LinkedOpenHashSet", "LinkedOpenCustomHashSet");
addBlockedFiles("Set", "Sets", "AbstractSet", "OpenHashSet", "OpenCustomHashSet", "ImmutableOpenHashSet");
//Test Classes
addBlockedFiles("SetTests", "SetTestSuiteBuilder", "TestSetGenerator");
addBlockedFiles("OrderedSetTestSuiteBuilder", "TestOrderedSetGenerator", "OrderedSetMoveTester", "OrderedSetNavigationTester", "OrderedSetIterationTester");
addBlockedFiles("SortedSetTestSuiteBuilder", "TestSortedSetGenerator", "SortedSetNaviationTester", "SortedSetSubsetTestSetGenerator", "SortedSetIterationTester", "SortedSetNaviationTester");
addBlockedFiles("NavigableSetTestSuiteBuilder", "TestNavigableSetGenerator", "NavigableSetNavigationTester");
addBlockedFiles("MinimalSet", "AbstractSetTester", "SetAddAllTester", "SetAddTester", "SetCreationTester", "SetEqualsTester", "SetRemoveTester");
}
}
@Override
protected void loadRemappers()
{
//Main Classes
addRemapper("AbstractSet", "Abstract%sSet");
addRemapper("ImmutableOpenHashSet", "Immutable%sOpenHashSet");
//Test Classes
addRemapper("MinimalSet", "Minimal%sSet");
addRemapper("TestNavigableSetGenerator", "Test%sNavigableSetGenerator");
addRemapper("TestSortedSetGenerator", "Test%sSortedSetGenerator");
addRemapper("TestOrderedSetGenerator", "Test%sOrderedSetGenerator");
addRemapper("TestSetGenerator", "Test%sSetGenerator");
addRemapper("AbstractSetTester", "Abstract%sSetTester");
}
@Override
protected void loadFunctions()
{
addFunctionMapper("POLL_FIRST_KEY", "pollFirst");
addFunctionMapper("POLL_LAST_KEY", "pollLast");
addFunctionMapper("FIRST_KEY", "first");
addFunctionMapper("LAST_KEY", "last");
}
@Override
protected void loadTestClasses()
{
//Implementation Classes
addAbstractMapper("MINIMAL_SET", "Minimal%sSet");
addClassMapper("ORDERED_SET_TEST_BUILDER", "OrderedSetTestSuiteBuilder");
addClassMapper("SORTED_SET_TEST_BUILDER", "SortedSetTestSuiteBuilder");
addClassMapper("NAVIGABLE_SET_TEST_BUILDER", "NavigableSetTestSuiteBuilder");
addClassMapper("SET_TEST_BUILDER", "SetTestSuiteBuilder");
addClassMapper("SET_TESTS", "SetTests");
//Abstract Classes
addAbstractMapper("ABSTRACT_SET_TESTER", "Abstract%sSetTester");
//Helper Classes
addClassMapper("SUB_SORTED_SET_CLASS_GENERATOR", "SortedSetSubsetTestSetGenerator");
addClassMapper("SUB_NAVIGABLE_SET_CLASS_GENERATOR", "NavigableSetSubsetTestSetGenerator");
addAbstractMapper("TEST_NAVIGABLE_SET_GENERATOR", "Test%sNavigableSetGenerator");
addAbstractMapper("TEST_SORTED_SET_GENERATOR", "Test%sSortedSetGenerator");
addAbstractMapper("TEST_ORDERED_SET_GENERATOR", "Test%sOrderedSetGenerator");
addAbstractMapper("TEST_SET_GENERATOR", "Test%sSetGenerator");
}
@Override
protected void loadClasses()
{
//Implementation Classes
addClassMapper("LINKED_CUSTOM_HASH_SET", "LinkedOpenCustomHashSet");
addClassMapper("LINKED_HASH_SET", "LinkedOpenHashSet");
addAbstractMapper("IMMUTABLE_HASH_SET", "Immutable%sOpenHashSet");
addClassMapper("CUSTOM_HASH_SET", "OpenCustomHashSet");
addClassMapper("HASH_SET", "OpenHashSet");
addClassMapper("RB_TREE_SET", "RBTreeSet");
addClassMapper("AVL_TREE_SET", "AVLTreeSet");
addClassMapper("ARRAY_SET", "ArraySet");
//Abstract Classes
addAbstractMapper("ABSTRACT_SET", "Abstract%sSet");
//Helper Classes
addClassMapper("SETS", "Sets");
//Interfaces
addClassMapper("NAVIGABLE_SET", "NavigableSet");
addClassMapper("SORTED_SET", "SortedSet");
addClassMapper("ORDERED_SET", "OrderedSet");
addClassMapper("SET", "Set");
}
}
@@ -10,6 +10,7 @@ import java.util.function.Consumer;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif #endif
/** /**
@@ -230,6 +231,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
KEY_TYPE e = iter.NEXT(); KEY_TYPE e = iter.NEXT();
if(!c.contains(e)) { if(!c.contains(e)) {
r.accept(e);
iter.remove(); iter.remove();
modified = true; modified = true;
} }
@@ -244,6 +246,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
*/ */
@Override @Override
public KEY_TYPE[] TO_ARRAY() { public KEY_TYPE[] TO_ARRAY() {
if(isEmpty()) return ARRAYS.EMPTY_ARRAY;
return TO_ARRAY(new KEY_TYPE[size()]); return TO_ARRAY(new KEY_TYPE[size()]);
} }
@@ -256,6 +259,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) { public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()]; if(a == null || a.length < size()) a = new KEY_TYPE[size()];
ITERATORS.unwrap(a, iterator()); ITERATORS.unwrap(a, iterator());
if (a.length > size()) a[size()] = EMPTY_KEY_VALUE;
return a; return a;
} }
#endif #endif
@@ -1,19 +1,11 @@
package speiger.src.collections.PACKAGE.collections; package speiger.src.collections.PACKAGE.collections;
#if !TYPE_OBJECT
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
/**
* A Type-Specific {@link ObjectBidirectionalIterator} to reduce (un)boxing
*/
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, ObjectBidirectionalIterator<CLASS_TYPE>
#else
/** /**
* This is a basically a {@link java.util.ListIterator} without the index functions. * This is a basically a {@link java.util.ListIterator} without the index functions.
* Allowing to have a simple Bidirectional Iterator without having to keep track of the Iteration index. * Allowing to have a simple Bidirectional Iterator without having to keep track of the Iteration index.
* @Type(T) * @Type(T)
*/ */
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE
#endif
{ {
/** /**
* Returns true if the Iterator has a Previous element * Returns true if the Iterator has a Previous element
@@ -29,11 +21,11 @@ public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE
public KEY_TYPE PREVIOUS(); public KEY_TYPE PREVIOUS();
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** {@inheritDoc} /**
* <p>This default implementation delegates to the corresponding type-specific function. * <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead. * @deprecated Please use the corresponding type-specific function instead.
* @return the Previous element of the iterator.+
*/ */
@Override
@Deprecated @Deprecated
public default CLASS_TYPE previous() { public default CLASS_TYPE previous() {
return KEY_TO_OBJ(PREVIOUS()); return KEY_TO_OBJ(PREVIOUS());
@@ -57,7 +49,7 @@ public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE
public default int back(int amount) { public default int back(int amount) {
if(amount < 0) throw new IllegalStateException("Can't go forward"); if(amount < 0) throw new IllegalStateException("Can't go forward");
int i = 0; int i = 0;
for(;i<amount && hasPrevious();previous(),i++); for(;i<amount && hasPrevious();PREVIOUS(),i++);
return i; return i;
} }
} }
@@ -5,24 +5,29 @@ import java.util.Collection;
import java.util.Objects; import java.util.Objects;
import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_PREDICATE;
import java.util.function.Predicate; import java.util.function.Predicate;
#if SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
import java.util.stream.JAVA_STREAM; import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
#endif #endif
#endif
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
import speiger.src.collections.ints.functions.function.Int2ObjectFunction; import java.util.function.IntFunction;
#else #else
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.PACKAGE.utils.COLLECTIONS; import speiger.src.collections.PACKAGE.utils.COLLECTIONS;
import speiger.src.collections.utils.ISizeProvider;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
* A Type-Specific {@link Collection} that reduces (un)boxing * A Type-Specific {@link Collection} that reduces (un)boxing
* @Type(T) * @Type(T)
*/ */
public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITERABLE KEY_GENERIC_TYPE public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{ {
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** /**
@@ -174,11 +179,12 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
/** /**
* A Helper function that simplifies the process of creating a new Array. * A Helper function that simplifies the process of creating a new Array.
* @param action the array creation function * @param action the array creation function
* @param <E> the returning arrayType
* @return an array containing all of the elements in this collection * @return an array containing all of the elements in this collection
* @see Collection#toArray(Object[]) * @see Collection#toArray(Object[])
*/ */
default KEY_TYPE[] TO_ARRAY(Int2ObjectFunction<KEY_TYPE[]> action) { default <E> E[] TO_ARRAY(IntFunction<E[]> action) {
return TO_ARRAY(action.get(size())); return TO_ARRAY(action.apply(size()));
} }
#else #else
@@ -290,6 +296,7 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
*/ */
public default COLLECTION KEY_GENERIC_TYPE unmodifiable() { return COLLECTIONS.unmodifiable(this); } public default COLLECTION KEY_GENERIC_TYPE unmodifiable() { return COLLECTIONS.unmodifiable(this); }
#if SPLIT_ITERATOR_FEATURE
#if PRIMITIVES #if PRIMITIVES
/** /**
* Returns a Java-Type-Specific Stream to reduce boxing/unboxing. * Returns a Java-Type-Specific Stream to reduce boxing/unboxing.
@@ -302,11 +309,15 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
* @return a Stream of the closest java type * @return a Stream of the closest java type
*/ */
default JAVA_STREAM parallelPrimitiveStream() { return StreamSupport.NEW_STREAM(SPLIT_ITERATORS.createJavaSplititerator(this, 0), true); } default JAVA_STREAM parallelPrimitiveStream() { return StreamSupport.NEW_STREAM(SPLIT_ITERATORS.createJavaSplititerator(this, 0), true); }
#endif #endif
#if STREAM_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
*/ */
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
#endif
} }
@@ -2,6 +2,10 @@ package speiger.src.collections.PACKAGE.collections;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -9,23 +13,71 @@ import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.objects.collections.ObjectIterable; import speiger.src.collections.objects.collections.ObjectIterable;
#else #else
import java.util.function.BiFunction; import java.util.function.BiFunction;
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.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
#if !TYPE_BOOLEAN
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.sets.LINKED_HASH_SET;
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE
import speiger.src.collections.PACKAGE.lists.LIST;
#if ARRAY_LIST_FEATURE
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
#else
import speiger.src.collections.PACKAGE.lists.LINKED_LIST;
#endif
#endif
#if SET_MODULE && !TYPE_BOOLEAN
#if LINKED_SET_FEATURE || LINKED_CUSTOM_SET_FEATURE || SET_FEATURE || CUSTOM_SET_FEATURE || RB_TREE_SET_FEATURE || AVL_TREE_SET_FEATURE || ARRAY_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.SET;
#if LINKED_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.LINKED_HASH_SET;
#else if LINKED_CUSTOM_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.LINKED_CUSTOM_HASH_SET;
#else if SET_FEATURE
import speiger.src.collections.PACKAGE.sets.HASH_SET;
#else if CUSTOM_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.CUSTOM_HASH_SET;
#else if RB_TREE_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.RB_TREE_SET;
#else if AVL_TREE_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.AVL_TREE_SET;
#else if ARRAY_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.ARRAY_SET;
#endif
#endif
#endif
import speiger.src.collections.PACKAGE.utils.ARRAYS;
#if ASYNC_MODULE
import speiger.src.collections.PACKAGE.utils.ASYNC_BUILDER; import speiger.src.collections.PACKAGE.utils.ASYNC_BUILDER;
#endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.PACKAGE.utils.ITERABLES; import speiger.src.collections.PACKAGE.utils.ITERABLES;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#if !LINKED_HASH_SET_FEATURE && LINKED_CUSTOM_HASH_SET_FEATURE
import speiger.src.collections.PACKAGE.utils.STRATEGY;
#endif
import speiger.src.collections.utils.ISizeProvider;
/** /**
* A Type-Specific {@link Iterable} that reduces (un)boxing * A Type-Specific {@link Iterable} that reduces (un)boxing
@@ -72,6 +124,17 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
} }
#endif #endif
/**
* A Indexed forEach implementation that allows you to keep track of how many elements were already iterated over.
* @param action The action to be performed for each element
* @throws java.lang.NullPointerException if the specified action is null
*/
public default void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int index = 0;
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();action.accept(index++, iter.NEXT()));
}
/** /**
* Helper function to reduce Lambda usage and allow for more method references, since these are faster/cleaner. * Helper function to reduce Lambda usage and allow for more method references, since these are faster/cleaner.
* @param input the object that should be included * @param input the object that should be included
@@ -84,6 +147,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
iterator().forEachRemaining(input, action); iterator().forEachRemaining(input, action);
} }
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
@@ -91,6 +155,8 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createUnknownSplititerator(iterator(), 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createUnknownSplititerator(iterator(), 0); }
#endif
#if ASYNC_MODULE
/** /**
* Creates a Async Builder for moving work of the thread. * Creates a Async Builder for moving work of the thread.
* It is not designed to split the work to multithreaded work, so using this keep it singlethreaded, but it allows to be moved to another thread. * It is not designed to split the work to multithreaded work, so using this keep it singlethreaded, but it allows to be moved to another thread.
@@ -101,6 +167,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
return new ASYNC_BUILDERBRACES(this); return new ASYNC_BUILDERBRACES(this);
} }
#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 mapping function * @param mapper the mapping function
@@ -111,12 +178,32 @@ 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
* @param <V> The return type supplier. * @param <V> The return type supplier.
* @param <E> The return type. * @param <E> The return type.
* @return a new Iterable that returns the desired result * @return a new Iterable that returns the desired result
* @note does not support TO_ARRAY optimizations.
*/ */
default <E, V extends Iterable<E>> ObjectIterable<E> flatMap(TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<V> mapper) { default <E, V extends Iterable<E>> ObjectIterable<E> flatMap(TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<V> mapper) {
return ITERABLES.flatMap(this, mapper); return ITERABLES.flatMap(this, mapper);
@@ -127,6 +214,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
* @param mapper the flatMapping function * @param mapper the flatMapping function
* @param <E> The return type. * @param <E> The return type.
* @return a new Iterable that returns the desired result * @return a new Iterable that returns the desired result
* @note does not support TO_ARRAY optimizations.
*/ */
default <E> ObjectIterable<E> arrayflatMap(TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<E[]> mapper) { default <E> ObjectIterable<E> arrayflatMap(TO_OBJECT_FUNCTION KKS_GENERIC_TYPE<E[]> mapper) {
return ITERABLES.arrayFlatMap(this, mapper); return ITERABLES.arrayFlatMap(this, mapper);
@@ -136,6 +224,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
* A Helper function to reduce the usage of Streams and allows to filter out unwanted elements * A Helper function to reduce the usage of Streams and allows to filter out unwanted elements
* @param filter the elements that should be kept. * @param filter the elements that should be kept.
* @return a Iterable that filtered out all unwanted elements * @return a Iterable that filtered out all unwanted elements
* @note does not support TO_ARRAY optimizations.
*/ */
default ITERABLE KEY_GENERIC_TYPE filter(PREDICATE KEY_GENERIC_TYPE filter) { default ITERABLE KEY_GENERIC_TYPE filter(PREDICATE KEY_GENERIC_TYPE filter) {
return ITERABLES.filter(this, filter); return ITERABLES.filter(this, filter);
@@ -144,11 +233,21 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
/** /**
* A Helper function to reduce the usage of Streams and allows to filter out duplicated elements * A Helper function to reduce the usage of Streams and allows to filter out duplicated elements
* @return a Iterable that filtered out all duplicated elements * @return a Iterable that filtered out all duplicated elements
* @note does not support TO_ARRAY optimizations.
*/ */
default ITERABLE KEY_GENERIC_TYPE distinct() { default ITERABLE KEY_GENERIC_TYPE distinct() {
return ITERABLES.distinct(this); return ITERABLES.distinct(this);
} }
/**
* A Helper function to reduce the usage of Streams and allows to repeat elements a desired amount of times
* @param repeats how many times the elements should be repeated
* @return a Iterable that is repeating multiple times
*/
default ITERABLE KEY_GENERIC_TYPE repeat(int repeats) {
return ITERABLES.repeat(this, repeats);
}
/** /**
* A Helper function to reduce the usage of Streams and allows to limit the amount of elements * A Helper function to reduce the usage of Streams and allows to limit the amount of elements
* @param limit the amount of elements it should be limited to * @param limit the amount of elements it should be limited to
@@ -187,21 +286,81 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
return collection; return collection;
} }
#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE
/** /**
* A Helper function that reduces the usage of streams and allows to collect all elements as a ArrayList * A Helper function that reduces the usage of streams and allows to collect all elements as a ArrayList
* @return a new ArrayList of all elements * @return a new ArrayList of all elements
*/ */
default LIST KEY_GENERIC_TYPE pourAsList() { default LIST KEY_GENERIC_TYPE pourAsList() {
#if ARRAY_LIST_FEATURE
return pour(new ARRAY_LISTBRACES()); return pour(new ARRAY_LISTBRACES());
#else
return pour(new LINKED_LISTBRACES());
#endif
} }
#if !TYPE_BOOLEAN #endif
#if !TYPE_BOOLEAN && SET_MODULE
#if LINKED_SET_FEATURE || LINKED_CUSTOM_SET_FEATURE || SET_FEATURE || CUSTOM_SET_FEATURE || RB_TREE_SET_FEATURE || AVL_TREE_SET_FEATURE || ARRAY_SET_FEATURE
/** /**
* A Helper function that reduces the usage of streams and allows to collect all elements as a LinkedHashSet * A Helper function that reduces the usage of streams and allows to collect all elements as a LinkedHashSet
* @return a new LinkedHashSet of all elements * @return a new LinkedHashSet of all elements
*/ */
default SET KEY_GENERIC_TYPE pourAsSet() { default SET KEY_GENERIC_TYPE pourAsSet() {
#if LINKED_SET_FEATURE
return pour(new LINKED_HASH_SETBRACES()); return pour(new LINKED_HASH_SETBRACES());
#else if LINKED_CUSTOM_SET_FEATURE
return pour(new LINKED_CUSTOM_HASH_SETBRACES(STRATEGY.normalStrategy()));
#else if SET_FEATURE
return pour(new HASH_SETBRACES());
#else if CUSTOM_SET_FEATURE
return pour(new CUSTOM_HASH_SETBRACES(STRATEGY.normalStrategy()));
#else if RB_TREE_SET_FEATURE
return pour(new RB_Tree_SETBRACES());
#else if AVL_TREE_SET_FEATURE
return pour(new AVL_Tree_SETBRACES());
#else if ARRAY_SET_FEATURE
return pour(new ARRAY_SETBRACES());
#endif
}
#endif
#endif
#if TYPE_OBJECT
/**
* A Helper function that reduces the usage of streams and allows to collect all elements as a Array
* @param action is the creator function of said Array to ensure type is kept.
* @param <E> the returning arrayType
* @return a new Array of all elements
*/
default <E> E[] TO_ARRAY(IntFunction<E[]> action) {
ISizeProvider prov = ISizeProvider.of(this);
if(prov != null) {
int size = prov.size();
if(size >= 0) {
E[] array = action.apply(size);
ITERATORS.unwrap(array, iterator());
return array;
}
}
return ARRAYS.pour(iterator(), action);
}
#else
/**
* A Helper function that reduces the usage of streams and allows to collect all elements as a Array
* @return a new Array of all elements
*/
default KEY_TYPE[] TO_ARRAY() {
ISizeProvider prov = ISizeProvider.of(this);
if(prov != null) {
int size = prov.size();
if(size >= 0) {
KEY_TYPE[] array = NEW_KEY_ARRAY(size);
ITERATORS.unwrap(array, iterator());
return array;
}
}
return ARRAYS.pour(iterator());
} }
#endif #endif
@@ -213,7 +372,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
default boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { default boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
if(filter.TEST_VALUE(iter.NEXT())) return true; if(filter.test(iter.NEXT())) return true;
} }
return false; return false;
} }
@@ -226,7 +385,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
default boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { default boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
if(filter.TEST_VALUE(iter.NEXT())) return false; if(filter.test(iter.NEXT())) return false;
} }
return true; return true;
} }
@@ -239,7 +398,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
default boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { default boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
if(!filter.TEST_VALUE(iter.NEXT())) return false; if(!filter.test(iter.NEXT())) return false;
} }
return true; return true;
} }
@@ -253,7 +412,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
KEY_TYPE entry = iter.NEXT(); KEY_TYPE entry = iter.NEXT();
if(filter.TEST_VALUE(entry)) return entry; if(filter.test(entry)) return entry;
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -324,7 +483,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
if(filter.TEST_VALUE(iter.NEXT())) result++; if(filter.test(iter.NEXT())) result++;
} }
return result; return result;
} }
@@ -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);
} }
@@ -15,12 +15,5 @@ public interface SUPPLIER KEY_GENERIC_TYPE
/** /**
* @return the supplied value * @return the supplied value
*/ */
public KEY_TYPE GET_KEY(); public KEY_TYPE SUPPLY_GET();
#if JDK_TYPE && PRIMITIVES
@Override
public default KEY_TYPE GET_JAVA() {
return GET_KEY();
}
#endif
} }
@@ -1,6 +1,6 @@
package speiger.src.collections.PACKAGE.functions.function; package speiger.src.collections.PACKAGE.functions.function;
#if JDK_FUNCTION && VALUE_BOOLEAN #if VALUE_BOOLEAN || SAME_TYPE
import java.util.Objects; import java.util.Objects;
#endif #endif
@@ -21,12 +21,67 @@ public interface FUNCTION KEY_VALUE_GENERIC_TYPE
* @param k the value that should be processed * @param k the value that should be processed
* @return the result of the function * @return the result of the function
*/ */
public VALUE_TYPE GET_VALUE(KEY_TYPE k); public VALUE_TYPE APPLY(KEY_TYPE k);
#if JDK_FUNCTION #if SAME_TYPE
/**
* Creates a Default function that returns the input provided.
* @Type(T)
* @return a input returning function
*/
public static GENERIC_KEY_BRACES FUNCTION KEY_SAME_GENERIC_TYPE identity() {
return T -> T;
}
/**
* Returns a composed function that first applies the {@code before}
* function to its input, and then applies this function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @Type(I)
* @param before the function that should be used first
* @return a composed function with a different starting function.
*/
public default GENERIC_SPECIAL_VALUE_BRACES<I> FUNCTION SV_GENERIC_TYPE<I> compose(FUNCTION SK_GENERIC_TYPE<I> before) {
Objects.requireNonNull(before);
return T -> APPLY(before.APPLY(T));
}
/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@code after} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @Type(I)
* @param after the function that should be used last
* @return a composed function with a different starting function.
*/
public default GENERIC_SPECIAL_VALUE_BRACES<I> FUNCTION KS_GENERIC_TYPE<I> andThen(FUNCTION VS_GENERIC_TYPE<I> after) {
Objects.requireNonNull(after);
return T -> after.APPLY(APPLY(T));
}
#endif
#if VALUE_BOOLEAN #if VALUE_BOOLEAN
@Override /**
public default VALUE_TYPE test(KEY_TYPE k) { return GET_VALUE(k); } * Creates a Always true function that may be useful if you don't need to process information or just want a default.
* @Type(T)
* @return a default returning function
*/
public static GENERIC_KEY_BRACES FUNCTION KEY_GENERIC_TYPE alwaysTrue() {
return T -> true;
}
/**
* Creates a Always false function that may be useful if you don't need to process information or just want a default.
* @Type(T)
* @return a default returning function
*/
public static GENERIC_KEY_BRACES FUNCTION KEY_GENERIC_TYPE alwaysFalse() {
return T -> false;
}
/** /**
* A Type specific and-function helper function that reduces boxing/unboxing * A Type specific and-function helper function that reduces boxing/unboxing
@@ -35,19 +90,26 @@ public interface FUNCTION KEY_VALUE_GENERIC_TYPE
*/ */
public default FUNCTION KEY_VALUE_GENERIC_TYPE andType(FUNCTION KEY_VALUE_GENERIC_TYPE other) { public default FUNCTION KEY_VALUE_GENERIC_TYPE andType(FUNCTION KEY_VALUE_GENERIC_TYPE other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
return T -> GET_VALUE(T) && other.GET_VALUE(T); return T -> APPLY(T) && other.APPLY(T);
} }
#if JDK_FUNCTION
@Override @Override
@Deprecated @Deprecated
public default FUNCTION KEY_VALUE_GENERIC_TYPE and(JAVA_FUNCTION KEY_VALUE_SUPER_GENERIC_TYPE other) { public default FUNCTION KEY_VALUE_GENERIC_TYPE and(JAVA_FUNCTION KEY_VALUE_SUPER_GENERIC_TYPE other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
return T -> GET_VALUE(T) && other.test(T); return T -> APPLY(T) && other.APPLY(T);
} }
@Override @Override
#else
/**
* A type specific inverter function
* @return the same function but inverts the result
*/
#endif
public default FUNCTION KEY_VALUE_GENERIC_TYPE negate() { public default FUNCTION KEY_VALUE_GENERIC_TYPE negate() {
return T -> !GET_VALUE(T); return T -> !APPLY(T);
} }
/** /**
@@ -57,23 +119,16 @@ public interface FUNCTION KEY_VALUE_GENERIC_TYPE
*/ */
public default FUNCTION KEY_VALUE_GENERIC_TYPE orType(FUNCTION KEY_VALUE_GENERIC_TYPE other) { public default FUNCTION KEY_VALUE_GENERIC_TYPE orType(FUNCTION KEY_VALUE_GENERIC_TYPE other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
return T -> GET_VALUE(T) || other.GET_VALUE(T); return T -> APPLY(T) || other.APPLY(T);
} }
#if JDK_FUNCTION
@Override @Override
@Deprecated @Deprecated
public default FUNCTION KEY_VALUE_GENERIC_TYPE or(JAVA_FUNCTION KEY_VALUE_SUPER_GENERIC_TYPE other) { public default FUNCTION KEY_VALUE_GENERIC_TYPE or(JAVA_FUNCTION KEY_VALUE_SUPER_GENERIC_TYPE other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
return T -> GET_VALUE(T) || other.test(T); return T -> APPLY(T) || other.APPLY(T);
} }
#else if VALUE_OBJECT
@Override
public default VALUE_TYPE apply(KEY_TYPE k) { return GET_VALUE(k); }
#else
@Override
public default VALUE_TYPE APPLY_VALUE(KEY_TYPE k) { return GET_VALUE(k); }
#endif #endif
#endif #endif
} }
@@ -1,16 +1,25 @@
package speiger.src.collections.PACKAGE.lists; package speiger.src.collections.PACKAGE.lists;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.RandomAccess;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#endif
#if INT_LIST_MODULE && !TYPE_INT
import speiger.src.collections.ints.lists.IntList;
#endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
@@ -66,8 +75,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
*/ */
@Override @Override
@Deprecated @Deprecated
public boolean addAll(Collection<? extends CLASS_TYPE> c) public boolean addAll(Collection<? extends CLASS_TYPE> c) {
{
return c instanceof COLLECTION ? addAll((COLLECTION KEY_GENERIC_TYPE)c) : addAll(size(), c); return c instanceof COLLECTION ? addAll((COLLECTION KEY_GENERIC_TYPE)c) : addAll(size(), c);
} }
@@ -221,6 +229,11 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return new SubList(this, 0, fromIndex, toIndex); return new SubList(this, 0, fromIndex, toIndex);
} }
@Override
public LIST KEY_GENERIC_TYPE reversed() {
return new ReversedList(this);
}
@Override @Override
public ITERATOR KEY_GENERIC_TYPE iterator() { public ITERATOR KEY_GENERIC_TYPE iterator() {
return listIterator(0); return listIterator(0);
@@ -237,6 +250,18 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return new LIST_ITER(index); return new LIST_ITER(index);
} }
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) {
return new IndexedIterator(indecies);
}
#if INT_LIST_MODULE
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) {
return new ListIndexedIterator(indecies);
}
#endif
@Override @Override
public void size(int size) { public void size(int size) {
while(size > size()) add(EMPTY_KEY_VALUE); while(size > size()) add(EMPTY_KEY_VALUE);
@@ -245,6 +270,138 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
public ABSTRACT_LIST KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public ABSTRACT_LIST KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
private class ReversedList extends ABSTRACT_LIST KEY_GENERIC_TYPE
{
final ABSTRACT_LIST KEY_GENERIC_TYPE list;
public ReversedList(ABSTRACT_LIST KEY_GENERIC_TYPE list) {
this.list = list;
}
@Override
public void add(int index, KEY_TYPE e) {
list.add(list.size() - index - 1, e);
}
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
return addCollection(index, c);
}
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
if(c instanceof RandomAccess) {
for(int i = 0,m=c.size();i<m;i++) {
list.add(list.size() - index - i - 1, c.GET_KEY(i));
}
return true;
}
return addCollection(index, c);
}
private boolean addCollection(int index, COLLECTION KEY_GENERIC_TYPE c) {
int i = 0;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();i++) {
list.add(list.size() - index - i - 1, iter.NEXT());
}
return true;
}
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
int i = 0;
for(Iterator<? extends CLASS_TYPE> iter = c.iterator();iter.hasNext();i++) {
list.add(list.size() - index - i - 1, iter.next());
}
return true;
}
@Override
public KEY_TYPE GET_KEY(int index) {
return list.GET_KEY(list.size() - index - 1);
}
@Override
public KEY_TYPE set(int index, KEY_TYPE e) {
return list.set(list.size() - index - 1, e);
}
@Override
public KEY_TYPE REMOVE(int index) {
return list.REMOVE(list.size() - index - 1);
}
@Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
for(int i = 0,m=length;i<m;i++) {
list.add(list.size() - from - i - 1, a[i+offset]);
}
}
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
return reverse(list.getElements(list.size() - from - 1, a, offset, length));
}
@Override
public void removeElements(int from, int to) {
list.removeElements(list.size() - to - 1, list.size() - from - 1);
}
@Override
public KEY_TYPE swapRemove(int index) {
return list.swapRemove(list.size() - index - 1);
}
#if TYPE_OBJECT
@Override
public <K> K[] extractElements(int from, int to, Class<K> type) {
return reverse(list.extractElements(list.size() - to - 1, list.size() - from - 1, type));
}
#else
@Override
public KEY_TYPE[] extractElements(int from, int to) {
return reverse(list.extractElements(list.size() - to - 1, list.size() - from - 1));
}
#endif
@Override
public int size() {
return list.size();
}
@Override
public void clear() {
list.clear();
}
@Override
public LIST KEY_GENERIC_TYPE reversed() {
return list;
}
#if TYPE_OBJECT
private <K> K[] reverse(K[] data) {
for (int i = 0, mid = data.length >> 1, j = data.length - 1; i < mid; i++, j--) {
K t = data[i];
data[i] = data[j];
data[j] = t;
}
return data;
}
#else
private KEY_TYPE[] reverse(KEY_TYPE[] data) {
for (int i = 0, mid = data.length >> 1, j = data.length - 1; i < mid; i++, j--) {
KEY_TYPE t = data[i];
data[i] = data[j];
data[j] = t;
}
return data;
}
#endif
}
private class SubList extends ABSTRACT_LIST KEY_GENERIC_TYPE private class SubList extends ABSTRACT_LIST KEY_GENERIC_TYPE
{ {
final ABSTRACT_LIST KEY_GENERIC_TYPE list; final ABSTRACT_LIST KEY_GENERIC_TYPE list;
@@ -308,14 +465,14 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
SanityChecks.checkArrayCapacity(size, from, length); SanityChecks.checkArrayCapacity(size, from, length);
SanityChecks.checkArrayCapacity(a.length, offset, length); SanityChecks.checkArrayCapacity(a.length, offset, length);
return list.getElements(from+this.offset, a, offset, length); return list.getElements(from+parentOffset, a, offset, length);
} }
@Override @Override
public void removeElements(int from, int to) { public void removeElements(int from, int to) {
if(to-from <= 0) return; if(to-from <= 0) return;
checkSubRange(from); checkSubRange(from);
checkSubRange(to); checkAddSubRange(to);
list.removeElements(from+parentOffset, to+parentOffset); list.removeElements(from+parentOffset, to+parentOffset);
size -= to - from; size -= to - from;
} }
@@ -324,9 +481,9 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override @Override
public <K> K[] extractElements(int from, int to, Class<K> type) { public <K> K[] extractElements(int from, int to, Class<K> type) {
checkSubRange(from); checkSubRange(from);
checkSubRange(to); checkAddSubRange(to);
K[] result = list.extractElements(from+parentOffset, to+parentOffset, type); K[] result = list.extractElements(from+parentOffset, to+parentOffset, type);
size -= to - from; size -= result.length;
return result; return result;
} }
@@ -334,9 +491,9 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override @Override
public KEY_TYPE[] extractElements(int from, int to) { public KEY_TYPE[] extractElements(int from, int to) {
checkSubRange(from); checkSubRange(from);
checkSubRange(to); checkAddSubRange(to);
KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset); KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset);
size -= to - from; size -= result.length;
return result; return result;
} }
@@ -344,19 +501,25 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override @Override
public KEY_TYPE GET_KEY(int index) { public KEY_TYPE GET_KEY(int index) {
checkSubRange(index); checkSubRange(index);
return list.GET_KEY(offset+index); return list.GET_KEY(parentOffset+index);
} }
@Override @Override
public KEY_TYPE set(int index, KEY_TYPE element) { public KEY_TYPE set(int index, KEY_TYPE element) {
checkSubRange(index); checkSubRange(index);
return list.set(offset+index, element); return list.set(parentOffset+index, element);
} }
@Override @Override
public KEY_TYPE swapRemove(int index) { public KEY_TYPE swapRemove(int index) {
checkSubRange(index); checkSubRange(index);
KEY_TYPE result = list.swapRemove(index+parentOffset); if(index == size-1) {
KEY_TYPE result = list.REMOVE(parentOffset+size-1);
size--;
return result;
}
KEY_TYPE result = list.set(index+parentOffset, list.GET_KEY(parentOffset+size-1));
list.REMOVE(parentOffset+size-1);
size--; size--;
return result; return result;
} }
@@ -373,9 +536,10 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
public int size() { public int size() {
return size; return size;
} }
#if SPLIT_ITERATOR_FEATURE
@Override @Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 16464); } public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 16464); }
#endif
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) { public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
@@ -386,7 +550,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override @Override
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) { public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
SanityChecks.checkArrayCapacity(size, fromIndex, toIndex-fromIndex); SanityChecks.checkArrayCapacity(size, fromIndex, toIndex-fromIndex);
return new SubList(list, offset, fromIndex, toIndex); return new SubList(this, offset, fromIndex, toIndex);
} }
protected void checkSubRange(int index) { protected void checkSubRange(int index) {
@@ -460,15 +624,17 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override @Override
public void add(KEY_TYPE e) { public void add(KEY_TYPE e) {
list.add(index++, e); list.add(index, e);
index++;
lastReturned = -1; lastReturned = -1;
} }
@Override @Override
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (list.size() - 1) - index); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps; return steps;
} }
@@ -477,11 +643,160 @@ 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);
return steps; return steps;
} }
} }
} }
#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;
@@ -540,15 +855,17 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
@Override @Override
public void add(KEY_TYPE e) { public void add(KEY_TYPE e) {
ABSTRACT_LIST.this.add(index++, e); ABSTRACT_LIST.this.add(index, e);
index++;
lastReturned = -1; lastReturned = -1;
} }
@Override @Override
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (size() - 1) - index); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps; return steps;
} }
@@ -557,6 +874,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index); int steps = Math.min(amount, index);
index -= steps; index -= steps;
if(steps > 0) lastReturned = Math.max(index, 0);
return steps; return steps;
} }
} }
@@ -8,13 +8,22 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects; import java.util.Objects;
#if TYPE_OBJECT #if TYPE_OBJECT
#if IARRAY_FEATURE || TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
#endif
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.IntFunction;
#endif
#if !TYPE_OBJECT && JDK_FUNCTION
import java.util.function.PREDICATE;
#endif #endif
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
#if PRIMITIVES #if PRIMITIVES
#if !JDK_FUNCTION
import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_PREDICATE;
#endif
import java.util.function.JAVA_UNARY_OPERATOR; import java.util.function.JAVA_UNARY_OPERATOR;
import java.nio.JAVA_BUFFER; import java.nio.JAVA_BUFFER;
#endif #endif
@@ -29,42 +38,50 @@ 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.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#if TYPE_OBJECT #if TYPE_OBJECT
import speiger.src.collections.utils.Stack; import speiger.src.collections.utils.Stack;
#else
import speiger.src.collections.objects.utils.ObjectArrays;
#endif #endif
#if PRIMITIVES #if PRIMITIVES && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
import java.util.stream.JAVA_STREAM; import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
#endif #endif
#if IARRAY_FEATURE
import speiger.src.collections.PACKAGE.utils.IARRAY; import speiger.src.collections.PACKAGE.utils.IARRAY;
#endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
#if !IARRAY_FEATURE
import speiger.src.collections.utils.IArray;
#endif
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
#if TYPE_OBJECT
/** /**
* A Type-Specific Array-based implementation of list that is written to reduce (un)boxing * A Type-Specific Array-based implementation of list that is written to reduce (un)boxing
* *
* <p>This implementation is optimized to improve how data is processed with interfaces like {@link IARRAY}, {@link Stack} #if IARRAY_FEATURE
* <p>This implementation is optimized to improve how data is processed with interfaces like {@link IARRAY}, {@link STACK}
#else
* <p>This implementation is optimized to improve how data is processed with interfaces like {@link IArray}, {@link STACK}
#endif
* and with optimized functions that use type-specific implementations for primitives and optimized logic for bulkactions. * and with optimized functions that use type-specific implementations for primitives and optimized logic for bulkactions.
* *
* @Type(T) * @Type(T)
*/ */
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IARRAY<KEY_TYPE>, Stack<KEY_TYPE> #if IARRAY_FEATURE
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IARRAY KEY_GENERIC_TYPE, STACK KEY_GENERIC_TYPE
#else #else
/** public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IArray, STACK KEY_GENERIC_TYPE
* A Type-Specific Array-based implementation of list that is written to reduce (un)boxing
*
* <p>This implementation is optimized to improve how data is processed with interfaces like {@link IARRAY}, {@link STACK}
* and with optimized functions that use type-specific implementations for primitives and optimized logic for bulkactions.
*/
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IARRAY, STACK
#endif #endif
{ {
static final int DEFAULT_ARRAY_SIZE = 10; static final int DEFAULT_ARRAY_SIZE = 10;
@@ -86,6 +103,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
* @param size the minimum initial size of the Backing array * @param size the minimum initial size of the Backing array
*/ */
public ARRAY_LIST(int size) { public ARRAY_LIST(int size) {
if(size < 0) throw new IllegalStateException("Size has to be 0 or greater");
data = NEW_KEY_ARRAY(size); data = NEW_KEY_ARRAY(size);
} }
@@ -324,8 +342,9 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public void addElements(int from, KEY_TYPE[] a, int offset, int length) { public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
if(length <= 0) return; if(length <= 0) return;
checkAddRange(from); checkAddRange(from);
SanityChecks.checkArrayCapacity(a.length, offset, length);
grow(size + length); grow(size + length);
if(from != size) System.arraycopy(data, from, data, from+length, size - length); if(from != size) System.arraycopy(data, from, data, from+length, size - from);
size+=length; size+=length;
System.arraycopy(a, offset, data, from, length); System.arraycopy(a, offset, data, from, length);
} }
@@ -361,11 +380,11 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
int length = to - from; int length = to - from;
if(length <= 0) return; if(length <= 0) return;
if(to != size) System.arraycopy(data, to, data, from, size - to); if(to != size) System.arraycopy(data, to, data, from, size - to);
size -= length;
#if TYPE_OBJECT #if TYPE_OBJECT
for(int i = 0;i<length;i++) for(int i = 0;i<length;i++)
data[i+to] = null; data[i+size] = null;
#endif #endif
size -= length;
} }
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -381,13 +400,13 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
checkRange(from); checkRange(from);
checkAddRange(to); checkAddRange(to);
int length = to - from; int length = to - from;
if(length <= 0) return ARRAYS.newArray(type, 0);
K[] a = ARRAYS.newArray(type, length); K[] a = ARRAYS.newArray(type, length);
if(length <= 0) return a;
System.arraycopy(data, from, a, 0, length); System.arraycopy(data, from, a, 0, length);
if(to != size) System.arraycopy(data, to, data, from, size - to); if(to != size) System.arraycopy(data, to, data, from, size - to);
for(int i = 0;i<length;i++)
data[i+to] = null;
size -= length; size -= length;
for(int i = 0;i<length;i++)
data[i+size] = null;
return a; return a;
} }
@@ -585,6 +604,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return data[(size() - 1) - index]; return data[(size() - 1) - index];
} }
#if IARRAY_FEATURE
/** /**
* Provides the Underlying Array in the Implementation * Provides the Underlying Array in the Implementation
* @return underlying Array * @return underlying Array
@@ -604,6 +624,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return data.getClass() != Object[].class; return data.getClass() != Object[].class;
} }
#endif
#endif #endif
/** /**
* A Type Specific foreach function that reduces (un)boxing * A Type Specific foreach function that reduces (un)boxing
@@ -637,7 +658,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(data[i])) return true; if(filter.test(data[i])) return true;
} }
return false; return false;
} }
@@ -646,7 +667,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(data[i])) return false; if(filter.test(data[i])) return false;
} }
return true; return true;
} }
@@ -655,7 +676,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(!filter.TEST_VALUE(data[i])) return false; if(!filter.test(data[i])) return false;
} }
return true; return true;
} }
@@ -664,7 +685,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(data[i])) return data[i]; if(filter.test(data[i])) return data[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -713,7 +734,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(data[i])) result++; if(filter.test(data[i])) result++;
} }
return result; return result;
} }
@@ -1024,6 +1045,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override @Override
@Primitive @Primitive
public Object[] toArray() { public Object[] toArray() {
if(size == 0) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size]; Object[] obj = new Object[size];
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
obj[i] = KEY_TO_OBJ(data[i]); obj[i] = KEY_TO_OBJ(data[i]);
@@ -1059,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
@@ -1157,8 +1185,8 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
} }
#if SPLIT_ITERATOR_FEATURE
#if PRIMITIVES #if PRIMITIVES && STREAM_FEATURE
/** /**
* Returns a Java-Type-Specific Stream to reduce boxing/unboxing. * Returns a Java-Type-Specific Stream to reduce boxing/unboxing.
* @return a Stream of the closest java type * @return a Stream of the closest java type
@@ -1175,4 +1203,5 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
*/ */
@Override @Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createArraySplititerator(data, size, 16464); } public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createArraySplititerator(data, size, 16464); }
#endif
} }
@@ -9,14 +9,21 @@ import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
#if TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
#if TYPE_OBJECT
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.IntFunction;
#endif
#if !TYPE_OBJECT && JDK_FUNCTION
import java.util.function.PREDICATE;
#endif #endif
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
#if PRIMITIVES #if PRIMITIVES
#if !JDK_FUNCTION
import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_PREDICATE;
#endif
import java.util.function.JAVA_UNARY_OPERATOR; import java.util.function.JAVA_UNARY_OPERATOR;
import java.nio.JAVA_BUFFER; import java.nio.JAVA_BUFFER;
#endif #endif
@@ -31,21 +38,26 @@ 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.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#if TYPE_OBJECT #if TYPE_OBJECT
import speiger.src.collections.utils.Stack; import speiger.src.collections.utils.Stack;
#else
import speiger.src.collections.objects.utils.ObjectArrays;
#endif #endif
#if PRIMITIVES #if PRIMITIVES && STREAM_FEATURE && SPLIT_ITERATOR_FEATURE
import java.util.stream.JAVA_STREAM; import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
#endif #endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@@ -147,14 +159,22 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
* @Type(T) * @Type(T)
* @return a typed List * @return a typed List
*/ */
public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE of(Class<KEY_TYPE> c) { public static GENERIC_KEY_BRACES COPY_ON_WRITE_LIST KEY_GENERIC_TYPE of(Class<KEY_TYPE> c) {
ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); COPY_ON_WRITE_LIST KEY_GENERIC_TYPE list = new COPY_ON_WRITE_LISTBRACES();
list.data = (KEY_TYPE[])ObjectArrays.newArray(c, 0); list.data = (KEY_TYPE[])ObjectArrays.newArray(c, 0);
return list; return list;
} }
#endif #endif
private void setArray(KEY_TYPE[] data) {
this.data = data;
}
private KEY_TYPE[] getArray() {
return data;
}
/** /**
* Appends the specified element to the end of this list. * Appends the specified element to the end of this list.
* *
@@ -365,6 +385,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
int size = data.length; int size = data.length;
if(from < 0 || from > size) throw new IndexOutOfBoundsException("Index: " + from + ", Size: " + size); if(from < 0 || from > size) throw new IndexOutOfBoundsException("Index: " + from + ", Size: " + size);
SanityChecks.checkArrayCapacity(a.length, offset, length);
KEY_TYPE[] newElements; KEY_TYPE[] newElements;
if(from == size) { if(from == size) {
newElements = Arrays.copyOf(data, size+length); newElements = Arrays.copyOf(data, size+length);
@@ -409,6 +430,8 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
*/ */
@Override @Override
public void removeElements(int from, int to) { public void removeElements(int from, int to) {
checkRange(from);
checkAddRange(to);
int length = to - from; int length = to - from;
if(length <= 0) return; if(length <= 0) return;
ReentrantLock lock = this.lock; ReentrantLock lock = this.lock;
@@ -439,9 +462,11 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
*/ */
@Override @Override
public <K> K[] extractElements(int from, int to, Class<K> type) { public <K> K[] extractElements(int from, int to, Class<K> type) {
checkRange(from);
checkAddRange(to);
int length = to - from; int length = to - from;
if(length <= 0) return ARRAYS.newArray(type, 0);
K[] a = ARRAYS.newArray(type, length); K[] a = ARRAYS.newArray(type, length);
if(length <= 0) return a;
ReentrantLock lock = this.lock; ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
@@ -449,9 +474,9 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
System.arraycopy(data, from, a, 0, length); System.arraycopy(data, from, a, 0, length);
if(to == data.length) this.data = Arrays.copyOf(data, data.length - length); if(to == data.length) this.data = Arrays.copyOf(data, data.length - length);
else { else {
int size = data.length-1; int size = data.length;
KEY_TYPE[] newElements = NEW_KEY_ARRAY(size); KEY_TYPE[] newElements = NEW_KEY_ARRAY(size-length);
System.arraycopy(data, 0, newElements, 0, from); if(from != 0) System.arraycopy(data, 0, newElements, 0, from);
System.arraycopy(data, to, newElements, from, size - to); System.arraycopy(data, to, newElements, from, size - to);
this.data = newElements; this.data = newElements;
} }
@@ -471,6 +496,8 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
*/ */
@Override @Override
public KEY_TYPE[] extractElements(int from, int to) { public KEY_TYPE[] extractElements(int from, int to) {
checkRange(from);
checkAddRange(to);
int length = to - from; int length = to - from;
if(length <= 0) return EMPTY_KEY_ARRAY; if(length <= 0) return EMPTY_KEY_ARRAY;
ReentrantLock lock = this.lock; ReentrantLock lock = this.lock;
@@ -481,9 +508,9 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
System.arraycopy(data, from, a, 0, length); System.arraycopy(data, from, a, 0, length);
if(to == data.length) this.data = Arrays.copyOf(data, data.length - length); if(to == data.length) this.data = Arrays.copyOf(data, data.length - length);
else { else {
int size = data.length-1; int size = data.length;
KEY_TYPE[] newElements = NEW_KEY_ARRAY(size); KEY_TYPE[] newElements = NEW_KEY_ARRAY(size-length);
System.arraycopy(data, 0, newElements, 0, from); if(from != 0) System.arraycopy(data, 0, newElements, 0, from);
System.arraycopy(data, to, newElements, from, size - to); System.arraycopy(data, to, newElements, from, size - to);
this.data = newElements; this.data = newElements;
} }
@@ -719,7 +746,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) { public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
SanityChecks.checkArrayCapacity(data.length, fromIndex, toIndex-fromIndex); SanityChecks.checkArrayCapacity(data.length, fromIndex, toIndex-fromIndex);
return new COWSubListBRACES(this, 0, fromIndex, toIndex); return new COWSubListBRACES(this, lock, this::setArray, this::getArray, 0, fromIndex, toIndex);
} }
/** /**
@@ -757,7 +784,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(filter.TEST_VALUE(data[i])) return true; if(filter.test(data[i])) return true;
} }
return false; return false;
} }
@@ -767,7 +794,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(filter.TEST_VALUE(data[i])) return false; if(filter.test(data[i])) return false;
} }
return true; return true;
} }
@@ -777,7 +804,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(!filter.TEST_VALUE(data[i])) return false; if(!filter.test(data[i])) return false;
} }
return true; return true;
} }
@@ -787,7 +814,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(filter.TEST_VALUE(data[i])) return data[i]; if(filter.test(data[i])) return data[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -840,7 +867,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
int result = 0; int result = 0;
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(filter.TEST_VALUE(data[i])) result++; if(filter.test(data[i])) result++;
} }
return result; return result;
} }
@@ -1266,6 +1293,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
public Object[] toArray() { public Object[] toArray() {
KEY_TYPE[] data = this.data; KEY_TYPE[] data = this.data;
int size = data.length; int size = data.length;
if(size == 0) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size]; Object[] obj = new Object[size];
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
obj[i] = KEY_TO_OBJ(data[i]); obj[i] = KEY_TO_OBJ(data[i]);
@@ -1304,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
@@ -1388,7 +1421,13 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + data.length); throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + data.length);
} }
#if PRIMITIVES protected void checkAddRange(int index) {
if (index < 0 || index > data.length)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + data.length);
}
#if SPLIT_ITERATOR_FEATURE
#if PRIMITIVES && STREAM_FEATURE
/** /**
* Returns a Java-Type-Specific Stream to reduce boxing/unboxing. * Returns a Java-Type-Specific Stream to reduce boxing/unboxing.
* @return a Stream of the closest java type * @return a Stream of the closest java type
@@ -1406,6 +1445,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createArraySplititerator(data, data.length, 16464); } public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createArraySplititerator(data, data.length, 16464); }
#endif
static final class COWIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE static final class COWIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE
{ {
KEY_TYPE[] data; KEY_TYPE[] data;
@@ -1435,7 +1475,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
return data[index--]; return data[--index];
} }
@Override @Override
@@ -1458,7 +1498,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (data.length - 1) - index); int steps = Math.min(amount, data.length - index);
index += steps; index += steps;
return steps; return steps;
} }
@@ -1474,13 +1514,19 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
private static class COWSubList KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE private static class COWSubList KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
{ {
final COPY_ON_WRITE_LIST KEY_GENERIC_TYPE list; final ABSTRACT_LIST KEY_GENERIC_TYPE list;
final ReentrantLock lock;
final Consumer<KEY_TYPE[]> setter;
final Supplier<KEY_TYPE[]> getter;
final int parentOffset; final int parentOffset;
final int offset; final int offset;
int size; int size;
public COWSubList(COPY_ON_WRITE_LIST KEY_GENERIC_TYPE list, int offset, int from, int to) { public COWSubList(ABSTRACT_LIST KEY_GENERIC_TYPE list, ReentrantLock lock, Consumer<KEY_TYPE[]> setter, Supplier<KEY_TYPE[]> getter, int offset, int from, int to) {
this.list = list; this.list = list;
this.lock = lock;
this.setter = setter;
this.getter = getter;
this.parentOffset = from; this.parentOffset = from;
this.offset = offset + from; this.offset = offset + from;
this.size = to - from; this.size = to - from;
@@ -1488,7 +1534,6 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public void add(int index, KEY_TYPE element) { public void add(int index, KEY_TYPE element) {
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkAddSubRange(index); checkAddSubRange(index);
@@ -1504,7 +1549,6 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) { public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
int add = c.size(); int add = c.size();
if(add <= 0) return false; if(add <= 0) return false;
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkAddSubRange(index); checkAddSubRange(index);
@@ -1521,7 +1565,6 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) { public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
int add = c.size(); int add = c.size();
if(add <= 0) return false; if(add <= 0) return false;
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkAddSubRange(index); checkAddSubRange(index);
@@ -1538,7 +1581,6 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
int add = c.size(); int add = c.size();
if(add <= 0) return false; if(add <= 0) return false;
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkAddSubRange(index); checkAddSubRange(index);
@@ -1554,7 +1596,6 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) { public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
if(length <= 0) return; if(length <= 0) return;
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkAddSubRange(from); checkAddSubRange(from);
@@ -1570,17 +1611,16 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
SanityChecks.checkArrayCapacity(size, from, length); SanityChecks.checkArrayCapacity(size, from, length);
SanityChecks.checkArrayCapacity(a.length, offset, length); SanityChecks.checkArrayCapacity(a.length, offset, length);
return list.getElements(from+this.offset, a, offset, length); return list.getElements(from+parentOffset, a, offset, length);
} }
@Override @Override
public void removeElements(int from, int to) { public void removeElements(int from, int to) {
if(to-from <= 0) return; if(to-from <= 0) return;
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkSubRange(from); checkSubRange(from);
checkSubRange(to); checkAddSubRange(to);
list.removeElements(from+parentOffset, to+parentOffset); list.removeElements(from+parentOffset, to+parentOffset);
size -= to - from; size -= to - from;
} }
@@ -1592,13 +1632,12 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
#if TYPE_OBJECT #if TYPE_OBJECT
@Override @Override
public <K> K[] extractElements(int from, int to, Class<K> type) { public <K> K[] extractElements(int from, int to, Class<K> type) {
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkSubRange(from); checkSubRange(from);
checkSubRange(to); checkAddSubRange(to);
K[] result = list.extractElements(from+parentOffset, to+parentOffset, type); K[] result = list.extractElements(from+parentOffset, to+parentOffset, type);
size -= to - from; size -= result.length;
return result; return result;
} }
finally { finally {
@@ -1609,13 +1648,12 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
#else #else
@Override @Override
public KEY_TYPE[] extractElements(int from, int to) { public KEY_TYPE[] extractElements(int from, int to) {
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkSubRange(from); checkSubRange(from);
checkSubRange(to); checkAddSubRange(to);
KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset); KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset);
size -= to - from; size -= result.length;
return result; return result;
} }
finally { finally {
@@ -1627,16 +1665,15 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public KEY_TYPE GET_KEY(int index) { public KEY_TYPE GET_KEY(int index) {
checkSubRange(index); checkSubRange(index);
return list.GET_KEY(offset+index); return list.GET_KEY(parentOffset+index);
} }
@Override @Override
public KEY_TYPE set(int index, KEY_TYPE element) { public KEY_TYPE set(int index, KEY_TYPE element) {
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkSubRange(index); checkSubRange(index);
return list.set(offset+index, element); return list.set(parentOffset+index, element);
} }
finally { finally {
lock.unlock(); lock.unlock();
@@ -1645,11 +1682,18 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public KEY_TYPE swapRemove(int index) { public KEY_TYPE swapRemove(int index) {
ReentrantLock lock = list.lock; if(index < 0 || index >= size) throw new IndexOutOfBoundsException();
ReentrantLock lock = this.lock;
lock.lock(); lock.lock();
try { try {
checkSubRange(index); KEY_TYPE[] data = getter.get();
KEY_TYPE result = list.swapRemove(index+parentOffset); KEY_TYPE result = data[offset+index];
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length-1);
int end = offset+size-1;
System.arraycopy(data, 0, newElements, 0, end);
if(end != newElements.length) System.arraycopy(data, end+1, newElements, end, data.length-end-1);
if(index+offset != end) newElements[index+offset] = data[end];
setter.accept(newElements);
size--; size--;
return result; return result;
} }
@@ -1660,7 +1704,6 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public KEY_TYPE REMOVE(int index) { public KEY_TYPE REMOVE(int index) {
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
checkSubRange(index); checkSubRange(index);
@@ -1673,6 +1716,371 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
} }
} }
#if !TYPE_OBJECT
@Override
public boolean REMOVE_KEY(KEY_TYPE type) {
int index = indexOf(type);
if(index == -1) return false;
REMOVE(index);
return true;
}
#else
@Override
public boolean remove(Object type) {
int index = indexOf(type);
if(index == -1) return false;
REMOVE(index);
return true;
}
#endif
#if TYPE_OBJECT
@Override
public void sort(Comparator<? super CLASS_TYPE> c) {
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newData = Arrays.copyOf(data, data.length);
if(c != null) ARRAYS.stableSort(newData, offset, offset+size, c);
else ARRAYS.stableSort(newData, offset, offset+size);
setter.accept(newData);
}
finally {
lock.unlock();
}
}
@Override
public void unstableSort(Comparator<? super CLASS_TYPE> c) {
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newData = Arrays.copyOf(data, data.length);
if(c != null) ARRAYS.unstableSort(newData, offset, offset+size, c);
else ARRAYS.unstableSort(newData, offset, offset+size);
setter.accept(newData);
}
finally {
lock.unlock();
}
}
#else
@Override
public void sort(COMPARATOR c) {
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newData = Arrays.copyOf(data, data.length);
if(c != null) ARRAYS.stableSort(newData, offset, offset+size, c);
else ARRAYS.stableSort(newData, offset, offset+size);
setter.accept(newData);
}
finally {
lock.unlock();
}
}
@Override
public void unstableSort(COMPARATOR c) {
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newData = Arrays.copyOf(data, data.length);
if(c != null) ARRAYS.unstableSort(newData, offset, offset+size, c);
else ARRAYS.unstableSort(newData, offset, offset+size);
setter.accept(newData);
}
finally {
lock.unlock();
}
}
#endif
@Override
@Deprecated
public boolean removeAll(Collection<?> c) {
if(c.isEmpty()) return false;
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length);
int j = 0;
for(int i= 0,m=data.length;i<m;i++) {
if(i < offset || i >= offset+size) newElements[j++] = data[i];
else if(!c.contains(KEY_TO_OBJ(data[i]))) newElements[j++] = data[i];
}
if(data.length != j) {
setter.accept(Arrays.copyOf(newElements, j));
size -= data.length - j;
return true;
}
return false;
}
finally {
lock.unlock();
}
}
@Override
@Deprecated
public boolean retainAll(Collection<?> c) {
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
if(c.isEmpty()) {
if(size > 0) {
clear();
return true;
}
return false;
}
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length);
int j = 0;
for(int i= 0,m=data.length;i<m;i++) {
if(i < offset || i >= offset+size) newElements[j++] = data[i];
else if(c.contains(KEY_TO_OBJ(data[i]))) newElements[j++] = data[i];
}
if(data.length != j) {
setter.accept(Arrays.copyOf(newElements, j));
size -= data.length - j;
return true;
}
return false;
}
finally {
lock.unlock();
}
}
@Override
@Deprecated
public boolean removeIf(Predicate<? super CLASS_TYPE> filter) {
Objects.requireNonNull(filter);
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length);
int j = 0;
for(int i= 0,m=data.length;i<m;i++) {
if(i < offset || i >= offset+size) newElements[j++] = data[i];
else if(!filter.test(KEY_TO_OBJ(data[i]))) newElements[j++] = data[i];
}
if(data.length != j) {
setter.accept(Arrays.copyOf(newElements, j));
size -= data.length - j;
return true;
}
return false;
}
finally {
lock.unlock();
}
}
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) {
if(c.isEmpty()) return false;
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length);
int j = 0;
for(int i= 0,m=data.length;i<m;i++) {
if(i < offset || i >= offset+size) newElements[j++] = data[i];
else if(!c.contains(data[i])) newElements[j++] = data[i];
}
if(data.length != j) {
setter.accept(Arrays.copyOf(newElements, j));
size -= data.length - j;
return true;
}
return false;
}
finally {
lock.unlock();
}
}
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
if(c.isEmpty()) return false;
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length);
int j = 0;
for(int i= 0,m=data.length;i<m;i++) {
if(i < offset || i >= offset+size) newElements[j++] = data[i];
else if(!c.contains(data[i])) newElements[j++] = data[i];
else r.accept(data[i]);
}
if(data.length != j) {
setter.accept(Arrays.copyOf(newElements, j));
size -= data.length - j;
return true;
}
return false;
}
finally {
lock.unlock();
}
}
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) {
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
if(c.isEmpty()) {
if(size > 0) {
clear();
return true;
}
return false;
}
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length);
int j = 0;
for(int i= 0,m=data.length;i<m;i++) {
if(i < offset || i >= offset+size) newElements[j++] = data[i];
else if(c.contains(data[i])) newElements[j++] = data[i];
}
if(data.length != j) {
setter.accept(Arrays.copyOf(newElements, j));;
size -= data.length - j;
return true;
}
return false;
}
finally {
lock.unlock();
}
}
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c, CONSUMER KEY_GENERIC_TYPE r) {
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
if(c.isEmpty()) {
if(size > 0) {
forEach(r);
clear();
return true;
}
return false;
}
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length);
int j = 0;
for(int i= 0,m=data.length;i<m;i++) {
if(i < offset || i >= offset+size) newElements[j++] = data[i];
else if(c.contains(data[i])) newElements[j++] = data[i];
else r.accept(data[i]);
}
if(data.length != j) {
setter.accept(Arrays.copyOf(newElements, j));
size -= data.length - j;
return true;
}
return false;
}
finally {
lock.unlock();
}
}
#if PRIMITIVES
@Override
public boolean remIf(JAVA_PREDICATE filter) {
Objects.requireNonNull(filter);
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newElements = NEW_KEY_ARRAY(data.length);
int j = 0;
for(int i=0,m=data.length;i<m;i++) {
if(i < offset || i >= offset+size) newElements[j++] = data[i];
else if(!filter.test(data[i])) newElements[j++] = data[i];
}
if(data.length != j) {
setter.accept(Arrays.copyOf(newElements, j));
size -= data.length - j;
return true;
}
return false;
}
finally {
lock.unlock();
}
}
#endif
@Override
@Primitive
public void replaceAll(UnaryOperator<CLASS_TYPE> o) {
#if PRIMITIVES
Objects.requireNonNull(o);
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ(SanityChecks.SANITY_CAST(T)))));
#else
REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ(T))));
#endif
#else
Objects.requireNonNull(o);
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newData = Arrays.copyOf(data, data.length);
for(int i = 0,m=size;i<m;i++)
newData[i+offset] = OBJ_TO_KEY(o.apply(KEY_TO_OBJ(newData[i+offset])));
setter.accept(newData);
}
finally {
lock.unlock();
}
#endif
}
#if PRIMITIVES
@Override
public void REPLACE(JAVA_UNARY_OPERATOR o) {
Objects.requireNonNull(o);
ReentrantLock lock = this.lock;
lock.lock();
try {
KEY_TYPE[] data = getter.get();
KEY_TYPE[] newData = Arrays.copyOf(data, data.length);
for(int i = 0,m=size;i<m;i++)
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
newData[i+offset] = SanityChecks.SANITY_CAST(o.APPLY_CAST(newData[i+offset]));
#else
newData[i+offset] = o.APPLY(newData[i+offset]);
#endif
setter.accept(newData);
}
finally {
lock.unlock();
}
}
#endif
@Override @Override
public int size() { public int size() {
return size; return size;
@@ -1681,10 +2089,9 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public void clear() { public void clear() {
if(size == 0) return; if(size == 0) return;
ReentrantLock lock = list.lock;
lock.lock(); lock.lock();
try { try {
list.removeElements(offset, offset+size); list.removeElements(parentOffset, parentOffset+size);
size = 0; size = 0;
} }
finally { finally {
@@ -1692,9 +2099,11 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
} }
} }
#if SPLIT_ITERATOR_FEATURE
@Override @Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 16464); } public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 16464); }
#endif
@Override @Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) { public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
if(index < 0 || index > size()) throw new IndexOutOfBoundsException(); if(index < 0 || index > size()) throw new IndexOutOfBoundsException();
@@ -1704,7 +2113,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) { public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
SanityChecks.checkArrayCapacity(size, fromIndex, toIndex-fromIndex); SanityChecks.checkArrayCapacity(size, fromIndex, toIndex-fromIndex);
return new COWSubListBRACES(list, offset, fromIndex, toIndex); return new COWSubListBRACES(this, lock, setter, getter, offset, fromIndex, toIndex);
} }
protected void checkSubRange(int index) { protected void checkSubRange(int index) {
@@ -1772,7 +2181,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
@Override @Override
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (list.size() - 1) - index); int steps = Math.min(amount, list.size() - index);
index += steps; index += steps;
return steps; return steps;
} }
@@ -13,8 +13,13 @@ import java.util.function.Consumer;
#endif #endif
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
#if !TYPE_OBJECT && JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
#if PRIMITIVES #if PRIMITIVES
#if !JDK_FUNCTION
import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_PREDICATE;
#endif
import java.util.function.JAVA_UNARY_OPERATOR; import java.util.function.JAVA_UNARY_OPERATOR;
#endif #endif
@@ -25,16 +30,20 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif #endif
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.objects.utils.ObjectArrays; import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#if PRIMITIVES #if PRIMITIVES && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE
import java.util.stream.JAVA_STREAM; import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
#endif #endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -129,7 +138,8 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
@Override @Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
SanityChecks.checkArrayCapacity(data.length, offset, length); SanityChecks.checkArrayCapacity(a.length, offset, length);
SanityChecks.checkArrayCapacity(data.length, from, length);
System.arraycopy(data, from, a, offset, length); System.arraycopy(data, from, a, offset, length);
return a; return a;
} }
@@ -301,7 +311,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(filter.TEST_VALUE(data[i])) return true; if(filter.test(data[i])) return true;
} }
return false; return false;
} }
@@ -310,7 +320,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(filter.TEST_VALUE(data[i])) return false; if(filter.test(data[i])) return false;
} }
return true; return true;
} }
@@ -319,7 +329,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(!filter.TEST_VALUE(data[i])) return false; if(!filter.test(data[i])) return false;
} }
return true; return true;
} }
@@ -328,7 +338,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(filter.TEST_VALUE(data[i])) return data[i]; if(filter.test(data[i])) return data[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -377,7 +387,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(int i = 0,m=data.length;i<m;i++) { for(int i = 0,m=data.length;i<m;i++) {
if(filter.TEST_VALUE(data[i])) result++; if(filter.test(data[i])) result++;
} }
return result; return result;
} }
@@ -436,6 +446,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
@Override @Override
@Primitive @Primitive
public Object[] toArray() { public Object[] toArray() {
if(data.length == 0) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[data.length]; Object[] obj = new Object[data.length];
for(int i = 0,m=data.length;i<m;i++) for(int i = 0,m=data.length;i<m;i++)
obj[i] = KEY_TO_OBJ(data[i]); obj[i] = KEY_TO_OBJ(data[i]);
@@ -487,7 +498,8 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + data.length); throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + data.length);
} }
#if PRIMITIVES #if SPLIT_ITERATOR_FEATURE
#if PRIMITIVES && STREAM_FEATURE
/** /**
* Returns a Java-Type-Specific Stream to reduce boxing/unboxing. * Returns a Java-Type-Specific Stream to reduce boxing/unboxing.
* @return a Stream of the closest java type * @return a Stream of the closest java type
@@ -505,6 +517,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
@Override @Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createArraySplititerator(data, data.length, 16464); } public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createArraySplititerator(data, data.length, 16464); }
#endif
private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE { private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index; int index;
@@ -556,7 +569,7 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T
@Override @Override
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (size() - 1) - index); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
return steps; return steps;
} }
@@ -1,7 +1,10 @@
package speiger.src.collections.PACKAGE.lists; package speiger.src.collections.PACKAGE.lists;
#if TYPE_OBJECT #if TYPE_OBJECT
#if DEQUEUE_FEATURE
import java.util.Comparator; import java.util.Comparator;
#endif
import java.util.function.BiFunction; import java.util.function.BiFunction;
#else if PRIMITIVES #else if PRIMITIVES
import java.nio.JAVA_BUFFER; import java.nio.JAVA_BUFFER;
@@ -10,44 +13,63 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects; import java.util.Objects;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
#if SPLIT_ITERATOR_FEATURE
import java.util.Spliterator; import java.util.Spliterator;
#if PRIMITIVES #if PRIMITIVES
import java.util.Spliterator.JAVA_SPLIT_ITERATOR; import java.util.Spliterator.JAVA_SPLIT_ITERATOR;
#endif #endif
import java.util.function.Consumer; import java.util.function.Consumer;
#endif
import java.util.function.Predicate; import java.util.function.Predicate;
#if TYPE_OBJECT
import java.util.function.IntFunction;
#endif
#if !TYPE_OBJECT && JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
#if PRIMITIVES #if PRIMITIVES
#if !JDK_FUNCTION
import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_PREDICATE;
#endif
import java.util.function.JAVA_UNARY_OPERATOR; import java.util.function.JAVA_UNARY_OPERATOR;
#endif #endif
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.STACK; import speiger.src.collections.PACKAGE.collections.STACK;
#else
import speiger.src.collections.ints.functions.function.Int2ObjectFunction;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if DEQUEUE_FEATURE
import speiger.src.collections.PACKAGE.queues.PRIORITY_DEQUEUE; import speiger.src.collections.PACKAGE.queues.PRIORITY_DEQUEUE;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
#if DEQUEUE_FEATURE
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
import speiger.src.collections.objects.utils.ObjectArrays;
#if TYPE_OBJECT #if TYPE_OBJECT
import speiger.src.collections.utils.Stack; import speiger.src.collections.utils.Stack;
#else
import speiger.src.collections.objects.utils.ObjectArrays;
#endif #endif
#if SPLIT_ITERATOR_FEATURE
#if PRIMITIVES #if PRIMITIVES
import java.util.stream.JAVA_STREAM; import java.util.stream.JAVA_STREAM;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
#endif #endif
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
@@ -62,10 +84,10 @@ import speiger.src.collections.utils.SanityChecks;
* *
* @Type(T) * @Type(T)
*/ */
#if TYPE_OBJECT #if DEQUEUE_FEATURE
public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_GENERIC_TYPE, Stack KEY_GENERIC_TYPE
#else
public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_GENERIC_TYPE, STACK KEY_GENERIC_TYPE public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_GENERIC_TYPE, STACK KEY_GENERIC_TYPE
#else
public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements STACK KEY_GENERIC_TYPE
#endif #endif
{ {
Entry KEY_GENERIC_TYPE first; Entry KEY_GENERIC_TYPE first;
@@ -152,10 +174,16 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
int length = c.size(); int length = c.size();
if(length == 0) return false; if(length == 0) return false;
checkAddRange(index); checkAddRange(index);
Entry KEY_GENERIC_TYPE next = null; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE prev = null; Entry KEY_GENERIC_TYPE prev;
if(index == size) prev = last; if(index == size) {
else if(index == 0) next = first; prev = last;
next = null;
}
else if(index == 0) {
next = first;
prev = null;
}
else { else {
next = getNode(index); next = getNode(index);
prev = next.prev; prev = next.prev;
@@ -177,30 +205,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override @Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
int length = c.size(); return addAll(index, (COLLECTION KEY_GENERIC_TYPE)c); //
if(length == 0) return false;
checkAddRange(index);
Entry KEY_GENERIC_TYPE next = null;
Entry KEY_GENERIC_TYPE prev = null;
if(index == size) prev = last;
else if(index == 0) next = first;
else {
next = getNode(index);
prev = next.prev;
}
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();) {
Entry KEY_GENERIC_TYPE entry = new EntryBRACES(iter.NEXT(), prev, null);
if(prev == null) first = entry;
else prev.next = entry;
prev = entry;
}
if(next == null) last = prev;
else {
prev.next = next;
next.prev = prev;
}
size += length;
return true;
} }
@Override @Override
@@ -210,10 +215,16 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
int length = c.size(); int length = c.size();
if(length == 0) return false; if(length == 0) return false;
checkAddRange(index); checkAddRange(index);
Entry KEY_GENERIC_TYPE next = null; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE prev = null; Entry KEY_GENERIC_TYPE prev;
if(index == size) prev = last; if(index == size) {
else if(index == 0) next = first; prev = last;
next = null;
}
else if(index == 0) {
next = first;
prev = null;
}
else { else {
next = getNode(index); next = getNode(index);
prev = next.prev; prev = next.prev;
@@ -233,6 +244,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return true; return true;
} }
#if DEQUEUE_FEATURE
@Override @Override
public void enqueue(KEY_TYPE e) { public void enqueue(KEY_TYPE e) {
add(e); add(e);
@@ -243,6 +255,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
add(0, e); add(0, e);
} }
#endif
@Override @Override
public void push(KEY_TYPE e) { public void push(KEY_TYPE e) {
add(e); add(e);
@@ -258,12 +271,19 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override @Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) { public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
if(length <= 0) return;
SanityChecks.checkArrayCapacity(a.length, offset, length); SanityChecks.checkArrayCapacity(a.length, offset, length);
checkAddRange(from); checkAddRange(from);
Entry KEY_GENERIC_TYPE next = null; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE prev = null; Entry KEY_GENERIC_TYPE prev;
if(from == size) prev = last; if(from == size) {
else if(from == 0) next = first; prev = last;
next = null;
}
else if(from == 0) {
next = first;
prev = null;
}
else { else {
next = getNode(from); next = getNode(from);
prev = next.prev; prev = next.prev;
@@ -295,18 +315,41 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return a; return a;
} }
#if DEQUEUE_FEATURE
@Override @Override
public KEY_TYPE first() { public KEY_TYPE first() {
if(first == null) throw new IllegalStateException(); return GET_FIRST_KEY();
return first.value;
} }
@Override @Override
public KEY_TYPE last() { public KEY_TYPE last() {
if(last == null) throw new IllegalStateException(); return GET_LAST_KEY();
}
#endif
@Override
public KEY_TYPE GET_FIRST_KEY() {
if(first == null) throw new NoSuchElementException();
return first.value;
}
@Override
public KEY_TYPE GET_LAST_KEY() {
if(last == null) throw new NoSuchElementException();
return last.value; return last.value;
} }
@Override
public KEY_TYPE REMOVE_FIRST_KEY() {
if(first == null) throw new NoSuchElementException();
return unlinkFirst(first);
}
@Override
public KEY_TYPE REMOVE_LAST_KEY() {
return pop();
}
@Override @Override
public KEY_TYPE peek(int index) { public KEY_TYPE peek(int index) {
return GET_KEY((size() - 1) - index); return GET_KEY((size() - 1) - index);
@@ -377,6 +420,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return new ListIter(getNode(index), index); return new ListIter(getNode(index), index);
} }
#if SPLIT_ITERATOR_FEATURE
#if PRIMITIVES #if PRIMITIVES
/** /**
* Returns a Java-Type-Specific Stream to reduce boxing/unboxing. * Returns a Java-Type-Specific Stream to reduce boxing/unboxing.
@@ -397,6 +441,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override @Override
public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return new TypeSplitIteratorBRACES(this, first, 0); } public SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return new TypeSplitIteratorBRACES(this, first, 0); }
#endif
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -405,6 +450,14 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next)
action.accept(index++, entry.value);
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -416,7 +469,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(filter.TEST_VALUE(entry.value)) return true; if(filter.test(entry.value)) return true;
} }
return false; return false;
} }
@@ -425,7 +478,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(filter.TEST_VALUE(entry.value)) return false; if(filter.test(entry.value)) return false;
} }
return true; return true;
} }
@@ -434,7 +487,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(!filter.TEST_VALUE(entry.value)) return false; if(!filter.test(entry.value)) return false;
} }
return true; return true;
} }
@@ -443,7 +496,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(filter.TEST_VALUE(entry.value)) return entry.value; if(filter.test(entry.value)) return entry.value;
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -492,7 +545,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(filter.TEST_VALUE(entry.value)) result++; if(filter.test(entry.value)) result++;
} }
return result; return result;
} }
@@ -529,6 +582,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
#endif #endif
#if DEQUEUE_FEATURE
@Override @Override
public void onChanged() {} public void onChanged() {}
@Override @Override
@@ -536,31 +590,30 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override @Override
public KEY_TYPE dequeue() { public KEY_TYPE dequeue() {
if(first == null) throw new IllegalStateException(); if(first == null) throw new NoSuchElementException();
return unlinkFirst(first); return unlinkFirst(first);
} }
@Override @Override
public KEY_TYPE dequeueLast() { public KEY_TYPE dequeueLast() {
if(last == null) throw new IllegalStateException(); return pop();
}
#endif
@Override
public KEY_TYPE pop() {
if(last == null) throw new NoSuchElementException();
return unlinkLast(last); return unlinkLast(last);
} }
@Override #if DEQUEUE_FEATURE
public KEY_TYPE pop() {
return dequeueLast();
}
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
if(size == 0) return false; #if TYPE_OBJECT
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) { return remove(e);
if(KEY_EQUALS(entry.value, e)) { #else
unlink(entry); return REMOVE_KEY(e);
return true; #endif
}
}
return false;
} }
@Override @Override
@@ -575,6 +628,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return false; return false;
} }
#endif
@Override @Override
public KEY_TYPE swapRemove(int index) { public KEY_TYPE swapRemove(int index) {
checkRange(index); checkRange(index);
@@ -593,12 +647,15 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
first = temp; first = temp;
return result; return result;
} }
else if(before.next != last) {
Entry KEY_GENERIC_TYPE temp = last; Entry KEY_GENERIC_TYPE temp = last;
last = temp.prev; last = temp.prev;
last.next = null; last.next = null;
temp.next = before.next; temp.next = before.next;
temp.prev = before; temp.prev = before;
before.next = temp; before.next = temp;
temp.next.prev = temp;
}
return result; return result;
} }
@@ -623,12 +680,15 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
first = temp; first = temp;
return true; return true;
} }
else if(before.next != last) {
Entry KEY_GENERIC_TYPE temp = last; Entry KEY_GENERIC_TYPE temp = last;
last = temp.prev; last = temp.prev;
last.next = null; last.next = null;
temp.next = before.next; temp.next = before.next;
temp.prev = before; temp.prev = before;
before.next = temp; before.next = temp;
temp.next.prev = temp;
}
return true; return true;
} }
} }
@@ -651,7 +711,14 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#else #else
@Override @Override
public boolean REMOVE_KEY(KEY_TYPE e) { public boolean REMOVE_KEY(KEY_TYPE e) {
return removeFirst(e); if(size == 0) return false;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
if(KEY_EQUALS(entry.value, e)) {
unlink(entry);
return true;
}
}
return false;
} }
#endif #endif
@@ -671,16 +738,18 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
if(from < size - to) { if(from < size - to) {
Entry KEY_GENERIC_TYPE entry = getNode(from); Entry KEY_GENERIC_TYPE entry = getNode(from);
while(length > 0) { while(length > 0) {
entry = entry.next; Entry KEY_GENERIC_TYPE next = entry.next;
unlink(entry.prev); unlink(entry);
entry = next;
length--; length--;
} }
return; return;
} }
Entry KEY_GENERIC_TYPE entry = getNode(to); Entry KEY_GENERIC_TYPE entry = getNode(to-1);
while(length > 0) { while(length > 0) {
entry = entry.prev; Entry KEY_GENERIC_TYPE prev = entry.prev;
unlink(entry.next); unlink(entry);
entry = prev;
length--; length--;
} }
} }
@@ -691,20 +760,22 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
checkRange(from); checkRange(from);
checkAddRange(to); checkAddRange(to);
int length = to - from; int length = to - from;
if(length <= 0) return ARRAYS.newArray(type, 0);
K[] a = ARRAYS.newArray(type, length); K[] a = ARRAYS.newArray(type, length);
if(length <= 0) return a;
if(from < size - to) { if(from < size - to) {
Entry KEY_GENERIC_TYPE entry = getNode(from); Entry KEY_GENERIC_TYPE entry = getNode(from);
for(int i = 0;length > 0;i++, length--) { for(int i = 0;length > 0;i++, length--) {
entry = entry.next; Entry KEY_GENERIC_TYPE next = entry.next;
a[i] = (K)unlink(entry.prev); a[i] = (K)unlink(entry);
entry = next;
} }
return a; return a;
} }
Entry KEY_GENERIC_TYPE entry = getNode(to); Entry KEY_GENERIC_TYPE entry = getNode(to-1);
for(int i = length-1;length > 0;i--) { for(int i = length-1;length > 0;i--, length--) {
entry = entry.prev; Entry KEY_GENERIC_TYPE prev = entry.prev;
a[i] = (K)unlink(entry.next); a[i] = (K)unlink(entry);
entry = prev;
} }
return a; return a;
} }
@@ -720,15 +791,17 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
if(from < size - to) { if(from < size - to) {
Entry KEY_GENERIC_TYPE entry = getNode(from); Entry KEY_GENERIC_TYPE entry = getNode(from);
for(int i = 0;length > 0;i++, length--) { for(int i = 0;length > 0;i++, length--) {
entry = entry.next; Entry KEY_GENERIC_TYPE next = entry.next;
d[i] = unlink(entry.prev); d[i] = unlink(entry);
entry = next;
} }
return d; return d;
} }
Entry KEY_GENERIC_TYPE entry = getNode(to); Entry KEY_GENERIC_TYPE entry = getNode(to-1);
for(int i = length-1;length > 0;i--) { for(int i = length-1;length > 0;i--, length--) {
entry = entry.prev; Entry KEY_GENERIC_TYPE prev = entry.prev;
d[i] = unlink(entry.next); d[i] = unlink(entry);
entry = prev;
} }
return d; return d;
} }
@@ -923,6 +996,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#endif #endif
@Override @Override
public Object[] toArray() { public Object[] toArray() {
if(size == 0) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size]; Object[] obj = new Object[size];
int i = 0; int i = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next) {
@@ -957,7 +1031,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#else #else
@Override @Override
public T[] toArray(Int2ObjectFunction<T[]> action) { public <E> E[] toArray(IntFunction<E[]> action) {
return super.toArray(action); return super.toArray(action);
} }
@@ -1100,12 +1174,16 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
Entry KEY_GENERIC_TYPE prev; Entry KEY_GENERIC_TYPE prev;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
public Entry(KEY_TYPE value, Entry KEY_GENERIC_TYPE prev, Entry KEY_GENERIC_TYPE next) public Entry(KEY_TYPE value, Entry KEY_GENERIC_TYPE prev, Entry KEY_GENERIC_TYPE next) {
{
this.value = value; this.value = value;
this.prev = prev; this.prev = prev;
this.next = next; this.next = next;
} }
@Override
public String toString() {
return KEY_TO_STRING(value);
}
} }
private class ListIter implements LIST_ITERATOR KEY_GENERIC_TYPE private class ListIter implements LIST_ITERATOR KEY_GENERIC_TYPE
@@ -1181,6 +1259,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
} }
#if SPLIT_ITERATOR_FEATURE
private static class TypeSplitIterator KEY_GENERIC_TYPE implements SPLIT_ITERATOR KEY_GENERIC_TYPE private static class TypeSplitIterator KEY_GENERIC_TYPE implements SPLIT_ITERATOR KEY_GENERIC_TYPE
{ {
static final int BATCH_UNIT = 1 << 10; static final int BATCH_UNIT = 1 << 10;
@@ -1239,7 +1318,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override @Override
public long estimateSize() { public long estimateSize() {
return list.size - index; return (long)list.size - (long)index;
} }
@Override @Override
@@ -1305,7 +1384,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
@Override @Override
public long estimateSize() { public long estimateSize() {
return list.size - index; return (long)list.size - (long)index;
} }
@Override @Override
@@ -1325,4 +1404,5 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
} }
} }
#endif #endif
#endif
} }
@@ -5,23 +5,33 @@ import java.nio.JAVA_BUFFER;
#endif #endif
import java.util.List; import java.util.List;
#if !TYPE_OBJECT && !TYPE_BOOLEAN #if !TYPE_OBJECT && !TYPE_BOOLEAN
import java.util.Objects;
import java.util.function.JAVA_UNARY_OPERATOR; import java.util.function.JAVA_UNARY_OPERATOR;
import java.util.function.UnaryOperator; #endif
#else if TYPE_OBJECT
import java.util.Objects; import java.util.Objects;
import java.util.Comparator;
#if !TYPE_BOOLEAN
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
#endif #endif
import java.util.Comparator;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#if LISTS_FEATURE
import speiger.src.collections.PACKAGE.utils.LISTS; import speiger.src.collections.PACKAGE.utils.LISTS;
#endif
#if INT_LIST_MODULE && !TYPE_INT
import speiger.src.collections.ints.lists.IntList;
#endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT #if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
#endif #endif
@@ -95,6 +105,46 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
*/ */
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c); public boolean addAll(int index, LIST KEY_GENERIC_TYPE c);
/**
* Helper method that returns the first element of a List.
* This function was introduced due to how annoying it is to get/remove the last element of a list.
* This simplifies this process a bit.
* @return first element of the list
*/
public default KEY_TYPE GET_FIRST_KEY() {
return GET_KEY(0);
}
/**
* Helper method that returns the last element of a List.
* This function was introduced due to how annoying it is to get/remove the last element of a list.
* This simplifies this process a bit.
* @return last element of the list
*/
public default KEY_TYPE GET_LAST_KEY() {
return GET_KEY(size() - 1);
}
/**
* Helper method that removes and returns the first element of a List.
* This function was introduced due to how annoying it is to get/remove the last element of a list.
* This simplifies this process a bit.
* @return first element of the list and removes it
*/
public default KEY_TYPE REMOVE_FIRST_KEY() {
return REMOVE(0);
}
/**
* Helper method that removes and returns the last element of a List.
* This function was introduced due to how annoying it is to get/remove the last element of a list.
* This simplifies this process a bit.
* @return last element of the list and removes it
*/
public default KEY_TYPE REMOVE_LAST_KEY() {
return REMOVE(size() - 1);
}
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** /**
* A Type-Specific get function to reduce (un)boxing * A Type-Specific get function to reduce (un)boxing
@@ -358,6 +408,16 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
} }
#endif #endif
/**
* A Indexed forEach implementation that allows you to keep track of how many elements were already iterated over.
* @param action The action to be performed for each element
* @throws java.lang.NullPointerException if the specified action is null
*/
@Override
public default void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size();i<m;action.accept(i, GET_KEY(i++)));
}
/** /**
* A Type-Specific Iterator of listIterator * A Type-Specific Iterator of listIterator
* @see java.util.List#listIterator * @see java.util.List#listIterator
@@ -372,6 +432,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)
@@ -379,6 +459,13 @@ 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
/** /**
* Creates a Wrapped List that is Synchronized * Creates a Wrapped List that is Synchronized
* @return a new List that is synchronized * @return a new List that is synchronized
@@ -401,6 +488,7 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
*/ */
public default LIST KEY_GENERIC_TYPE unmodifiable() { return LISTS.unmodifiable(this); } public default LIST KEY_GENERIC_TYPE unmodifiable() { return LISTS.unmodifiable(this); }
#endif
/** /**
* A function to ensure the elements are within the requested size. * A function to ensure the elements are within the requested size.
* If smaller then the stored elements they get removed as needed. * If smaller then the stored elements they get removed as needed.
@@ -510,10 +598,12 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
} }
#endif #endif
#endif #endif
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
*/ */
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
} }
@@ -3,15 +3,22 @@ package speiger.src.collections.PACKAGE.maps.abstracts;
import java.util.AbstractMap; import java.util.AbstractMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
#if VALUE_BOOLEAN && JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#if !VALUE_BOOLEAN || !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SET;
#if MAPS_FEATURE
import speiger.src.collections.PACKAGE.utils.maps.MAPS; import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
#if !SAME_TYPE #if !SAME_TYPE
@@ -19,6 +26,7 @@ import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
#endif #endif
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER; import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER;
import speiger.src.collections.objects.collections.ObjectIterable;
#if !TYPE_OBJECT && !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
#endif #endif
@@ -47,6 +55,22 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
return this; return this;
} }
protected ObjectIterable<MAP.Entry KEY_VALUE_GENERIC_TYPE> getFastIterable(MAP KEY_VALUE_GENERIC_TYPE map) {
#if MAPS_FEATURE
return MAPS.fastIterable(map);
#else
return map.ENTRY_SET();
#endif
}
protected ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> getFastIterator(MAP KEY_VALUE_GENERIC_TYPE map) {
#if MAPS_FEATURE
return MAPS.fastIterator(map);
#else
return map.ENTRY_SET().iterator();
#endif
}
@Override @Override
public MAP KEY_VALUE_GENERIC_TYPE copy() { public MAP KEY_VALUE_GENERIC_TYPE copy() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@@ -63,14 +87,14 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
#if VALUE_PRIMITIVES #if VALUE_PRIMITIVES
@Override @Override
public void addToAll(MAP KEY_VALUE_GENERIC_TYPE m) { public void addToAll(MAP KEY_VALUE_GENERIC_TYPE m) {
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m))
addTo(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); addTo(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
} }
#endif #endif
@Override @Override
public void putAll(MAP KEY_VALUE_GENERIC_TYPE m) { public void putAll(MAP KEY_VALUE_GENERIC_TYPE m) {
for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(m);iter.hasNext();) { for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = getFastIterator(m);iter.hasNext();) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next(); MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next();
put(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); put(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
} }
@@ -101,7 +125,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
#endif #endif
@Override @Override
public void putAllIfAbsent(MAP KEY_VALUE_GENERIC_TYPE m) { public void putAllIfAbsent(MAP KEY_VALUE_GENERIC_TYPE m) {
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m))
putIfAbsent(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); putIfAbsent(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
} }
@@ -161,14 +185,14 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
@Override @Override
public void REPLACE_VALUES(MAP KEY_VALUE_GENERIC_TYPE m) { public void REPLACE_VALUES(MAP KEY_VALUE_GENERIC_TYPE m) {
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m))
replace(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); replace(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
} }
@Override @Override
public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(this);iter.hasNext();) { for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = getFastIterator(this);iter.hasNext();) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next(); MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next();
entry.setValue(mappingFunction.APPLY_VALUE(entry.ENTRY_KEY(), entry.ENTRY_VALUE())); entry.setValue(mappingFunction.APPLY_VALUE(entry.ENTRY_KEY(), entry.ENTRY_VALUE()));
} }
@@ -177,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())) {
@@ -191,11 +305,11 @@ 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)) {
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key); VALUE_TYPE newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) {
put(key, newValue); put(key, newValue);
return newValue; return newValue;
@@ -205,11 +319,11 @@ 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)) {
VALUE_TYPE newValue = valueProvider.VALUE_GET_KEY(); VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) {
put(key, newValue); put(key, newValue);
return newValue; return newValue;
@@ -219,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)) {
@@ -233,6 +347,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
return getDefaultReturnValue(); return getDefaultReturnValue();
} }
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -246,7 +361,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
@Override @Override
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) { for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m)) {
KEY_TYPE key = entry.ENTRY_KEY(); KEY_TYPE key = entry.ENTRY_KEY();
VALUE_TYPE oldValue = GET_VALUE(key); VALUE_TYPE oldValue = GET_VALUE(key);
VALUE_TYPE newValue = VALUE_EQUALS(oldValue, getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(oldValue, entry.ENTRY_VALUE()); VALUE_TYPE newValue = VALUE_EQUALS(oldValue, getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(oldValue, entry.ENTRY_VALUE());
@@ -285,10 +400,20 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
} }
#endif #endif
@Override
public CLASS_VALUE_TYPE remove(Object key) {
#if TYPE_OBJECT
return VALUE_TO_OBJ(REMOVE_VALUE((CLASS_TYPE)key));
#else
return key instanceof CLASS_TYPE ? VALUE_TO_OBJ(REMOVE_VALUE(CLASS_TO_KEY(key))) : VALUE_TO_OBJ(getDefaultReturnValue());
#endif
}
@Override @Override
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) { public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(this);iter.hasNext();) { for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = getFastIterator(this);iter.hasNext();) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next(); MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next();
action.accept(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); action.accept(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
} }
@@ -306,7 +431,11 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
#else #else
@Override @Override
public boolean remove(Object o) { public boolean remove(Object o) {
return VALUE_EQUALS_NOT(ABSTRACT_MAP.this.remove(o), getDefaultReturnValue()); if(ABSTRACT_MAP.this.containsKey(o)) {
ABSTRACT_MAP.this.remove(o);
return true;
}
return false;
} }
#endif #endif
@@ -318,7 +447,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
@Override @Override
public ITERATOR KEY_GENERIC_TYPE iterator() { public ITERATOR KEY_GENERIC_TYPE iterator() {
return new ITERATOR KEY_GENERIC_TYPE() { return new ITERATOR KEY_GENERIC_TYPE() {
ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(ABSTRACT_MAP.this); ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = getFastIterator(ABSTRACT_MAP.this);
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return iter.hasNext(); return iter.hasNext();
@@ -369,7 +498,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
@Override @Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new VALUE_ITERATOR VALUE_GENERIC_TYPE() { return new VALUE_ITERATOR VALUE_GENERIC_TYPE() {
ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(ABSTRACT_MAP.this); ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = getFastIterator(ABSTRACT_MAP.this);
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return iter.hasNext(); return iter.hasNext();
@@ -409,7 +538,7 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
@Override @Override
public int hashCode() { public int hashCode() {
int hash = 0; int hash = 0;
ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(this); ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = getFastIterator(this);
while(iter.hasNext()) hash += iter.next().hashCode(); while(iter.hasNext()) hash += iter.next().hashCode();
return hash; return hash;
} }
@@ -6,8 +6,14 @@ import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.locks.StampedLock; import java.util.concurrent.locks.StampedLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
@@ -17,13 +23,24 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#endif #endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif #endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN #if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
@@ -43,6 +60,7 @@ import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPER
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator; import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator;
#endif #endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_BI_ITERATOR; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_BI_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER; import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER;
@@ -54,18 +72,14 @@ import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOpera
#if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT
import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer; import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer;
#endif #endif
#if !TYPE_OBJECT || !VALUE_BOOLEAN
#if !VALUE_OBJECT || SAME_TYPE
import speiger.src.collections.objects.functions.function.Object2BooleanFunction;
#endif
#endif
#if !SAME_TYPE #if !SAME_TYPE
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
#endif #endif
#endif
#if VALUE_OBJECT #if VALUE_OBJECT
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
#endif #endif
@@ -73,6 +87,7 @@ import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet; import speiger.src.collections.objects.sets.ObjectSet;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable;
/** /**
* A TypeSpecific ConcurrentHashMap implementation that is based on <a href="https://github.com/google/guava">Guavas</a> approach and backing array implementations. * A TypeSpecific ConcurrentHashMap implementation that is based on <a href="https://github.com/google/guava">Guavas</a> approach and backing array implementations.
@@ -84,7 +99,7 @@ import speiger.src.collections.utils.HashUtil;
* @Type(T) * @Type(T)
* @ValueType(V) * @ValueType(V)
*/ */
public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE, ITrimmable
{ {
/** Segment Limit */ /** Segment Limit */
private static final int MAX_SEGMENTS = 1 << 16; private static final int MAX_SEGMENTS = 1 << 16;
@@ -524,6 +539,36 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
return getSegment(hash).computeIfPresent(hash, key, mappingFunction); return getSegment(hash).computeIfPresent(hash, key, mappingFunction);
} }
#if !VALUE_OBJECT
@Override
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int hash = getHashCode(key);
return getSegment(hash).computeNonDefault(hash, key, mappingFunction);
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int hash = getHashCode(key);
return getSegment(hash).computeIfAbsentNonDefault(hash, key, mappingFunction);
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
int hash = getHashCode(key);
return getSegment(hash).supplyIfAbsentNonDefault(hash, key, valueProvider);
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int hash = getHashCode(key);
return getSegment(hash).computeIfPresentNonDefault(hash, key, mappingFunction);
}
#endif
@Override @Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
@@ -538,6 +583,30 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
@Override
public boolean trim(int size) {
int segmentCapacity = size / segments.length;
if(segmentCapacity * segments.length < size) {
segmentCapacity++;
}
boolean result = false;
for(int i = 0, m=segments.length;i<m;i++) {
result |= segments[i].trim(segmentCapacity);
}
return result;
}
@Override
public void clearAndTrim(int size) {
int segmentCapacity = size / segments.length;
if(segmentCapacity * segments.length < size) {
segmentCapacity++;
}
for(int i = 0, m=segments.length;i<m;i++) {
segments[i].clearAndTrim(segmentCapacity);
}
}
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
for(int i = 0,m=segments.length;i<m;i++) { for(int i = 0,m=segments.length;i<m;i++) {
@@ -613,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];
} }
} }
@@ -625,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];
} }
@@ -643,6 +712,26 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
@Override
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action);
int count = 0;
for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock();
try {
int index = seg.firstIndex;
while(index != -1) {
action.accept(count++, new ValueMapEntry(index, i));
index = (int)seg.links[index];
}
}
finally {
seg.unlockRead(stamp);
}
}
}
@Override @Override
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);
@@ -652,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];
} }
} }
@@ -663,17 +752,17 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
@Override @Override
public boolean matchesAny(Object2BooleanFunction<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.getBoolean(entry)) return true; if(filter.test(entry)) return true;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -685,17 +774,17 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
@Override @Override
public boolean matchesNone(Object2BooleanFunction<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.getBoolean(entry)) return false; if(filter.test(entry)) return false;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -707,17 +796,17 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
@Override @Override
public boolean matchesAll(Object2BooleanFunction<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.getBoolean(entry)) return false; if(!filter.test(entry)) return false;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -738,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];
} }
} }
@@ -762,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];
} }
} }
@@ -778,17 +867,17 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Object2BooleanFunction<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.getBoolean(entry)) return entry; if(filter.test(entry)) return entry;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -800,18 +889,18 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
@Override @Override
public int count(Object2BooleanFunction<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.getBoolean(entry)) result++; if(filter.test(entry)) result++;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -952,6 +1041,26 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int count = 0;
for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock();
try {
int index = seg.firstIndex;
while(index != -1){
action.accept(count++, seg.keys[index]);
index = (int)seg.links[index];
}
}
finally {
seg.unlockRead(stamp);
}
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -980,7 +1089,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(seg.keys[index])) return true; if(filter.test(seg.keys[index])) return true;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1000,7 +1109,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(seg.keys[index])) return false; if(filter.test(seg.keys[index])) return false;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1020,7 +1129,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
if(!filter.TEST_VALUE(seg.keys[index])) return false; if(!filter.test(seg.keys[index])) return false;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1113,7 +1222,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(seg.keys[index])) return seg.keys[index]; if(filter.test(seg.keys[index])) return seg.keys[index];
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1134,7 +1243,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(seg.keys[index])) result++; if(filter.test(seg.keys[index])) result++;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1200,6 +1309,26 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
} }
} }
@Override
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int count = 0;
for(int i = 0,m=segments.length;i<m;i++) {
Segment KEY_VALUE_GENERIC_TYPE seg = segments[i];
long stamp = seg.readLock();
try {
int index = seg.firstIndex;
while(index != -1){
action.accept(count++, seg.values[index]);
index = (int)seg.links[index];
}
}
finally {
seg.unlockRead(stamp);
}
}
}
@Override @Override
public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) { public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1228,7 +1357,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(seg.values[index])) return true; if(filter.test(seg.values[index])) return true;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1248,7 +1377,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
if(filter.VALUE_TEST_VALUE(seg.values[index])) return false; if(filter.test(seg.values[index])) return false;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1268,7 +1397,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1) { while(index != -1) {
if(!filter.VALUE_TEST_VALUE(seg.values[index])) return false; if(!filter.test(seg.values[index])) return false;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1362,7 +1491,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(seg.values[index])) return seg.values[index]; if(filter.test(seg.values[index])) return seg.values[index];
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1383,7 +1512,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
try { try {
int index = seg.firstIndex; int index = seg.firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(seg.values[index])) result++; if(filter.test(seg.values[index])) result++;
index = (int)seg.links[index]; index = (int)seg.links[index];
} }
} }
@@ -1420,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
@@ -1610,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;
@@ -1645,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;
} }
@@ -1787,6 +1943,11 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
insert(-slot-1, key, value); insert(-slot-1, key, value);
return getDefaultReturnValue(); return getDefaultReturnValue();
} }
else if(VALUE_EQUALS(values[slot], getDefaultReturnValue())) {
VALUE_TYPE oldValue = values[slot];
values[slot] = value;
return oldValue;
}
return values[slot]; return values[slot];
} }
finally { finally {
@@ -2025,7 +2186,11 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
long stamp = writeLock(); long stamp = writeLock();
try try
{ {
#if TYPE_OBJECT
if(key == null) { if(key == null) {
#else
if(key == null || (key instanceof CLASS_TYPE && KEY_EQUALS_NULL(CLASS_TO_KEY(key)))) {
#endif
if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) { if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) {
removeNullIndex(); removeNullIndex();
return true; return true;
@@ -2085,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;
@@ -2102,19 +2371,20 @@ 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);
if(index < 0) { if(index < 0) {
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key); VALUE_TYPE newValue = mappingFunction.APPLY(key);
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;
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key); newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -2125,19 +2395,19 @@ 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);
if(index < 0) { if(index < 0) {
VALUE_TYPE newValue = valueProvider.VALUE_GET_KEY(); VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
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;
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY(); newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -2148,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);
@@ -2166,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 {
@@ -2202,7 +2473,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
protected boolean trim(int size) { protected boolean trim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false; if(request >= mask+1 || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
long stamp = writeLock(); long stamp = writeLock();
try { try {
try { try {
@@ -2218,7 +2489,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
protected void clearAndTrim(int size) { protected void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= mask+1) {
clear(); clear();
return; return;
} }
@@ -2298,6 +2569,9 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
#endif #endif
protected int findIndex(int hash, Object key) { protected int findIndex(int hash, Object key) {
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1); if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
#if !TYPE_OBJECT
if(KEY_EQUALS_NULL(CLASS_TO_KEY(key))) return containsNull ? nullIndex : -(nullIndex + 1);
#endif
int pos = hash & mask; int pos = hash & mask;
KEY_TYPE current = keys[pos]; KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NOT_NULL(current)) { if(KEY_EQUALS_NOT_NULL(current)) {
@@ -3,26 +3,41 @@ package speiger.src.collections.PACKAGE.maps.impl.customHash;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.Objects; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !TYPE_OBJECT || VALUE_BOOLEAN import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET; import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.utils.STRATEGY; import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
@@ -37,18 +52,15 @@ import speiger.src.collections.VALUE_PACKAGE.lists.VALUE_LIST_ITERATOR;
#if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT
import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer; import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer;
#endif #endif
#if !TYPE_OBJECT || !VALUE_BOOLEAN
#if !VALUE_OBJECT || SAME_TYPE
import speiger.src.collections.objects.functions.function.Object2BooleanFunction;
#endif
#endif
#if !SAME_TYPE #if !SAME_TYPE
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
#endif #endif
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
#if !VALUE_OBJECT #if !VALUE_OBJECT
import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator; import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator;
@@ -57,7 +69,7 @@ import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOpera
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator; import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
import speiger.src.collections.objects.lists.ObjectListIterator; import speiger.src.collections.objects.lists.ObjectListIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet; import speiger.src.collections.objects.sets.ObjectOrderedSet;
#endif #endif
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
@@ -285,7 +297,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public boolean moveToFirst(KEY_TYPE key) { public boolean moveToFirst(KEY_TYPE key) {
if(strategy.equals(FIRST_ENTRY_KEY(), key)) return false; if(isEmpty() || strategy.equals(FIRST_ENTRY_KEY(), key)) return false;
if(strategy.equals(key, EMPTY_KEY_VALUE)) { if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex);
@@ -307,7 +319,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public boolean moveToLast(KEY_TYPE key) { public boolean moveToLast(KEY_TYPE key) {
if(strategy.equals(LAST_ENTRY_KEY(), key)) return false; if(isEmpty() || strategy.equals(LAST_ENTRY_KEY(), key)) return false;
if(strategy.equals(key, EMPTY_KEY_VALUE)) { if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex);
@@ -370,8 +382,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public KEY_TYPE POLL_FIRST_ENTRY_KEY() { public KEY_TYPE POLL_FIRST_ENTRY_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = firstIndex; int pos = firstIndex;
firstIndex = (int)links[pos]; onNodeRemoved(pos);
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
KEY_TYPE result = keys[pos]; KEY_TYPE result = keys[pos];
size--; size--;
if(strategy.equals(result, EMPTY_KEY_VALUE)) { if(strategy.equals(result, EMPTY_KEY_VALUE)) {
@@ -394,8 +405,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
public KEY_TYPE POLL_LAST_ENTRY_KEY() { public KEY_TYPE POLL_LAST_ENTRY_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = lastIndex; int pos = lastIndex;
lastIndex = (int)(links[pos] >>> 32); onNodeRemoved(pos);
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
KEY_TYPE result = keys[pos]; KEY_TYPE result = keys[pos];
size--; size--;
if(strategy.equals(result, EMPTY_KEY_VALUE)) { if(strategy.equals(result, EMPTY_KEY_VALUE)) {
@@ -421,15 +431,15 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
} }
@Override @Override
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet(); if(entrySet == null) entrySet = new MapEntrySet();
return entrySet; return (ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE>)entrySet;
} }
@Override @Override
public SET KEY_GENERIC_TYPE keySet() { public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keySet == null) keySet = new KeySet(); if(keySet == null) keySet = new KeySet();
return keySet; return (ORDERED_SET KEY_GENERIC_TYPE)keySet;
} }
@Override @Override
@@ -456,7 +466,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
@Override @Override
public void clearAndTrim(int size) { public void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= nullIndex) {
clear(); clear();
return; return;
} }
@@ -670,70 +680,82 @@ 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];
} }
} }
@Override
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1) {
action.accept(count++, new ValueMapEntry(index));
index = (int)links[index];
}
}
@Override @Override
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;
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];
} }
} }
@Override @Override
public boolean matchesAny(Object2BooleanFunction<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.getBoolean(entry)) return true; if(filter.test(entry)) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
} }
@Override @Override
public boolean matchesNone(Object2BooleanFunction<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.getBoolean(entry)) return false; if(filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
} }
@Override @Override
public boolean matchesAll(Object2BooleanFunction<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.getBoolean(entry)) return false; if(!filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -745,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;
@@ -760,40 +782,40 @@ 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;
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Object2BooleanFunction<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.getBoolean(entry)) return entry; if(filter.test(entry)) return entry;
index = (int)links[index]; index = (int)links[index];
} }
return null; return null;
} }
@Override @Override
public int count(Object2BooleanFunction<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.getBoolean(entry)) result++; if(filter.test(entry)) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -947,6 +969,18 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1){
action.accept(count++, keys[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -964,7 +998,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return false; if(size() <= 0) return false;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return true; if(filter.test(keys[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -976,7 +1010,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return false; if(filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -988,7 +1022,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(!filter.TEST_VALUE(keys[index])) return false; if(!filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -1046,7 +1080,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return EMPTY_KEY_VALUE;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return keys[index]; if(filter.test(keys[index])) return keys[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_KEY_VALUE; return EMPTY_KEY_VALUE;
@@ -1059,7 +1093,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) result++; if(filter.test(keys[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -1110,6 +1144,18 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
} }
} }
@Override
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1){
action.accept(count++, values[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) { public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1127,7 +1173,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return false; if(size() <= 0) return false;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) return true; if(filter.test(values[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -1139,7 +1185,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) return false; if(filter.test(values[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -1151,7 +1197,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(!filter.VALUE_TEST_VALUE(values[index])) return false; if(!filter.test(values[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -1209,7 +1255,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return EMPTY_VALUE;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) return values[index]; if(filter.test(values[index])) return values[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
@@ -1222,7 +1268,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) result++; if(filter.test(values[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -1266,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
@@ -7,26 +7,41 @@ import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#endif #endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif #endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN #if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SET;
@@ -42,6 +57,7 @@ import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPER
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator; import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator;
#endif #endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER; import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER;
#endif #endif
@@ -52,18 +68,15 @@ import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOpera
#if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT
import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer; import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer;
#endif #endif
#if !TYPE_OBJECT || !VALUE_BOOLEAN
#if !VALUE_OBJECT || SAME_TYPE
import speiger.src.collections.objects.functions.function.Object2BooleanFunction;
#endif
#endif
#if !SAME_TYPE #if !SAME_TYPE
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
#endif #endif
#endif
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet; import speiger.src.collections.objects.sets.ObjectSet;
@@ -270,6 +283,11 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
insert(-slot-1, key, value); insert(-slot-1, key, value);
return getDefaultReturnValue(); return getDefaultReturnValue();
} }
else if(VALUE_EQUALS(values[slot], getDefaultReturnValue())) {
VALUE_TYPE oldValue = values[slot];
values[slot] = value;
return oldValue;
}
return values[slot]; return values[slot];
} }
@@ -394,7 +412,11 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
@Override @Override
public boolean remove(Object key, Object value) { public boolean remove(Object key, Object value) {
Objects.requireNonNull(value); Objects.requireNonNull(value);
#if TYPE_OBJECT
if(key == null) { if(key == null) {
#else
if(key == null || (key instanceof CLASS_TYPE && strategy.equals(CLASS_TO_KEY(key), EMPTY_KEY_VALUE))) {
#endif
if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) { if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) {
removeNullIndex(); removeNullIndex();
return true; return true;
@@ -515,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;
@@ -529,18 +640,18 @@ 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) {
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key); VALUE_TYPE newValue = mappingFunction.APPLY(key);
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;
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key); newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -548,18 +659,18 @@ 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) {
VALUE_TYPE newValue = valueProvider.VALUE_GET_KEY(); VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
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;
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY(); newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -567,7 +678,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
} }
@Override @Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
int index = findIndex(key); int index = findIndex(key);
if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue(); if(index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
@@ -580,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);
@@ -600,7 +712,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
@Override @Override
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) { for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m)) {
KEY_TYPE key = entry.ENTRY_KEY(); KEY_TYPE key = entry.ENTRY_KEY();
int index = findIndex(key); int index = findIndex(key);
VALUE_TYPE newValue = index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE()); VALUE_TYPE newValue = index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
@@ -628,7 +740,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
@Override @Override
public boolean trim(int size) { public boolean trim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false; if(request >= nullIndex || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
try { try {
rehash(request); rehash(request);
} }
@@ -639,7 +751,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
@Override @Override
public void clearAndTrim(int size) { public void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= nullIndex) {
clear(); clear();
return; return;
} }
@@ -669,6 +781,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
protected int findIndex(CLASS_TYPE key) { protected int findIndex(CLASS_TYPE key) {
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1); if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
KEY_TYPE keyType = CLASS_TO_KEY(key); KEY_TYPE keyType = CLASS_TO_KEY(key);
#if !TYPE_OBJECT
if(strategy.equals(keyType, EMPTY_KEY_VALUE)) return containsNull ? nullIndex : -(nullIndex + 1);
#endif
int pos = HashUtil.mix(strategy.hashCode(keyType)) & mask; int pos = HashUtil.mix(strategy.hashCode(keyType)) & mask;
KEY_TYPE current = keys[pos]; KEY_TYPE current = keys[pos];
if(!strategy.equals(current, EMPTY_KEY_VALUE)) { if(!strategy.equals(current, EMPTY_KEY_VALUE)) {
@@ -765,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;
@@ -773,6 +915,10 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -795,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;
@@ -815,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());
} }
} }
@@ -837,85 +983,95 @@ 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);
} }
} }
} }
@Override
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
if(containsNull) action.accept(0, new ValueMapEntry(nullIndex));
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(index++, new ValueMapEntry(i));
}
}
@Override @Override
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));
} }
} }
@Override @Override
public boolean matchesAny(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) return true; if(filter.test(entry)) return true;
} }
} }
return false; return false;
} }
@Override @Override
public boolean matchesNone(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) return false; if(filter.test(entry)) return false;
} }
} }
return true; return true;
} }
@Override @Override
public boolean matchesAll(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) return false; if(!filter.test(entry)) return false;
} }
} }
return true; return true;
@@ -925,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;
} }
@@ -939,53 +1095,53 @@ 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 = 0;i<size;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;
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) return entry; if(filter.test(entry)) return entry;
} }
} }
return null; return null;
} }
@Override @Override
public int count(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) result++; if(filter.test(entry)) result++;
} }
} }
return result; return result;
@@ -1094,6 +1250,16 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(keys[i]); if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(keys[i]);
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
if(containsNull) action.accept(0, keys[nullIndex]);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(index++, keys[i]);
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1108,9 +1274,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return true; if(containsNull && filter.test(keys[nullIndex])) 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) && filter.TEST_VALUE(keys[i])) return true; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return true;
} }
return false; return false;
} }
@@ -1119,9 +1285,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return false; if(containsNull && filter.test(keys[nullIndex])) 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) && filter.TEST_VALUE(keys[i])) return false; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -1130,9 +1296,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && !filter.TEST_VALUE(keys[nullIndex])) return false; if(containsNull && !filter.test(keys[nullIndex])) 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) && !filter.TEST_VALUE(keys[i])) return false; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && !filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -1173,7 +1339,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
state = keys[nullIndex]; state = keys[nullIndex];
empty = false; empty = false;
} }
for(int i = 0;i<size;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;
@@ -1189,9 +1355,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return EMPTY_KEY_VALUE;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return keys[nullIndex]; if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex];
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.TEST_VALUE(keys[i])) return keys[i]; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return keys[i];
} }
return EMPTY_KEY_VALUE; return EMPTY_KEY_VALUE;
} }
@@ -1201,9 +1367,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
int result = 0; int result = 0;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) result++; if(containsNull && filter.test(keys[nullIndex])) 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) && filter.TEST_VALUE(keys[i])) result++; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) result++;
} }
return result; return result;
} }
@@ -1250,6 +1416,16 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(values[i]); if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(values[i]);
} }
@Override
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
if(containsNull) action.accept(0, values[nullIndex]);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(index++, values[i]);
}
}
@Override @Override
public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) { public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1264,9 +1440,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesAny(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesAny(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
if(containsNull && filter.VALUE_TEST_VALUE(values[nullIndex])) return true; if(containsNull && filter.test(values[nullIndex])) 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) && filter.VALUE_TEST_VALUE(values[i])) return true; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(values[i])) return true;
} }
return false; return false;
} }
@@ -1275,9 +1451,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesNone(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesNone(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && filter.VALUE_TEST_VALUE(values[nullIndex])) return false; if(containsNull && filter.test(values[nullIndex])) 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) && filter.VALUE_TEST_VALUE(values[i])) return false; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(values[i])) return false;
} }
return true; return true;
} }
@@ -1286,9 +1462,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public boolean matchesAll(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesAll(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && !filter.VALUE_TEST_VALUE(values[nullIndex])) return false; if(containsNull && !filter.test(values[nullIndex])) 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) && !filter.VALUE_TEST_VALUE(values[i])) return false; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && !filter.test(values[i])) return false;
} }
return true; return true;
} }
@@ -1329,7 +1505,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
state = values[nullIndex]; state = values[nullIndex];
empty = false; empty = false;
} }
for(int i = 0;i<size;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;
@@ -1345,9 +1521,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return EMPTY_VALUE;
if(containsNull && filter.VALUE_TEST_VALUE(values[nullIndex])) return values[nullIndex]; if(containsNull && filter.test(values[nullIndex])) return values[nullIndex];
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.VALUE_TEST_VALUE(values[i])) return values[i]; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(values[i])) return values[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -1357,9 +1533,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
int result = 0; int result = 0;
if(containsNull && filter.VALUE_TEST_VALUE(values[nullIndex])) result++; if(containsNull && filter.test(values[nullIndex])) 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) && filter.VALUE_TEST_VALUE(values[i])) result++; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(values[i])) result++;
} }
return result; return result;
} }
@@ -1378,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
@@ -1408,7 +1584,8 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
int lastReturned = -1; int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE; int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull; boolean returnNull = containsNull;
LIST KEY_GENERIC_TYPE wrapped = null; KEY_TYPE[] wrapped = null;
int wrappedIndex = 0;
public boolean hasNext() { public boolean hasNext() {
if(nextIndex == Integer.MIN_VALUE) { if(nextIndex == Integer.MIN_VALUE) {
@@ -1420,7 +1597,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
{ {
while(true) { while(true) {
if(--pos < 0) { if(--pos < 0) {
if(wrapped == null || wrapped.size() <= -pos - 1) break; if(wrapped == null || wrappedIndex <= -pos - 1) break;
nextIndex = -pos - 1; nextIndex = -pos - 1;
break; break;
} }
@@ -1439,7 +1616,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
returnedPos = pos; returnedPos = pos;
if(nextIndex < 0){ if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE; lastReturned = Integer.MAX_VALUE;
int value = findIndex(wrapped.GET_KEY(nextIndex)); int value = findIndex(wrapped[nextIndex]);
if(value < 0) throw new IllegalStateException("Entry ["+nextIndex+"] was removed during Iteration"); if(value < 0) throw new IllegalStateException("Entry ["+nextIndex+"] was removed during Iteration");
nextIndex = Integer.MIN_VALUE; nextIndex = Integer.MIN_VALUE;
return value; return value;
@@ -1458,7 +1635,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
} }
else if(returnedPos >= 0) shiftKeys(returnedPos); else if(returnedPos >= 0) shiftKeys(returnedPos);
else { else {
CUSTOM_HASH_MAP.this.remove(wrapped.GET_KEY(-returnedPos - 1)); CUSTOM_HASH_MAP.this.remove(wrapped[-returnedPos - 1]);
lastReturned = -1; lastReturned = -1;
return; return;
} }
@@ -1481,13 +1658,20 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break; if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask; startPos = ++startPos & mask;
} }
if(startPos < last) { if(startPos < last) addWrapper(keys[startPos]);
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
wrapped.add(keys[startPos]);
}
keys[last] = current; keys[last] = current;
values[last] = values[startPos]; values[last] = values[startPos];
} }
} }
private void addWrapper(KEY_TYPE value) {
if(wrapped == null) wrapped = NEW_KEY_ARRAY(2);
else if(wrappedIndex >= wrapped.length) {
KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2);
System.arraycopy(wrapped, 0, newArray, 0, wrapped.length);
wrapped = newArray;
}
wrapped[wrappedIndex++] = value;
}
} }
} }
@@ -3,26 +3,41 @@ package speiger.src.collections.PACKAGE.maps.impl.hash;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.Objects; import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !TYPE_OBJECT || VALUE_BOOLEAN import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_OBJECT && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET; import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
@@ -36,18 +51,15 @@ import speiger.src.collections.VALUE_PACKAGE.lists.VALUE_LIST_ITERATOR;
#if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT
import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer; import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer;
#endif #endif
#if !TYPE_OBJECT || !VALUE_BOOLEAN
#if !VALUE_OBJECT || SAME_TYPE
import speiger.src.collections.objects.functions.function.Object2BooleanFunction;
#endif
#endif
#if !SAME_TYPE #if !SAME_TYPE
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
#endif #endif
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
#if !VALUE_OBJECT #if !VALUE_OBJECT
import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator; import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator;
@@ -56,7 +68,7 @@ import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOpera
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator; import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
import speiger.src.collections.objects.lists.ObjectListIterator; import speiger.src.collections.objects.lists.ObjectListIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet; import speiger.src.collections.objects.sets.ObjectOrderedSet;
#endif #endif
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
@@ -262,7 +274,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public boolean moveToFirst(KEY_TYPE key) { public boolean moveToFirst(KEY_TYPE key) {
if(KEY_EQUALS(FIRST_ENTRY_KEY(), key)) return false; if(isEmpty() || KEY_EQUALS(FIRST_ENTRY_KEY(), key)) return false;
if(KEY_EQUALS_NULL(key)) { if(KEY_EQUALS_NULL(key)) {
if(containsNull) { if(containsNull) {
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex);
@@ -284,7 +296,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public boolean moveToLast(KEY_TYPE key) { public boolean moveToLast(KEY_TYPE key) {
if(KEY_EQUALS(LAST_ENTRY_KEY(), key)) return false; if(isEmpty() || KEY_EQUALS(LAST_ENTRY_KEY(), key)) return false;
if(KEY_EQUALS_NULL(key)) { if(KEY_EQUALS_NULL(key)) {
if(containsNull) { if(containsNull) {
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex);
@@ -374,8 +386,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public KEY_TYPE POLL_FIRST_ENTRY_KEY() { public KEY_TYPE POLL_FIRST_ENTRY_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = firstIndex; int pos = firstIndex;
firstIndex = (int)links[pos]; onNodeRemoved(pos);
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
KEY_TYPE result = keys[pos]; KEY_TYPE result = keys[pos];
size--; size--;
if(KEY_EQUALS_NULL(result)) { if(KEY_EQUALS_NULL(result)) {
@@ -398,8 +409,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
public KEY_TYPE POLL_LAST_ENTRY_KEY() { public KEY_TYPE POLL_LAST_ENTRY_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = lastIndex; int pos = lastIndex;
lastIndex = (int)(links[pos] >>> 32); onNodeRemoved(pos);
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
KEY_TYPE result = keys[pos]; KEY_TYPE result = keys[pos];
size--; size--;
if(KEY_EQUALS_NULL(result)) { if(KEY_EQUALS_NULL(result)) {
@@ -425,15 +435,15 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
} }
@Override @Override
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet(); if(entrySet == null) entrySet = new MapEntrySet();
return entrySet; return (ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE>)entrySet;
} }
@Override @Override
public SET KEY_GENERIC_TYPE keySet() { public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keySet == null) keySet = new KeySet(); if(keySet == null) keySet = new KeySet();
return keySet; return (ORDERED_SET KEY_GENERIC_TYPE)keySet;
} }
@Override @Override
@@ -460,7 +470,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
@Override @Override
public void clearAndTrim(int size) { public void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= nullIndex) {
clear(); clear();
return; return;
} }
@@ -674,70 +684,82 @@ 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];
} }
} }
@Override
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1) {
action.accept(count++, new ValueMapEntry(index));
index = (int)links[index];
}
}
@Override @Override
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;
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];
} }
} }
@Override @Override
public boolean matchesAny(Object2BooleanFunction<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.getBoolean(entry)) return true; if(filter.test(entry)) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
} }
@Override @Override
public boolean matchesNone(Object2BooleanFunction<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.getBoolean(entry)) return false; if(filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
} }
@Override @Override
public boolean matchesAll(Object2BooleanFunction<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.getBoolean(entry)) return false; if(!filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -749,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;
@@ -764,40 +786,40 @@ 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;
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Object2BooleanFunction<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.getBoolean(entry)) return entry; if(filter.test(entry)) return entry;
index = (int)links[index]; index = (int)links[index];
} }
return null; return null;
} }
@Override @Override
public int count(Object2BooleanFunction<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;
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.getBoolean(entry)) result++; if(filter.test(entry)) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -946,6 +968,18 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1){
action.accept(count++, keys[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -963,7 +997,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return false; if(size() <= 0) return false;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return true; if(filter.test(keys[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -975,7 +1009,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return false; if(filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -987,7 +1021,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(!filter.TEST_VALUE(keys[index])) return false; if(!filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -1045,7 +1079,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return EMPTY_KEY_VALUE;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return keys[index]; if(filter.test(keys[index])) return keys[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_KEY_VALUE; return EMPTY_KEY_VALUE;
@@ -1058,7 +1092,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) result++; if(filter.test(keys[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -1110,6 +1144,18 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
} }
} }
@Override
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1){
action.accept(count++, values[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) { public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1127,7 +1173,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return false; if(size() <= 0) return false;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) return true; if(filter.test(values[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -1139,7 +1185,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.VALUE_TEST_VALUE(values[index])) return false; if(filter.test(values[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -1151,7 +1197,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(!filter.VALUE_TEST_VALUE(values[index])) return false; if(!filter.test(values[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -1209,7 +1255,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return EMPTY_VALUE;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) return values[index]; if(filter.test(values[index])) return values[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
@@ -1222,7 +1268,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) result++; if(filter.test(values[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -1266,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
@@ -7,26 +7,41 @@ import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#endif #endif
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
#endif #endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN #if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SET;
@@ -51,18 +66,15 @@ import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOpera
#if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT
import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer; import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer;
#endif #endif
#if !TYPE_OBJECT || !VALUE_BOOLEAN
#if !VALUE_OBJECT || SAME_TYPE
import speiger.src.collections.objects.functions.function.Object2BooleanFunction;
#endif
#endif
#if !SAME_TYPE #if !SAME_TYPE
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
#endif #endif
#endif
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet; import speiger.src.collections.objects.sets.ObjectSet;
@@ -245,6 +257,11 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
insert(-slot-1, key, value); insert(-slot-1, key, value);
return getDefaultReturnValue(); return getDefaultReturnValue();
} }
else if(VALUE_EQUALS(values[slot], getDefaultReturnValue())) {
VALUE_TYPE oldValue = values[slot];
values[slot] = value;
return oldValue;
}
return values[slot]; return values[slot];
} }
@@ -362,7 +379,11 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
@Override @Override
public boolean remove(Object key, Object value) { public boolean remove(Object key, Object value) {
Objects.requireNonNull(value); Objects.requireNonNull(value);
#if TYPE_OBJECT
if(key == null) { if(key == null) {
#else
if(key == null || (key instanceof CLASS_TYPE && KEY_EQUALS_NULL(CLASS_TO_KEY(key)))) {
#endif
if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) { if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) {
removeNullIndex(); removeNullIndex();
return true; return true;
@@ -476,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;
@@ -490,18 +600,18 @@ 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) {
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key); VALUE_TYPE newValue = mappingFunction.APPLY(key);
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;
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key); newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -509,18 +619,18 @@ 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) {
VALUE_TYPE newValue = valueProvider.VALUE_GET_KEY(); VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
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;
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY(); newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -528,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();
@@ -541,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);
@@ -561,7 +672,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
@Override @Override
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) { for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m)) {
KEY_TYPE key = entry.ENTRY_KEY(); KEY_TYPE key = entry.ENTRY_KEY();
int index = findIndex(key); int index = findIndex(key);
VALUE_TYPE newValue = index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE()); VALUE_TYPE newValue = index < 0 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
@@ -589,7 +700,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
@Override @Override
public boolean trim(int size) { public boolean trim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false; if(request >= nullIndex || this.size >= Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
try { try {
rehash(request); rehash(request);
} }
@@ -600,7 +711,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
@Override @Override
public void clearAndTrim(int size) { public void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= nullIndex) {
clear(); clear();
return; return;
} }
@@ -629,6 +740,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
#endif #endif
protected int findIndex(Object key) { protected int findIndex(Object key) {
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1); if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
#if !TYPE_OBJECT
if(key instanceof CLASS_TYPE && KEY_EQUALS_NULL(CLASS_TO_KEY(key))) return containsNull ? nullIndex : -(nullIndex + 1);
#endif
int pos = HashUtil.mix(key.hashCode()) & mask; int pos = HashUtil.mix(key.hashCode()) & mask;
KEY_TYPE current = keys[pos]; KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NOT_NULL(current)) { if(KEY_EQUALS_NOT_NULL(current)) {
@@ -725,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;
@@ -733,6 +874,10 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -755,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;
@@ -775,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());
} }
} }
@@ -797,85 +942,95 @@ 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);
} }
} }
} }
@Override
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
if(containsNull) action.accept(0, new ValueMapEntry(nullIndex));
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(index++, new ValueMapEntry(i));
}
}
@Override @Override
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));
} }
} }
@Override @Override
public boolean matchesAny(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) return true; if(filter.test(entry)) return true;
} }
} }
return false; return false;
} }
@Override @Override
public boolean matchesNone(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) return false; if(filter.test(entry)) return false;
} }
} }
return true; return true;
} }
@Override @Override
public boolean matchesAll(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) return false; if(!filter.test(entry)) return false;
} }
} }
return true; return true;
@@ -885,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;
} }
@@ -899,53 +1054,53 @@ 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 = 0;i<size;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;
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) return entry; if(filter.test(entry)) return entry;
} }
} }
return null; return null;
} }
@Override @Override
public int count(Object2BooleanFunction<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.getBoolean(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.getBoolean(entry)) result++; if(filter.test(entry)) result++;
} }
} }
return result; return result;
@@ -1050,6 +1205,16 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(keys[i]); if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(keys[i]);
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
if(containsNull) action.accept(0, keys[nullIndex]);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(index++, keys[i]);
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1064,9 +1229,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return true; if(containsNull && filter.test(keys[nullIndex])) 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]) && filter.TEST_VALUE(keys[i])) return true; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return true;
} }
return false; return false;
} }
@@ -1075,9 +1240,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return false; if(containsNull && filter.test(keys[nullIndex])) 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]) && filter.TEST_VALUE(keys[i])) return false; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -1086,9 +1251,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && !filter.TEST_VALUE(keys[nullIndex])) return false; if(containsNull && !filter.test(keys[nullIndex])) 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]) && !filter.TEST_VALUE(keys[i])) return false; if(KEY_EQUALS_NOT_NULL(keys[i]) && !filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -1129,7 +1294,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
state = keys[nullIndex]; state = keys[nullIndex];
empty = false; empty = false;
} }
for(int i = 0;i<size;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;
@@ -1145,9 +1310,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return EMPTY_KEY_VALUE;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return keys[nullIndex]; if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex];
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.TEST_VALUE(keys[i])) return keys[i]; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return keys[i];
} }
return EMPTY_KEY_VALUE; return EMPTY_KEY_VALUE;
} }
@@ -1157,9 +1322,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
int result = 0; int result = 0;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) result++; if(containsNull && filter.test(keys[nullIndex])) result++;
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.TEST_VALUE(keys[i])) result++; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) result++;
} }
return result; return result;
} }
@@ -1206,6 +1371,16 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(values[i]); if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(values[i]);
} }
@Override
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
if(containsNull) action.accept(0, values[nullIndex]);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(index++, values[i]);
}
}
@Override @Override
public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) { public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1220,9 +1395,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesAny(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesAny(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
if(containsNull && filter.VALUE_TEST_VALUE(values[nullIndex])) return true; if(containsNull && filter.test(values[nullIndex])) 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]) && filter.VALUE_TEST_VALUE(values[i])) return true; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(values[i])) return true;
} }
return false; return false;
} }
@@ -1231,9 +1406,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesNone(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesNone(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && filter.VALUE_TEST_VALUE(values[nullIndex])) return false; if(containsNull && filter.test(values[nullIndex])) 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]) && filter.VALUE_TEST_VALUE(values[i])) return false; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(values[i])) return false;
} }
return true; return true;
} }
@@ -1242,9 +1417,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public boolean matchesAll(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesAll(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && !filter.VALUE_TEST_VALUE(values[nullIndex])) return false; if(containsNull && !filter.test(values[nullIndex])) 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]) && !filter.VALUE_TEST_VALUE(values[i])) return false; if(KEY_EQUALS_NOT_NULL(keys[i]) && !filter.test(values[i])) return false;
} }
return true; return true;
} }
@@ -1285,7 +1460,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
state = values[nullIndex]; state = values[nullIndex];
empty = false; empty = false;
} }
for(int i = 0;i<size;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;
@@ -1301,9 +1476,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return EMPTY_VALUE;
if(containsNull && filter.VALUE_TEST_VALUE(values[nullIndex])) return values[nullIndex]; if(containsNull && filter.test(values[nullIndex])) return values[nullIndex];
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.VALUE_TEST_VALUE(values[i])) return values[i]; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(values[i])) return values[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -1313,9 +1488,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
int result = 0; int result = 0;
if(containsNull && filter.VALUE_TEST_VALUE(values[nullIndex])) result++; if(containsNull && filter.test(values[nullIndex])) result++;
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.VALUE_TEST_VALUE(values[i])) result++; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(values[i])) result++;
} }
return result; return result;
} }
@@ -1334,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
@@ -1364,7 +1539,8 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
int lastReturned = -1; int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE; int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull; boolean returnNull = containsNull;
LIST KEY_GENERIC_TYPE wrapped = null; KEY_TYPE[] wrapped = null;
int wrappedIndex = 0;
public boolean hasNext() { public boolean hasNext() {
if(nextIndex == Integer.MIN_VALUE) { if(nextIndex == Integer.MIN_VALUE) {
@@ -1376,7 +1552,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
{ {
while(true) { while(true) {
if(--pos < 0) { if(--pos < 0) {
if(wrapped == null || wrapped.size() <= -pos - 1) break; if(wrapped == null || wrappedIndex <= -pos - 1) break;
nextIndex = -pos - 1; nextIndex = -pos - 1;
break; break;
} }
@@ -1395,7 +1571,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
returnedPos = pos; returnedPos = pos;
if(nextIndex < 0){ if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE; lastReturned = Integer.MAX_VALUE;
int value = findIndex(wrapped.GET_KEY(nextIndex)); int value = findIndex(wrapped[nextIndex]);
if(value < 0) throw new IllegalStateException("Entry ["+nextIndex+"] was removed during Iteration"); if(value < 0) throw new IllegalStateException("Entry ["+nextIndex+"] was removed during Iteration");
nextIndex = Integer.MIN_VALUE; nextIndex = Integer.MIN_VALUE;
return value; return value;
@@ -1414,7 +1590,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
} }
else if(returnedPos >= 0) shiftKeys(returnedPos); else if(returnedPos >= 0) shiftKeys(returnedPos);
else { else {
HASH_MAP.this.remove(wrapped.GET_KEY(-returnedPos - 1)); HASH_MAP.this.remove(wrapped[-returnedPos - 1]);
lastReturned = -1; lastReturned = -1;
return; return;
} }
@@ -1437,13 +1613,20 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break; if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask; startPos = ++startPos & mask;
} }
if(startPos < last) { if(startPos < last) addWrapper(keys[startPos]);
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
wrapped.add(keys[startPos]);
}
keys[last] = current; keys[last] = current;
values[last] = values[startPos]; values[last] = values[startPos];
} }
} }
private void addWrapper(KEY_TYPE value) {
if(wrapped == null) wrapped = NEW_KEY_ARRAY(2);
else if(wrappedIndex >= wrapped.length) {
KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2);
System.arraycopy(wrapped, 0, newArray, 0, wrapped.length);
wrapped = newArray;
}
wrapped[wrappedIndex++] = value;
}
} }
} }
@@ -6,17 +6,35 @@ import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
@@ -25,29 +43,26 @@ import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ORDERED_SET; import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.PACKAGE.utils.maps.MAPS; #endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif #endif
#if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT
import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer; import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer;
#endif #endif
#if !TYPE_OBJECT || !VALUE_BOOLEAN
#if !VALUE_OBJECT || SAME_TYPE
import speiger.src.collections.objects.functions.function.Object2BooleanFunction;
#endif
#endif
#if !SAME_TYPE #if !SAME_TYPE
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
#endif #endif
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET;
#endif #endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
@@ -70,7 +85,7 @@ import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOpera
import speiger.src.collections.objects.lists.ObjectListIterator; import speiger.src.collections.objects.lists.ObjectListIterator;
#endif #endif
import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet; import speiger.src.collections.objects.sets.ObjectOrderedSet;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@@ -100,9 +115,9 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
/** The Last Index in the Map */ /** The Last Index in the Map */
protected int lastIndex = -1; protected int lastIndex = -1;
/** EntrySet cache */ /** EntrySet cache */
protected transient FastEntrySet KEY_VALUE_GENERIC_TYPE entrySet; protected transient FastOrderedSet KEY_VALUE_GENERIC_TYPE entrySet;
/** KeySet cache */ /** KeySet cache */
protected transient SET KEY_GENERIC_TYPE keySet; protected transient ORDERED_SET KEY_GENERIC_TYPE keySet;
/** Values cache */ /** Values cache */
protected transient VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC; protected transient VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC;
@@ -214,7 +229,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
KEY_TYPE[] keys = NEW_KEY_ARRAY(map.size()); KEY_TYPE[] keys = NEW_KEY_ARRAY(map.size());
VALUE_TYPE[] values = NEW_VALUE_ARRAY(keys.length); VALUE_TYPE[] values = NEW_VALUE_ARRAY(keys.length);
int index = 0; int index = 0;
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(map)) { for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(map)) {
keys[index] = entry.ENTRY_KEY(); keys[index] = entry.ENTRY_KEY();
values[index] = entry.ENTRY_VALUE(); values[index] = entry.ENTRY_VALUE();
index++; index++;
@@ -429,13 +444,13 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
@Override @Override
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet(); if(entrySet == null) entrySet = new MapEntrySet();
return entrySet; return entrySet;
} }
@Override @Override
public SET KEY_GENERIC_TYPE keySet() { public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keySet == null) keySet = new KeySet(); if(keySet == null) keySet = new KeySet();
return keySet; return keySet;
} }
@@ -478,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(); }
@@ -516,6 +537,9 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
#endif #endif
protected int findIndex(Object key) { protected int findIndex(Object key) {
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1); if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
#if !TYPE_OBJECT
if(KEY_EQUALS_NULL(CLASS_TO_KEY(key))) return containsNull ? nullIndex : -(nullIndex + 1);
#endif
int pos = HashUtil.mix(key.hashCode()) & mask; int pos = HashUtil.mix(key.hashCode()) & mask;
KEY_TYPE current = keys[pos]; KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NOT_NULL(current)) { if(KEY_EQUALS_NOT_NULL(current)) {
@@ -655,6 +679,18 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
} }
@Override
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1) {
action.accept(count++, new BasicEntryKV_BRACES(keys[index], values[index]));
index = (int)links[index];
}
}
@Override @Override
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);
@@ -667,42 +703,42 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
@Override @Override
public boolean matchesAny(Object2BooleanFunction<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(); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(keys[index], values[index]);
if(filter.getBoolean(entry)) return true; if(filter.test(entry)) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
} }
@Override @Override
public boolean matchesNone(Object2BooleanFunction<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(); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(keys[index], values[index]);
if(filter.getBoolean(entry)) return false; if(filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
} }
@Override @Override
public boolean matchesAll(Object2BooleanFunction<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(); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(keys[index], values[index]);
if(!filter.getBoolean(entry)) return false; if(!filter.test(entry)) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -740,21 +776,21 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Object2BooleanFunction<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(); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(keys[index], values[index]);
if(filter.getBoolean(entry)) return entry; if(filter.test(entry)) return entry;
index = (int)links[index]; index = (int)links[index];
} }
return null; return null;
} }
@Override @Override
public int count(Object2BooleanFunction<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(); BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
@@ -762,7 +798,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
entry.set(keys[index], values[index]); entry.set(keys[index], values[index]);
if(filter.getBoolean(entry)) result++; if(filter.test(entry)) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -883,6 +919,18 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1){
action.accept(count++, keys[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -900,7 +948,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
if(size() <= 0) return false; if(size() <= 0) return false;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return true; if(filter.test(keys[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -912,7 +960,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return false; if(filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -924,7 +972,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(!filter.TEST_VALUE(keys[index])) return false; if(!filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -982,7 +1030,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
if(size() <= 0) return EMPTY_KEY_VALUE; if(size() <= 0) return EMPTY_KEY_VALUE;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) return keys[index]; if(filter.test(keys[index])) return keys[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_KEY_VALUE; return EMPTY_KEY_VALUE;
@@ -995,7 +1043,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
int index = firstIndex; int index = firstIndex;
int result = 0; int result = 0;
while(index != -1){ while(index != -1){
if(filter.TEST_VALUE(keys[index])) result++; if(filter.test(keys[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -1044,6 +1092,18 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
} }
} }
@Override
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
int count = 0;
int index = firstIndex;
while(index != -1){
action.accept(count++, values[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) { public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1061,7 +1121,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
if(size() <= 0) return false; if(size() <= 0) return false;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) return true; if(filter.test(values[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -1073,7 +1133,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) return false; if(filter.test(values[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -1085,7 +1145,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
if(size() <= 0) return true; if(size() <= 0) return true;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(!filter.VALUE_TEST_VALUE(values[index])) return false; if(!filter.test(values[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -1143,7 +1203,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return EMPTY_VALUE;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) return values[index]; if(filter.test(values[index])) return values[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
@@ -1156,7 +1216,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1){ while(index != -1){
if(filter.VALUE_TEST_VALUE(values[index])) result++; if(filter.test(values[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -6,17 +6,35 @@ import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Predicate;
#if !TYPE_OBJECT && JDK_TYPE
import java.util.function.PREDICATE;
#endif
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
import java.util.function.VALUE_PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
#if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
#endif
#if !SAME_TYPE && !TYPE_INT
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
#endif
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif #endif
#if !TYPE_INT || !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#endif
#if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
@@ -27,8 +45,6 @@ import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET; import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.utils.maps.MAPS;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
@@ -43,18 +59,15 @@ import speiger.src.collections.VALUE_PACKAGE.lists.VALUE_LIST_ITERATOR;
#if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT
import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer; import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer;
#endif #endif
#if !TYPE_OBJECT || !VALUE_BOOLEAN
#if !VALUE_OBJECT || SAME_TYPE
import speiger.src.collections.objects.functions.function.Object2BooleanFunction;
#endif
#endif
#if !SAME_TYPE #if !SAME_TYPE
#if VALUE_OBJECT #if VALUE_OBJECT
import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER;
#endif #endif
#if !JDK_VALUE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
#endif #endif
#endif
#if !VALUE_OBJECT #if !VALUE_OBJECT
import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.collections.ObjectIterator;
#endif #endif
@@ -90,7 +103,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
/** Amount of Elements stored in the ArrayMap */ /** Amount of Elements stored in the ArrayMap */
protected int size = 0; protected int size = 0;
/** KeySet cache */ /** KeySet cache */
protected SET KEY_GENERIC_TYPE keySet; protected ORDERED_SET KEY_GENERIC_TYPE keySet;
/** Values cache */ /** Values cache */
protected VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC; protected VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC;
/** EntrySet cache */ /** EntrySet cache */
@@ -177,7 +190,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
*/ */
public ARRAY_MAP(MAP KEY_VALUE_GENERIC_TYPE map) { public ARRAY_MAP(MAP KEY_VALUE_GENERIC_TYPE map) {
this(map.size()); this(map.size());
for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(map);iter.hasNext();size++) { for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = getFastIterator(map);iter.hasNext();size++) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next(); MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next();
keys[size] = entry.ENTRY_KEY(); keys[size] = entry.ENTRY_KEY();
values[size] = entry.ENTRY_VALUE(); values[size] = entry.ENTRY_VALUE();
@@ -203,6 +216,11 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
insertIndex(size++, key, value); insertIndex(size++, key, value);
return getDefaultReturnValue(); return getDefaultReturnValue();
} }
else if(VALUE_EQUALS(values[index], getDefaultReturnValue())) {
VALUE_TYPE oldValue = values[index];
values[index] = value;
return oldValue;
}
return values[index]; return values[index];
} }
@@ -270,7 +288,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public boolean moveToLast(KEY_TYPE key) { public boolean moveToLast(KEY_TYPE key) {
int index = findIndex(key); int index = findIndex(key);
if(index < size-1) { if(index >= 0 && index < size-1) {
moveIndexToLast(index); moveIndexToLast(index);
return true; return true;
} }
@@ -437,7 +455,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
@Override @Override
public SET KEY_GENERIC_TYPE keySet() { public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keySet == null) keySet = new KeySet(); if(keySet == null) keySet = new KeySet();
return keySet; return keySet;
} }
@@ -477,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;
@@ -491,18 +598,18 @@ 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) {
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key); VALUE_TYPE newValue = mappingFunction.APPLY(key);
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;
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key); newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -510,18 +617,18 @@ 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) {
VALUE_TYPE newValue = valueProvider.VALUE_GET_KEY(); VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
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;
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY(); newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -529,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();
@@ -542,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);
@@ -562,7 +670,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override @Override
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) { for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m)) {
KEY_TYPE key = entry.ENTRY_KEY(); KEY_TYPE key = entry.ENTRY_KEY();
int index = findIndex(key); int index = findIndex(key);
VALUE_TYPE newValue = index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE()); VALUE_TYPE newValue = index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
@@ -770,60 +878,68 @@ 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);
} }
} }
@Override
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;i++) {
action.accept(i, new ValueMapEntry(i));
}
}
@Override @Override
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));
} }
} }
@Override @Override
public boolean matchesAny(Object2BooleanFunction<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.getBoolean(entry)) return true; if(filter.test(entry)) return true;
} }
return false; return false;
} }
@Override @Override
public boolean matchesNone(Object2BooleanFunction<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.getBoolean(entry)) return false; if(filter.test(entry)) return false;
} }
return true; return true;
} }
@Override @Override
public boolean matchesAll(Object2BooleanFunction<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.getBoolean(entry)) return false; if(!filter.test(entry)) return false;
} }
return true; return true;
} }
@@ -833,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;
} }
@@ -846,35 +962,35 @@ 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;
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Object2BooleanFunction<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.getBoolean(entry)) return entry; if(filter.test(entry)) return entry;
} }
return null; return null;
} }
@Override @Override
public int count(Object2BooleanFunction<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;
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.getBoolean(entry)) result++; if(filter.test(entry)) result++;
} }
return result; return result;
} }
@@ -982,11 +1098,16 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
for(int i = 0;i<size;action.accept(keys[i++])); for(int i = 0;i<size;action.accept(keys[i++]));
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;action.accept(i, keys[i++]));
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
for(int i = 0;i<size;action.accept(input, keys[i++])); for(int i = 0;i<size;action.accept(input, keys[i++]));
} }
@Override @Override
@@ -994,7 +1115,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(keys[i])) return true; if(filter.test(keys[i])) return true;
} }
return false; return false;
} }
@@ -1003,7 +1124,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(keys[i])) return false; if(filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -1012,7 +1133,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(!filter.TEST_VALUE(keys[i])) return false; if(!filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -1060,7 +1181,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(keys[i])) return keys[i]; if(filter.test(keys[i])) return keys[i];
} }
return EMPTY_KEY_VALUE; return EMPTY_KEY_VALUE;
} }
@@ -1070,7 +1191,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(keys[i])) result++; if(filter.test(keys[i])) result++;
} }
return result; return result;
} }
@@ -1116,11 +1237,17 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
for(int i = 0;i<size;action.accept(values[i++])); for(int i = 0;i<size;action.accept(values[i++]));
} }
@Override
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;action.accept(i, values[i++]));
}
@Override @Override
public boolean matchesAny(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesAny(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.VALUE_TEST_VALUE(values[i])) return true; if(filter.test(values[i])) return true;
} }
return false; return false;
} }
@@ -1129,7 +1256,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public boolean matchesNone(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesNone(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.VALUE_TEST_VALUE(values[i])) return false; if(filter.test(values[i])) return false;
} }
return true; return true;
} }
@@ -1138,7 +1265,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public boolean matchesAll(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public boolean matchesAll(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(!filter.VALUE_TEST_VALUE(values[i])) return false; if(!filter.test(values[i])) return false;
} }
return true; return true;
} }
@@ -1186,7 +1313,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) { public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.VALUE_TEST_VALUE(values[i])) return values[i]; if(filter.test(values[i])) return values[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -1196,7 +1323,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.VALUE_TEST_VALUE(values[i])) result++; if(filter.test(values[i])) result++;
} }
return result; return result;
} }
@@ -1234,23 +1361,26 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public EntryIterator() {} public EntryIterator() {}
public EntryIterator(KEY_TYPE from) { public EntryIterator(KEY_TYPE from) {
index = findIndex(from); index = findIndex(from);
if(index == -1) throw new NoSuchElementException();
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry()); return entry = new ValueMapEntry(nextEntry());
} }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() { public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
return entry = new MapEntry(previousEntry()); return entry = new ValueMapEntry(previousEntry());
} }
@Override @Override
public void remove() { public void remove() {
super.remove(); super.remove();
if(entry != null && entry.index != -1) {
entry.index = -1; entry.index = -1;
} }
}
@Override @Override
public void set(MAP.Entry KEY_VALUE_GENERIC_TYPE e) { throw new UnsupportedOperationException(); } public void set(MAP.Entry KEY_VALUE_GENERIC_TYPE e) { throw new UnsupportedOperationException(); }
@@ -1262,7 +1392,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public KeyIterator() {} public KeyIterator() {}
public KeyIterator(KEY_TYPE element) { public KeyIterator(KEY_TYPE element) {
index = findIndex(element); index = findIndex(element);
if(index == -1) throw new NoSuchElementException();
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
return keys[previousEntry()]; return keys[previousEntry()];
@@ -1319,8 +1451,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
} }
public void remove() { public void remove() {
if(lastReturned == -1) if(lastReturned == -1) throw new IllegalStateException();
throw new IllegalStateException();
removeIndex(lastReturned); removeIndex(lastReturned);
if(lastReturned < index) if(lastReturned < index)
index--; index--;
@@ -1329,8 +1460,8 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public int previousEntry() { public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = index; index--;
return index--; return (lastReturned = index);
} }
public int nextEntry() { public int nextEntry() {
@@ -1341,8 +1472,9 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (size() - 1) - index); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps; return steps;
} }
@@ -1350,10 +1482,38 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
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);
return steps; return steps;
} }
} }
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;
@@ -1362,6 +1522,10 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -1384,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;
@@ -1404,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());
} }
} }
} }
@@ -4,6 +4,11 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer;
#if VALUE_BOOLEAN
import java.util.function.Predicate;
#endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
@@ -17,8 +22,9 @@ import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#if !VALUE_OBJECT #if !VALUE_OBJECT
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#endif #endif
#if !VALUE_BOOLEAN
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
import speiger.src.collections.PACKAGE.utils.maps.MAPS; #endif
import speiger.src.collections.objects.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.objects.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.objects.maps.interfaces.MAP; import speiger.src.collections.objects.maps.interfaces.MAP;
import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.AbstractObjectSet;
@@ -76,8 +82,8 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size"); if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size");
keyType = keys[0].getDeclaringClass(); keyType = keys[0].getDeclaringClass();
this.keys = getKeyUniverse(keyType); this.keys = getKeyUniverse(keyType);
this.values = NEW_VALUE_ARRAY(keys.length); this.values = NEW_VALUE_ARRAY(this.keys.length);
present = new long[((keys.length - 1) >> 6) + 1]; present = new long[((this.keys.length - 1) >> 6) + 1];
putAll(keys, values); putAll(keys, values);
} }
@@ -93,8 +99,8 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size"); if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size");
keyType = keys[0].getDeclaringClass(); keyType = keys[0].getDeclaringClass();
this.keys = getKeyUniverse(keyType); this.keys = getKeyUniverse(keyType);
this.values = NEW_VALUE_ARRAY(keys.length); this.values = NEW_VALUE_ARRAY(this.keys.length);
present = new long[((keys.length - 1) >> 6) + 1]; present = new long[((this.keys.length - 1) >> 6) + 1];
putAll(keys, values); putAll(keys, values);
} }
@@ -160,7 +166,14 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override @Override
public VALUE_TYPE putIfAbsent(T key, VALUE_TYPE value) { public VALUE_TYPE putIfAbsent(T key, VALUE_TYPE value) {
int index = key.ordinal(); int index = key.ordinal();
if(isSet(index)) return values[index]; if(isSet(index)) {
if(VALUE_EQUALS(values[index], getDefaultReturnValue())) {
VALUE_TYPE oldValue = values[index];
values[index] = value;
return oldValue;
}
return values[index];
}
set(index); set(index);
values[index] = value; values[index] = value;
return getDefaultReturnValue(); return getDefaultReturnValue();
@@ -350,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;
@@ -366,10 +469,10 @@ 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.GET_VALUE(key); VALUE_TYPE newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
set(index); set(index);
values[index] = newValue; values[index] = newValue;
@@ -377,7 +480,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key); newValue = mappingFunction.APPLY(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -385,10 +488,10 @@ 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_GET_KEY(); VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
set(index); set(index);
values[index] = newValue; values[index] = newValue;
@@ -396,7 +499,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
} }
VALUE_TYPE newValue = values[index]; VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) { if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY(); newValue = valueProvider.VALUE_SUPPLY_GET();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue; if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue; values[index] = newValue;
} }
@@ -404,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]);
@@ -417,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();
@@ -441,7 +545,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override @Override
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction); Objects.requireNonNull(mappingFunction);
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) { for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m)) {
T key = entry.ENTRY_KEY(); T key = entry.ENTRY_KEY();
int index = key.ordinal(); int index = key.ordinal();
VALUE_TYPE newValue = !isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE()); VALUE_TYPE newValue = !isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
@@ -530,6 +634,14 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
return false; return false;
} }
@Override
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
if(size() <= 0) return;
for(int i = 0,m=keys.length;i<m;i++) {
if(isSet(i)) action.accept(new ValueMapEntry(i));
}
}
@Override @Override
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator(); return new EntryIterator();
@@ -609,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());
} }
} }
@@ -656,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;
@@ -664,6 +803,10 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -686,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;
@@ -706,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());
} }
} }
} }
@@ -17,7 +17,6 @@ import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.ORDERED_SET; import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
@@ -29,7 +28,6 @@ import speiger.src.collections.VALUE_PACKAGE.lists.VALUE_LIST_ITERATOR;
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator; import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
import speiger.src.collections.objects.lists.ObjectListIterator; import speiger.src.collections.objects.lists.ObjectListIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet;
#endif #endif
/** /**
@@ -68,9 +66,9 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size"); if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size");
keyType = keys[0].getDeclaringClass(); keyType = keys[0].getDeclaringClass();
this.keys = getKeyUniverse(keyType); this.keys = getKeyUniverse(keyType);
this.values = NEW_VALUE_ARRAY(keys.length); this.values = NEW_VALUE_ARRAY(this.keys.length);
present = new long[((keys.length - 1) >> 6) + 1]; present = new long[((this.keys.length - 1) >> 6) + 1];
links = new long[keys.length]; links = new long[this.keys.length];
putAll(keys, values); putAll(keys, values);
} }
@@ -86,9 +84,9 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size"); if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size");
keyType = keys[0].getDeclaringClass(); keyType = keys[0].getDeclaringClass();
this.keys = getKeyUniverse(keyType); this.keys = getKeyUniverse(keyType);
this.values = NEW_VALUE_ARRAY(keys.length); this.values = NEW_VALUE_ARRAY(this.keys.length);
present = new long[((keys.length - 1) >> 6) + 1]; present = new long[((this.keys.length - 1) >> 6) + 1];
links = new long[keys.length]; links = new long[this.keys.length];
putAll(keys, values); putAll(keys, values);
} }
@@ -241,7 +239,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override @Override
public VALUE_TYPE getAndMoveToFirst(T key) { public VALUE_TYPE getAndMoveToFirst(T key) {
int index = key.ordinal(); int index = key.ordinal();
if(index < 0) return getDefaultReturnValue(); if(!isSet(index)) return getDefaultReturnValue();
moveToFirstIndex(index); moveToFirstIndex(index);
return values[index]; return values[index];
} }
@@ -249,7 +247,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override @Override
public VALUE_TYPE getAndMoveToLast(T key) { public VALUE_TYPE getAndMoveToLast(T key) {
int index = key.ordinal(); int index = key.ordinal();
if(index < 0) return getDefaultReturnValue(); if(!isSet(index)) return getDefaultReturnValue();
moveToLastIndex(index); moveToLastIndex(index);
return values[index]; return values[index];
} }
@@ -315,15 +313,15 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
} }
@Override @Override
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() { public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet(); if(entrySet == null) entrySet = new MapEntrySet();
return entrySet; return (ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE>)entrySet;
} }
@Override @Override
public SET KEY_GENERIC_TYPE keySet() { public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keySet == null) keySet = new KeySet(); if(keySet == null) keySet = new KeySet();
return keySet; return (ORDERED_SET KEY_GENERIC_TYPE)keySet;
} }
@Override @Override
@@ -482,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];
} }
@@ -751,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
@@ -830,6 +828,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
previous = from.ordinal() - 1; previous = from.ordinal() - 1;
index = from.ordinal(); index = from.ordinal();
next = from.ordinal(); next = from.ordinal();
if(!isSet(index)) throw new NoSuchElementException();
} }
public boolean hasNext() { public boolean hasNext() {
@@ -904,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;
@@ -912,6 +938,10 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
this.index = index; this.index = index;
} }
void set(int index) {
this.index = index;
}
@Override @Override
public KEY_TYPE ENTRY_KEY() { public KEY_TYPE ENTRY_KEY() {
return keys[index]; return keys[index];
@@ -934,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;
@@ -954,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());
} }
} }
} }
@@ -10,36 +10,72 @@ import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
#if VALUE_BOOLEAN && JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
#if TYPE_OBJECT #if TYPE_OBJECT
#if AVL_TREE_MAP_FEATURE || RB_TREE_MAP_FEATURE
import java.util.Comparator; import java.util.Comparator;
#endif #endif
#endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#if !VALUE_BOOLEAN || !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !TYPE_OBJECT && !TYPE_BOOLEAN #if !TYPE_OBJECT && !TYPE_BOOLEAN && SORTED_MAP_FEATURE
#if AVL_TREE_MAP_FEATURE || RB_TREE_MAP_FEATURE
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
#endif
#if !TYPE_BOOLEAN #if !TYPE_BOOLEAN
#if LINKED_CUSTOM_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.customHash.LINKED_CUSTOM_HASH_MAP; import speiger.src.collections.PACKAGE.maps.impl.customHash.LINKED_CUSTOM_HASH_MAP;
#endif
#if CUSTOM_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.customHash.CUSTOM_HASH_MAP; import speiger.src.collections.PACKAGE.maps.impl.customHash.CUSTOM_HASH_MAP;
#endif
#if LINKED_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.hash.LINKED_HASH_MAP; import speiger.src.collections.PACKAGE.maps.impl.hash.LINKED_HASH_MAP;
#endif
#if MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.hash.HASH_MAP; import speiger.src.collections.PACKAGE.maps.impl.hash.HASH_MAP;
#endif
#if IMMUTABLE_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.immutable.IMMUTABLE_HASH_MAP; import speiger.src.collections.PACKAGE.maps.impl.immutable.IMMUTABLE_HASH_MAP;
#endif
#if AVL_TREE_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.tree.AVL_TREE_MAP; import speiger.src.collections.PACKAGE.maps.impl.tree.AVL_TREE_MAP;
#endif
#if RB_TREE_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP; import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
#endif
#if ARRAY_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.misc.ARRAY_MAP; import speiger.src.collections.PACKAGE.maps.impl.misc.ARRAY_MAP;
#endif
#if CONCURRENT_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.concurrent.CONCURRENT_HASH_MAP; import speiger.src.collections.PACKAGE.maps.impl.concurrent.CONCURRENT_HASH_MAP;
#endif
#if TYPE_OBJECT #if TYPE_OBJECT
#if ENUM_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP; import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP;
#endif
#if LINKED_ENUM_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP; import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP;
#endif #endif
#endif
import speiger.src.collections.objects.collections.ObjectIterable; import speiger.src.collections.objects.collections.ObjectIterable;
#if CUSTOM_MAP_FEATURE || LINKED_CUSTOM_MAP_FEATURE
import speiger.src.collections.PACKAGE.utils.STRATEGY; import speiger.src.collections.PACKAGE.utils.STRATEGY;
#endif
#if MAPS_FEATURE
import speiger.src.collections.PACKAGE.utils.maps.MAPS; import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#endif #endif
#endif
import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SET;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
@@ -102,6 +138,26 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
*/ */
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value); public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value);
/**
* A Helper method that allows to put int a MAP.Entry into a map.
* @param entry then Entry that should be inserted.
* @return the last present value or default return value.
*/
public default VALUE_TYPE put(Entry KEY_VALUE_GENERIC_TYPE entry) {
return put(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
}
#if !TYPE_OBJECT || !VALUE_OBJECT
/**
* A Helper method that allows to put int a Map.Entry into a map.
* @param entry then Entry that should be inserted.
* @return the last present value or default return value.
*/
public default CLASS_VALUE_TYPE put(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) {
return put(entry.getKey(), entry.getValue());
}
#endif
/** /**
* Type Specific array method to bulk add elements into a map without creating a wrapper and increasing performances * Type Specific array method to bulk add elements into a map without creating a wrapper and increasing performances
* @param keys the keys that should be added * @param keys the keys that should be added
@@ -326,21 +382,26 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction); public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
/** /**
* A Type Specific compute method to reduce boxing/unboxing * A Type Specific compute method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed * @param key the key that should be computed
* @param mappingFunction the operator that should generate the value * @param mappingFunction the operator that should generate the value
* @return the result of the computation * @return the result of the computation
*/ */
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction); public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
/** /**
* A Type Specific compute method to reduce boxing/unboxing * A Type Specific computeIfAbsent method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed * @param key the key that should be computed
* @param mappingFunction the operator that should generate the value if not present * @param mappingFunction the operator that should generate the value if not present
* @return the result of the computed value or present value * @return the result of the computed value or present value
*/ */
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction); public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction);
/** /**
* A Supplier based computeIfAbsent function to fill the most used usecase of this function * A Supplier based computeIfAbsent function to fill the most used usecase of this function
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed * @param key the key that should be computed
* @param valueProvider the value if not present * @param valueProvider the value if not present
* @return the result of the computed value or present value * @return the result of the computed value or present value
@@ -348,14 +409,57 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider); public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider);
/** /**
* A Type Specific compute method to reduce boxing/unboxing * A Type Specific compute method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed * @param key the key that should be computed
* @param mappingFunction the operator that should generate the value if present * @param mappingFunction the operator that should generate the value if present
* @return the result of the default return value or present value * @return the result of the default return value or present value
* @note if not present then compute is not executed * @note if not present then compute is not executed
*/ */
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction); public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
#if !VALUE_OBJECT
/**
* A Type Specific compute method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed
* @param mappingFunction the operator that should generate the value
* @return the result of the computation
*/
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
/**
* A Type Specific computeIfAbsent method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed
* @param mappingFunction the operator that should generate the value if not present
* @return the result of the computed value or present value
*/
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction);
/**
* A Supplier based computeIfAbsent function to fill the most used usecase of this function
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed
* @param valueProvider the value if not present
* @return the result of the computed value or present value
*/
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider);
/**
* A Type Specific compute method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be computed
* @param mappingFunction the operator that should generate the value if present
* @return the result of the default return value or present value
* @note if not present then compute is not executed
*/
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
#endif
/** /**
* A Type Specific merge method to reduce boxing/unboxing * A Type Specific merge method to reduce boxing/unboxing
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param key the key that should be be searched for * @param key the key that should be be searched for
* @param value the value that should be merged with * @param value the value that should be merged with
* @param mappingFunction the operator that should generate the new Value * @param mappingFunction the operator that should generate the new Value
@@ -365,6 +469,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction); public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction);
/** /**
* A Bulk method for merging Maps. * A Bulk method for merging Maps.
* If the generated value equals the getDefaultReturnValue it will simply not insert it since that is treated as "null".
* A "Null Value" will be treated as "Do not insert/remove" based on how the Java has specified it.
* @param m the entries that should be bulk added * @param m the entries that should be bulk added
* @param mappingFunction the operator that should generate the new Value * @param mappingFunction the operator that should generate the new Value
* @note if the result matches the default return value then the key is removed from the map * @note if the result matches the default return value then the key is removed from the map
@@ -384,13 +490,19 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return VALUE_TO_OBJ(replace(OBJ_TO_KEY(key), OBJ_TO_VALUE(value))); return VALUE_TO_OBJ(replace(OBJ_TO_KEY(key), OBJ_TO_VALUE(value)));
} }
#endif
@Override
public default VALUE_TYPE APPLY(KEY_TYPE key) {
return GET_VALUE(key);
}
/** /**
* A Type Specific get method to reduce boxing/unboxing * A Type Specific get method to reduce boxing/unboxing
* @param key the key that is searched for * @param key the key that is searched for
* @return the searched value or default return value * @return the searched value or default return value
*/ */
@Override
public VALUE_TYPE GET_VALUE(KEY_TYPE key); public VALUE_TYPE GET_VALUE(KEY_TYPE key);
#if !TYPE_OBJECT || !VALUE_OBJECT
/** /**
* A Type Specific getOrDefault method to reduce boxing/unboxing * A Type Specific getOrDefault method to reduce boxing/unboxing
* @param key the key that is searched for * @param key the key that is searched for
@@ -485,7 +597,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
*/ */
public ObjectSet<Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET(); public ObjectSet<Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET();
#if !TYPE_BOOLEAN #if MAPS_FEATURE
/** /**
* Creates a Wrapped Map that is Synchronized * Creates a Wrapped Map that is Synchronized
* @return a new Map that is synchronized * @return a new Map that is synchronized
@@ -557,8 +669,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
*/ */
public KEY_TYPE ENTRY_KEY(); public KEY_TYPE ENTRY_KEY();
public default CLASS_TYPE getKey() { return KEY_TO_OBJ(ENTRY_KEY()); } public default CLASS_TYPE getKey() { return KEY_TO_OBJ(ENTRY_KEY()); }
#endif
#endif
#if !VALUE_OBJECT #if !VALUE_OBJECT
/** /**
* Type Specific getValue method that reduces boxing/unboxing * Type Specific getValue method that reduces boxing/unboxing
@@ -638,6 +750,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
} }
#endif #endif
#if MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @Type(T) * @Type(T)
@@ -711,6 +824,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new HASH_MAPKV_BRACES(map); return new HASH_MAPKV_BRACES(map);
} }
#endif
#if LINKED_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @Type(T) * @Type(T)
@@ -784,6 +899,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new IMMUTABLE_HASH_MAPKV_BRACES(map); return new IMMUTABLE_HASH_MAPKV_BRACES(map);
} }
#endif
#if IMMUTABLE_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @param keys the keys that should be inserted * @param keys the keys that should be inserted
@@ -836,7 +953,9 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new IMMUTABLE_HASH_MAPKV_BRACES(map); return new IMMUTABLE_HASH_MAPKV_BRACES(map);
} }
#endif
#if TYPE_OBJECT #if TYPE_OBJECT
#if ENUM_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @param keyType the EnumClass that should be used * @param keyType the EnumClass that should be used
@@ -904,6 +1023,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new ENUM_MAPKV_BRACES(map); return new ENUM_MAPKV_BRACES(map);
} }
#endif
#if LINKED_ENUM_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @param keyType the EnumClass that should be used * @param keyType the EnumClass that should be used
@@ -970,7 +1091,10 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public GENERIC_KEY_ENUM_VALUE_BRACES LINKED_ENUM_MAP KEY_VALUE_GENERIC_TYPE linkedEnumMap(MAP KEY_VALUE_GENERIC_TYPE map) { public GENERIC_KEY_ENUM_VALUE_BRACES LINKED_ENUM_MAP KEY_VALUE_GENERIC_TYPE linkedEnumMap(MAP KEY_VALUE_GENERIC_TYPE map) {
return new LINKED_ENUM_MAPKV_BRACES(map); return new LINKED_ENUM_MAPKV_BRACES(map);
} }
#endif #endif
#endif
#if CUSTOM_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @param strategy the Hash Controller * @param strategy the Hash Controller
@@ -1050,6 +1174,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new CUSTOM_HASH_MAPKV_BRACES(map, strategy); return new CUSTOM_HASH_MAPKV_BRACES(map, strategy);
} }
#endif
#if LINKED_CUSTOM_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @param strategy the Hash Controller * @param strategy the Hash Controller
@@ -1129,6 +1255,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new LINKED_CUSTOM_HASH_MAPKV_BRACES(map, strategy); return new LINKED_CUSTOM_HASH_MAPKV_BRACES(map, strategy);
} }
#endif
#if ARRAY_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @Type(T) * @Type(T)
@@ -1202,7 +1330,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new ARRAY_MAPKV_BRACES(map); return new ARRAY_MAPKV_BRACES(map);
} }
#endif
#if RB_TREE_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @Type(T) * @Type(T)
@@ -1280,6 +1409,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new RB_TREE_MAPKV_BRACES(map, comp); return new RB_TREE_MAPKV_BRACES(map, comp);
} }
#endif
#if AVL_TREE_MAP_FEATURE
/** /**
* Helper function to unify code * Helper function to unify code
* @Type(T) * @Type(T)
@@ -1356,6 +1487,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public GENERIC_KEY_VALUE_BRACES AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE avlTreeMap(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, COMPARATOR KEY_GENERIC_TYPE comp) { public GENERIC_KEY_VALUE_BRACES AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE avlTreeMap(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, COMPARATOR KEY_GENERIC_TYPE comp) {
return new AVL_TREE_MAPKV_BRACES(map, comp); return new AVL_TREE_MAPKV_BRACES(map, comp);
} }
#endif
} }
/** /**
@@ -1381,6 +1513,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
* @param initialSize the requested start capacity * @param initialSize the requested start capacity
*/ */
public BuilderCache(int initialSize) { public BuilderCache(int initialSize) {
if(initialSize < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed");
keys = NEW_KEY_ARRAY(initialSize); keys = NEW_KEY_ARRAY(initialSize);
values = NEW_VALUE_ARRAY(initialSize); values = NEW_VALUE_ARRAY(initialSize);
} }
@@ -1433,7 +1566,11 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
* @return self * @return self
*/ */
public BuilderCache KEY_VALUE_GENERIC_TYPE putAll(MAP KEY_VALUE_GENERIC_TYPE map) { public BuilderCache KEY_VALUE_GENERIC_TYPE putAll(MAP KEY_VALUE_GENERIC_TYPE map) {
#if MAPS_FEATURE
return putAll(MAPS.fastIterable(map)); return putAll(MAPS.fastIterable(map));
#else
return putAll(map.ENTRY_SET());
#endif
} }
/** /**
@@ -1462,11 +1599,14 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return this; return this;
} }
#if MAP_FEATURE || LINKED_MAP_FEATURE || CUSTOM_MAP_FEATURE || LINKED_CUSTOM_MAP_FEATURE || AVL_TREE_MAP_FEATURE || RB_TREE_MAP_FEATURE || CONCURRENT_MAP_FEATURE
private <E extends MAP KEY_VALUE_GENERIC_TYPE> E putElements(E e){ private <E extends MAP KEY_VALUE_GENERIC_TYPE> E putElements(E e){
e.putAll(keys, values, 0, size); e.putAll(keys, values, 0, size);
return e; return e;
} }
#endif
#if MAP_FEATURE
/** /**
* Builds the Keys and Values into a Hash Map * Builds the Keys and Values into a Hash Map
* @return a HASH_MAP * @return a HASH_MAP
@@ -1475,6 +1615,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return putElements(new HASH_MAPKV_BRACES(size)); return putElements(new HASH_MAPKV_BRACES(size));
} }
#endif
#if LINKED_MAP_FEATURE
/** /**
* Builds the Keys and Values into a Linked Hash Map * Builds the Keys and Values into a Linked Hash Map
* @return a LINKED_HASH_MAP * @return a LINKED_HASH_MAP
@@ -1483,6 +1625,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return putElements(new LINKED_HASH_MAPKV_BRACES(size)); return putElements(new LINKED_HASH_MAPKV_BRACES(size));
} }
#endif
#if IMMUTABLE_MAP_FEATURE
/** /**
* Builds the Keys and Values into a Immutable Hash Map * Builds the Keys and Values into a Immutable Hash Map
* @return a IMMUTABLE_HASH_MAP * @return a IMMUTABLE_HASH_MAP
@@ -1491,6 +1635,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new IMMUTABLE_HASH_MAPKV_BRACES(Arrays.copyOf(keys, size), Arrays.copyOf(values, size)); return new IMMUTABLE_HASH_MAPKV_BRACES(Arrays.copyOf(keys, size), Arrays.copyOf(values, size));
} }
#endif
#if CUSTOM_MAP_FEATURE
/** /**
* Builds the Keys and Values into a Custom Hash Map * Builds the Keys and Values into a Custom Hash Map
* @param strategy the that controls the keys and values * @param strategy the that controls the keys and values
@@ -1500,6 +1646,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return putElements(new CUSTOM_HASH_MAPKV_BRACES(size, strategy)); return putElements(new CUSTOM_HASH_MAPKV_BRACES(size, strategy));
} }
#endif
#if LINKED_CUSTOM_MAP_FEATURE
/** /**
* Builds the Keys and Values into a Linked Custom Hash Map * Builds the Keys and Values into a Linked Custom Hash Map
* @param strategy the that controls the keys and values * @param strategy the that controls the keys and values
@@ -1509,6 +1657,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return putElements(new LINKED_CUSTOM_HASH_MAPKV_BRACES(size, strategy)); return putElements(new LINKED_CUSTOM_HASH_MAPKV_BRACES(size, strategy));
} }
#endif
#if CONCURRENT_MAP_FEATURE
/** /**
* Builds the Keys and Values into a Concurrent Hash Map * Builds the Keys and Values into a Concurrent Hash Map
* @return a CONCURRENT_HASH_MAP * @return a CONCURRENT_HASH_MAP
@@ -1517,6 +1667,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return putElements(new CONCURRENT_HASH_MAPKV_BRACES(size)); return putElements(new CONCURRENT_HASH_MAPKV_BRACES(size));
} }
#endif
#if ARRAY_MAP_FEATURE
/** /**
* Builds the Keys and Values into a Array Map * Builds the Keys and Values into a Array Map
* @return a ARRAY_MAP * @return a ARRAY_MAP
@@ -1525,6 +1677,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return new ARRAY_MAPKV_BRACES(keys, values, size); return new ARRAY_MAPKV_BRACES(keys, values, size);
} }
#endif
#if RB_TREE_MAP_FEATURE
/** /**
* Builds the Keys and Values into a RedBlack TreeMap * Builds the Keys and Values into a RedBlack TreeMap
* @return a RB_TREE_MAP * @return a RB_TREE_MAP
@@ -1542,6 +1696,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
return putElements(new RB_TREE_MAPKV_BRACES(comp)); return putElements(new RB_TREE_MAPKV_BRACES(comp));
} }
#endif
#if AVL_TREE_MAP_FEATURE
/** /**
* Builds the Keys and Values into a AVL TreeMap * Builds the Keys and Values into a AVL TreeMap
* @return a AVL_TREE_MAP * @return a AVL_TREE_MAP
@@ -1558,6 +1714,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
public AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE avlTreeMap(COMPARATOR KEY_GENERIC_TYPE comp) { public AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE avlTreeMap(COMPARATOR KEY_GENERIC_TYPE comp) {
return putElements(new AVL_TREE_MAPKV_BRACES(comp)); return putElements(new AVL_TREE_MAPKV_BRACES(comp));
} }
#endif
} }
#endif #endif
} }
@@ -2,7 +2,9 @@ package speiger.src.collections.PACKAGE.maps.interfaces;
import java.util.NavigableMap; import java.util.NavigableMap;
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET; import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
#if MAPS_FEATURE
import speiger.src.collections.PACKAGE.utils.maps.MAPS; import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#endif
/** /**
* A Type Specific Navigable Map interface with a couple helper methods * A Type Specific Navigable Map interface with a couple helper methods
@@ -34,7 +36,11 @@ public interface NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE extends SORTED_MAP KEY_VAL
/** @return a Type Specific pollLastEntry */ /** @return a Type Specific pollLastEntry */
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry(); public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry();
/** @return a Type Specific Navigable Key Set */
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE keySet();
#if MAPS_FEATURE
/** /**
* Creates a Wrapped NavigableMap that is Synchronized * Creates a Wrapped NavigableMap that is Synchronized
* @return a new NavigableMap that is synchronized * @return a new NavigableMap that is synchronized
@@ -57,6 +63,7 @@ public interface NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE extends SORTED_MAP KEY_VAL
*/ */
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); } public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); }
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** /**
* A Type Specific SubMap method to reduce boxing/unboxing * A Type Specific SubMap method to reduce boxing/unboxing
@@ -1,6 +1,11 @@
package speiger.src.collections.PACKAGE.maps.interfaces; package speiger.src.collections.PACKAGE.maps.interfaces;
#if MAPS_FEATURE
import speiger.src.collections.PACKAGE.utils.maps.MAPS; import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
#endif
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator; import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
import speiger.src.collections.objects.sets.ObjectOrderedSet; import speiger.src.collections.objects.sets.ObjectOrderedSet;
/** /**
@@ -94,7 +99,12 @@ public interface ORDERED_MAP KEY_VALUE_GENERIC_TYPE extends MAP KEY_VALUE_GENERI
@Override @Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy(); public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy();
@Override
public ORDERED_SET KEY_GENERIC_TYPE keySet();
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET();
#if MAPS_FEATURE
/** /**
* Creates a Wrapped SortedMap that is Synchronized * Creates a Wrapped SortedMap that is Synchronized
* @return a new SortedMap that is synchronized * @return a new SortedMap that is synchronized
@@ -120,6 +130,7 @@ public interface ORDERED_MAP KEY_VALUE_GENERIC_TYPE extends MAP KEY_VALUE_GENERI
@Override @Override
public default ORDERED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); } public default ORDERED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); }
#endif
/** /**
* Fast Ordered Entry Set that allows for a faster Entry Iterator by recycling the Entry Object and just exchanging 1 internal value * Fast Ordered Entry Set that allows for a faster Entry Iterator by recycling the Entry Object and just exchanging 1 internal value
* @Type(T) * @Type(T)
@@ -9,9 +9,13 @@ import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SORTED_SET;
#if MAPS_FEATURE
import speiger.src.collections.PACKAGE.utils.maps.MAPS; import speiger.src.collections.PACKAGE.utils.maps.MAPS;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.objects.sets.ObjectSortedSet; import speiger.src.collections.objects.sets.ObjectSortedSet;
#endif
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator; import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
/** /**
@@ -31,10 +35,11 @@ public interface SORTED_MAP KEY_VALUE_GENERIC_TYPE extends SortedMap<CLASS_TYPE,
public SORTED_MAP KEY_VALUE_GENERIC_TYPE copy(); public SORTED_MAP KEY_VALUE_GENERIC_TYPE copy();
@Override @Override
public SET KEY_GENERIC_TYPE keySet(); public SORTED_SET KEY_GENERIC_TYPE keySet();
@Override @Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values(); public VALUE_COLLECTION VALUE_GENERIC_TYPE values();
#if MAPS_FEATURE
/** /**
* Creates a Wrapped SortedMap that is Synchronized * Creates a Wrapped SortedMap that is Synchronized
* @return a new SortedMap that is synchronized * @return a new SortedMap that is synchronized
@@ -57,6 +62,7 @@ public interface SORTED_MAP KEY_VALUE_GENERIC_TYPE extends SortedMap<CLASS_TYPE,
*/ */
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); } public default SORTED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); }
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** /**
* A Type Specific SubMap method to reduce boxing/unboxing * A Type Specific SubMap method to reduce boxing/unboxing
@@ -155,11 +161,11 @@ public interface SORTED_MAP KEY_VALUE_GENERIC_TYPE extends SortedMap<CLASS_TYPE,
public VALUE_TYPE LAST_ENTRY_VALUE(); public VALUE_TYPE LAST_ENTRY_VALUE();
@Override @Override
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, CLASS_TYPE toKey) { return subMap(OBJ_TO_KEY(fromKey), OBJ_TO_KEY(toKey)); } public SORTED_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, CLASS_TYPE toKey);
@Override @Override
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey) { return headMap(OBJ_TO_KEY(toKey)); } public SORTED_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey);
@Override @Override
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey) { return tailMap(OBJ_TO_KEY(fromKey)); } public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey);
#endif #endif
/** /**
@@ -1,7 +1,12 @@
package speiger.src.collections.PACKAGE.misc.pairs; package speiger.src.collections.PACKAGE.misc.pairs;
#if IMMUTABLE_PAIR
import speiger.src.collections.PACKAGE.misc.pairs.impl.IMMUTABLE_PAIR; import speiger.src.collections.PACKAGE.misc.pairs.impl.IMMUTABLE_PAIR;
#endif
#if MUTABLE_PAIR
import speiger.src.collections.PACKAGE.misc.pairs.impl.MUTABLE_PAIR; import speiger.src.collections.PACKAGE.misc.pairs.impl.MUTABLE_PAIR;
#endif
/** /**
* Key Value Pair Interface that allows to reduce boxing/unboxing. * Key Value Pair Interface that allows to reduce boxing/unboxing.
* @Type(T) * @Type(T)
@@ -9,6 +14,7 @@ import speiger.src.collections.PACKAGE.misc.pairs.impl.MUTABLE_PAIR;
*/ */
public interface PAIR KEY_VALUE_GENERIC_TYPE public interface PAIR KEY_VALUE_GENERIC_TYPE
{ {
#if IMMUTABLE_PAIR
/** /**
* Empty Reference for Immutable Pairs * Empty Reference for Immutable Pairs
*/ */
@@ -68,6 +74,8 @@ public interface PAIR KEY_VALUE_GENERIC_TYPE
return new IMMUTABLE_PAIRKV_BRACES(pair.ENTRY_KEY(), pair.ENTRY_VALUE()); return new IMMUTABLE_PAIRKV_BRACES(pair.ENTRY_KEY(), pair.ENTRY_VALUE());
} }
#endif
#if MUTABLE_PAIR
/** /**
* @Type(T) * @Type(T)
* @ValueType(V) * @ValueType(V)
@@ -118,6 +126,7 @@ public interface PAIR KEY_VALUE_GENERIC_TYPE
return new MUTABLE_PAIRKV_BRACES(pair.ENTRY_KEY(), pair.ENTRY_VALUE()); return new MUTABLE_PAIRKV_BRACES(pair.ENTRY_KEY(), pair.ENTRY_VALUE());
} }
#endif
/** /**
* Sets the Key of the Pair. * Sets the Key of the Pair.
* @param key the key that should be set. * @param key the key that should be set.
@@ -8,14 +8,20 @@ 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
import java.util.function.PREDICATE;
#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.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#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;
@@ -162,6 +168,15 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
return index >= array.length ? array[index-array.length] : array[index]; return index >= array.length ? array[index-array.length] : array[index];
} }
@Override
public boolean contains(KEY_TYPE e) {
if(first == last) return false;
for(int i = 0,m=size();i<m;i++) {
if(e == array[(first + i) % array.length]) return true;
}
return false;
}
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
if(first == last) return false; if(first == last) return false;
@@ -257,6 +272,15 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
clearAndTrim(0); clearAndTrim(0);
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(first == last) return;
for(int i = 0,m=size();i<m;i++)
action.accept(i, array[(first + i) % array.length]);
clearAndTrim(0);
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -270,7 +294,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
public boolean matchesAny(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_VALUE(array[(first + i) % array.length])) return true; if(filter.test(array[(first + i) % array.length])) return true;
} }
return false; return false;
} }
@@ -279,7 +303,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
public boolean matchesNone(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_VALUE(array[(first + i) % array.length])) return false; if(filter.test(array[(first + i) % array.length])) return false;
} }
return true; return true;
} }
@@ -288,7 +312,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
public boolean matchesAll(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++) {
if(!filter.TEST_VALUE(array[(first + i) % array.length])) return false; if(!filter.test(array[(first + i) % array.length])) return false;
} }
return true; return true;
} }
@@ -298,7 +322,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) { for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length; int index = (first + i) % array.length;
if(filter.TEST_VALUE(array[index])) { if(filter.test(array[index])) {
KEY_TYPE data = array[index]; KEY_TYPE data = array[index];
removeIndex(index); removeIndex(index);
return data; return data;
@@ -351,7 +375,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(int i = 0,m=size();i<m;i++) { for(int i = 0,m=size();i<m;i++) {
if(filter.TEST_VALUE(array[(first + i) % array.length])) result++; if(filter.test(array[(first + i) % array.length])) result++;
} }
return result; return result;
} }
@@ -434,6 +458,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
KEY_TYPE value = array[index]; KEY_TYPE value = array[index];
removeIndex(index); removeIndex(index);
index = ++index % array.length; index = ++index % array.length;
@@ -8,6 +8,9 @@ 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
import java.util.function.PREDICATE;
#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;
@@ -15,8 +18,11 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#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;
@@ -187,7 +193,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
@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 + (array.length >> 1), 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;
@@ -209,12 +215,26 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
return value; return value;
} }
@Override
public KEY_TYPE first() {
if(isEmpty()) throw new NoSuchElementException();
if(firstIndex == -1) findFirstIndex();
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
public boolean contains(KEY_TYPE e) {
for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return true;
return false;
}
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
@@ -263,6 +283,12 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
for(int i = 0,m=size;i<m;i++) action.accept(dequeue()); for(int i = 0,m=size;i<m;i++) action.accept(dequeue());
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue());
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -273,7 +299,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) return true; if(filter.test(array[i])) return true;
} }
return false; return false;
} }
@@ -282,7 +308,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) return false; if(filter.test(array[i])) return false;
} }
return true; return true;
} }
@@ -291,7 +317,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(!filter.TEST_VALUE(array[i])) return false; if(!filter.test(array[i])) return false;
} }
return true; return true;
} }
@@ -339,7 +365,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) { if(filter.test(array[i])) {
KEY_TYPE data = array[i]; KEY_TYPE data = array[i];
removeIndex(i); removeIndex(i);
return data; return data;
@@ -353,7 +379,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) result++; if(filter.test(array[i])) result++;
} }
return result; return result;
} }
@@ -414,6 +440,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUE
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
return dequeue(); return dequeue();
} }
} }
@@ -8,6 +8,9 @@ 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
import java.util.function.PREDICATE;
#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;
@@ -15,8 +18,11 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#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;
@@ -207,7 +213,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
@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 + (array.length >> 1), 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);
} }
@@ -230,6 +236,13 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
return array[index]; return array[index];
} }
@Override
public boolean contains(KEY_TYPE e) {
for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return true;
return false;
}
@Override @Override
public boolean removeFirst(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
@@ -250,6 +263,12 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
for(int i = 0,m=size;i<m;i++) action.accept(dequeue()); for(int i = 0,m=size;i<m;i++) action.accept(dequeue());
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue());
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -260,7 +279,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) return true; if(filter.test(array[i])) return true;
} }
return false; return false;
} }
@@ -269,7 +288,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) return false; if(filter.test(array[i])) return false;
} }
return true; return true;
} }
@@ -278,7 +297,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(!filter.TEST_VALUE(array[i])) return false; if(!filter.test(array[i])) return false;
} }
return true; return true;
} }
@@ -326,7 +345,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) { if(filter.test(array[i])) {
KEY_TYPE data = array[i]; KEY_TYPE data = array[i];
removeIndex(i); removeIndex(i);
return data; return data;
@@ -340,7 +359,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) result++; if(filter.test(array[i])) result++;
} }
return result; return result;
} }
@@ -389,6 +408,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEU
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
return dequeue(); return dequeue();
} }
} }
@@ -6,7 +6,9 @@ import java.util.Iterator;
#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 QUEUES_FEATURE
import speiger.src.collections.PACKAGE.utils.PRIORITY_QUEUES; import speiger.src.collections.PACKAGE.utils.PRIORITY_QUEUES;
#endif
/** /**
* A Type Speciifc PriorityDeque or Dequeue interface to allow implementations like FIFO queues. * A Type Speciifc PriorityDeque or Dequeue interface to allow implementations like FIFO queues.
@@ -81,6 +83,7 @@ public interface PRIORITY_DEQUEUE KEY_GENERIC_TYPE extends PRIORITY_QUEUE KEY_GE
*/ */
public default KEY_TYPE last() { return peek(size()-1); } public default KEY_TYPE last() { return peek(size()-1); }
#if QUEUES_FEATURE
/** /**
* Creates a Wrapped PriorityDequeue that is Synchronized * Creates a Wrapped PriorityDequeue that is Synchronized
* @return a new PriorityDequeue that is synchronized * @return a new PriorityDequeue that is synchronized
@@ -96,6 +99,7 @@ public interface PRIORITY_DEQUEUE KEY_GENERIC_TYPE extends PRIORITY_QUEUE KEY_GE
*/ */
public default PRIORITY_DEQUEUE KEY_GENERIC_TYPE synchronizeQueue(Object mutex) { return PRIORITY_QUEUES.synchronize(this, mutex); } public default PRIORITY_DEQUEUE KEY_GENERIC_TYPE synchronizeQueue(Object mutex) { return PRIORITY_QUEUES.synchronize(this, mutex); }
#endif
@Override @Override
public PRIORITY_DEQUEUE KEY_GENERIC_TYPE copy(); public PRIORITY_DEQUEUE KEY_GENERIC_TYPE copy();
} }
@@ -4,15 +4,16 @@ package speiger.src.collections.PACKAGE.queues;
import java.util.Comparator; import java.util.Comparator;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.function.IntFunction;
import speiger.src.collections.ints.functions.function.Int2ObjectFunction;
#else #else
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERABLE; import speiger.src.collections.PACKAGE.collections.ITERABLE;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if QUEUES_FEATURE
import speiger.src.collections.PACKAGE.utils.PRIORITY_QUEUES; import speiger.src.collections.PACKAGE.utils.PRIORITY_QUEUES;
#endif
/** /**
@@ -110,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
@@ -147,8 +155,9 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY
* @return draining iterator of the PriorityQueue * @return draining iterator of the PriorityQueue
*/ */
public ITERATOR KEY_GENERIC_TYPE iterator(); public ITERATOR KEY_GENERIC_TYPE iterator();
#endif
#endif
#if QUEUES_FEATURE
/** /**
* Creates a Wrapped PriorityQueue that is Synchronized * Creates a Wrapped PriorityQueue that is Synchronized
* @return a new PriorityQueue that is synchronized * @return a new PriorityQueue that is synchronized
@@ -164,6 +173,7 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY
*/ */
public default PRIORITY_QUEUE KEY_GENERIC_TYPE synchronizeQueue(Object mutex) { return PRIORITY_QUEUES.synchronize(this, mutex); } public default PRIORITY_QUEUE KEY_GENERIC_TYPE synchronizeQueue(Object mutex) { return PRIORITY_QUEUES.synchronize(this, mutex); }
#endif
/** /**
* A method to drop the contents of the Queue without clearing the queue * A method to drop the contents of the Queue without clearing the queue
* @Type(E) * @Type(E)
@@ -182,11 +192,12 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY
/** /**
* A Helper function that simplifies the process of creating a new Array. * A Helper function that simplifies the process of creating a new Array.
* @param action the array creation function * @param action the array creation function
* @param <E> the returning arrayType
* @return an array containing all of the elements in this collection * @return an array containing all of the elements in this collection
* @see Collection#toArray(Object[]) * @see Collection#toArray(Object[])
*/ */
default KEY_TYPE[] TO_ARRAY(Int2ObjectFunction<KEY_TYPE[]> action) { default <E> E[] TO_ARRAY(IntFunction<E[]> action) {
return TO_ARRAY(action.get(size())); return TO_ARRAY(action.apply(size()));
} }
#endif #endif
} }
@@ -10,16 +10,24 @@ import java.util.function.BiFunction;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_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.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
@@ -353,6 +361,15 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
action.accept(index++, entry.key);
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -364,7 +381,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.TEST_VALUE(entry.key)) return true; if(filter.test(entry.key)) return true;
} }
return false; return false;
} }
@@ -373,7 +390,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.TEST_VALUE(entry.key)) return false; if(filter.test(entry.key)) return false;
} }
return true; return true;
} }
@@ -382,7 +399,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(!filter.TEST_VALUE(entry.key)) return false; if(!filter.test(entry.key)) return false;
} }
return true; return true;
} }
@@ -391,7 +408,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.TEST_VALUE(entry.key)) return entry.key; if(filter.test(entry.key)) return entry.key;
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -440,7 +457,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.TEST_VALUE(entry.key)) result++; if(filter.test(entry.key)) result++;
} }
return result; return result;
} }
@@ -635,6 +652,44 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
tree = null; tree = null;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
a[index++] = entry.key;
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
obj[index++] = KEY_TO_OBJ(entry.key);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
a[index++] = (E)KEY_TO_OBJ(entry.key);
}
if (a.length > size) a[size] = null;
return a;
}
public AVL_TREE_SET KEY_GENERIC_TYPE copy() { public AVL_TREE_SET KEY_GENERIC_TYPE copy() {
AVL_TREE_SET KEY_GENERIC_TYPE set = new AVL_TREE_SETBRACES(); AVL_TREE_SET KEY_GENERIC_TYPE set = new AVL_TREE_SETBRACES();
set.size = size; set.size = size;
@@ -888,15 +943,11 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; } public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; }
public KEY_TYPE getDefaultMaxValue() { return super.getDefaultMinValue(); }
public KEY_TYPE getDefaultMinValue() { return super.getDefaultMaxValue(); }
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) {
if(!inRange(fromElement, fromInclusive)) throw new IllegalArgumentException("fromElement out of range"); if(!inRange(fromElement, fromInclusive)) throw new IllegalArgumentException("fromElement out of range");
if(!inRange(toElement, toInclusive)) throw new IllegalArgumentException("toElement out of range"); if(!inRange(toElement, toInclusive)) throw new IllegalArgumentException("toElement out of range");
return new DescendingSubSetBRACES(set, false, fromElement, fromInclusive, false, toElement, toInclusive); return new DescendingSubSetBRACES(set, false, toElement, toInclusive, false, fromElement, fromInclusive);
} }
@Override @Override
@@ -973,21 +1024,15 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public void setDefaultMaxValue(KEY_TYPE value) { set.setDefaultMaxValue(value); } public void setDefaultMaxValue(KEY_TYPE value) { set.setDefaultMaxValue(value); }
@Override @Override
public KEY_TYPE getDefaultMaxValue() { return set.getDefaultMaxValue(); } public KEY_TYPE getDefaultMaxValue() { return set.getDefaultMaxValue(); }
@Override @Override
public void setDefaultMinValue(KEY_TYPE value) { set.setDefaultMinValue(value); } public void setDefaultMinValue(KEY_TYPE value) { set.setDefaultMinValue(value); }
@Override @Override
public KEY_TYPE getDefaultMinValue() { return set.getDefaultMinValue(); } public KEY_TYPE getDefaultMinValue() { return set.getDefaultMinValue(); }
#else #else
public KEY_TYPE getDefaultMaxValue() { return null; } public KEY_TYPE getDefaultMaxValue() { return null; }
public KEY_TYPE getDefaultMinValue() { return null; } public KEY_TYPE getDefaultMinValue() { return null; }
#endif #endif
@Override @Override
public abstract BI_ITERATOR KEY_GENERIC_TYPE iterator(); public abstract BI_ITERATOR KEY_GENERIC_TYPE iterator();
@@ -1202,6 +1247,15 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
action.accept(index++, entry.key);
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1213,7 +1267,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.TEST_VALUE(entry.key)) return true; if(filter.test(entry.key)) return true;
} }
return false; return false;
} }
@@ -1222,7 +1276,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.TEST_VALUE(entry.key)) return false; if(filter.test(entry.key)) return false;
} }
return true; return true;
} }
@@ -1231,7 +1285,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(!filter.TEST_VALUE(entry.key)) return false; if(!filter.test(entry.key)) return false;
} }
return true; return true;
} }
@@ -1279,7 +1333,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.TEST_VALUE(entry.key)) return entry.key; if(filter.test(entry.key)) return entry.key;
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -1289,7 +1343,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.TEST_VALUE(entry.key)) result++; if(filter.test(entry.key)) result++;
} }
return result; return result;
} }
@@ -1298,6 +1352,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE lastReturned;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE previous;
boolean forwards = false; boolean forwards = false;
boolean unboundForwardFence; boolean unboundForwardFence;
boolean unboundBackwardFence; boolean unboundBackwardFence;
@@ -1307,6 +1362,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public AscendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence) public AscendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence)
{ {
next = first; next = first;
previous = first == null ? null : first.previous();
this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key; this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key;
this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key; this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key;
unboundForwardFence = forwardFence == null; unboundForwardFence = forwardFence == null;
@@ -1322,6 +1378,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = next; lastReturned = next;
previous = next;
KEY_TYPE result = next.key; KEY_TYPE result = next.key;
next = next.next(); next = next.next();
forwards = true; forwards = true;
@@ -1330,15 +1387,16 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return next != null && (unboundBackwardFence || next.key != backwardFence); return previous != null && (unboundBackwardFence || previous.key != backwardFence);
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next; lastReturned = previous;
KEY_TYPE result = next.key; next = previous;
next = next.previous(); KEY_TYPE result = previous.key;
previous = previous.previous();
forwards = false; forwards = false;
return result; return result;
} }
@@ -1346,6 +1404,8 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public void remove() { public void remove() {
if(lastReturned == null) throw new IllegalStateException(); if(lastReturned == null) throw new IllegalStateException();
if(previous == lastReturned) previous = previous.previous();
if(next == lastReturned) next = next.next();
if(forwards && lastReturned.needsSuccessor()) next = lastReturned; if(forwards && lastReturned.needsSuccessor()) next = lastReturned;
set.removeNode(lastReturned); set.removeNode(lastReturned);
lastReturned = null; lastReturned = null;
@@ -1356,6 +1416,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE lastReturned;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE previous;
boolean forwards = false; boolean forwards = false;
boolean unboundForwardFence; boolean unboundForwardFence;
boolean unboundBackwardFence; boolean unboundBackwardFence;
@@ -1365,6 +1426,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public DescendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence) public DescendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence)
{ {
next = first; next = first;
previous = first == null ? null : first.next();
this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key; this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key;
this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key; this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key;
unboundForwardFence = forwardFence == null; unboundForwardFence = forwardFence == null;
@@ -1380,6 +1442,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = next; lastReturned = next;
previous = next;
KEY_TYPE result = next.key; KEY_TYPE result = next.key;
next = next.previous(); next = next.previous();
forwards = false; forwards = false;
@@ -1388,15 +1451,16 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return next != null && (unboundBackwardFence || next.key != backwardFence); return previous != null && (unboundBackwardFence || previous.key != backwardFence);
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next; lastReturned = previous;
KEY_TYPE result = next.key; next = previous;
next = next.next(); KEY_TYPE result = previous.key;
previous = previous.next();
forwards = true; forwards = true;
return result; return result;
} }
@@ -1404,6 +1468,8 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public void remove() { public void remove() {
if(lastReturned == null) throw new IllegalStateException(); if(lastReturned == null) throw new IllegalStateException();
if(previous == lastReturned) previous = previous.next();
if(next == lastReturned) next = next.previous();
if(forwards && lastReturned.needsSuccessor()) next = lastReturned; if(forwards && lastReturned.needsSuccessor()) next = lastReturned;
set.removeNode(lastReturned); set.removeNode(lastReturned);
lastReturned = null; lastReturned = null;
@@ -1415,11 +1481,13 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE lastReturned;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE previous;
boolean forwards = false; boolean forwards = false;
public AscendingSetIterator(Entry KEY_GENERIC_TYPE first) public AscendingSetIterator(Entry KEY_GENERIC_TYPE first)
{ {
next = first; next = first;
previous = first == null ? null : first.previous();
} }
@Override @Override
@@ -1431,6 +1499,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = next; lastReturned = next;
previous = next;
KEY_TYPE result = next.key; KEY_TYPE result = next.key;
next = next.next(); next = next.next();
forwards = true; forwards = true;
@@ -1439,15 +1508,16 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return next != null; return previous != null;
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next; lastReturned = previous;
KEY_TYPE result = next.key; next = previous;
next = next.previous(); KEY_TYPE result = previous.key;
previous = previous.previous();
forwards = false; forwards = false;
return result; return result;
} }
@@ -1455,6 +1525,8 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public void remove() { public void remove() {
if(lastReturned == null) throw new IllegalStateException(); if(lastReturned == null) throw new IllegalStateException();
if(lastReturned == previous) previous = previous.previous();
if(lastReturned == next) next = next.next();
if(forwards && lastReturned.needsSuccessor()) next = lastReturned; if(forwards && lastReturned.needsSuccessor()) next = lastReturned;
removeNode(lastReturned); removeNode(lastReturned);
lastReturned = null; lastReturned = null;
@@ -1465,11 +1537,13 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE lastReturned;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE previous;
boolean forwards = false; boolean forwards = false;
public DescendingSetIterator(Entry KEY_GENERIC_TYPE first) public DescendingSetIterator(Entry KEY_GENERIC_TYPE first)
{ {
next = first; next = first;
previous = first == null ? null : first.next();
} }
@Override @Override
@@ -1481,6 +1555,7 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = next; lastReturned = next;
previous = next;
KEY_TYPE result = next.key; KEY_TYPE result = next.key;
next = next.previous(); next = next.previous();
forwards = false; forwards = false;
@@ -1489,15 +1564,16 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return next != null; return previous != null;
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next; lastReturned = previous;
KEY_TYPE result = next.key; next = previous;
next = next.next(); KEY_TYPE result = previous.key;
previous = previous.next();
forwards = true; forwards = true;
return result; return result;
} }
@@ -1505,6 +1581,8 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public void remove() { public void remove() {
if(lastReturned == null) throw new IllegalStateException(); if(lastReturned == null) throw new IllegalStateException();
if(lastReturned == previous) previous = previous.next();
if(lastReturned == next) next = next.previous();
if(forwards && lastReturned.needsSuccessor()) next = lastReturned; if(forwards && lastReturned.needsSuccessor()) next = lastReturned;
removeNode(lastReturned); removeNode(lastReturned);
lastReturned = null; lastReturned = null;
@@ -9,15 +9,21 @@ import java.util.function.BiFunction;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
#if PRIMITIVES #if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
#if PRIMITIVES && !JDK_FUNCTION
import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
@@ -54,6 +60,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
* @throws NegativeArraySizeException if the capacity is negative * @throws NegativeArraySizeException if the capacity is negative
*/ */
public ARRAY_SET(int capacity) { public ARRAY_SET(int capacity) {
if(capacity < 0) throw new IllegalStateException("Size has to be 0 or greater");
data = NEW_KEY_ARRAY(capacity); data = NEW_KEY_ARRAY(capacity);
} }
@@ -168,7 +175,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
} }
else if(index != size - 1) { else if(index != size - 1) {
o = data[index]; o = data[index];
System.arraycopy(data, index+1, data, index, size - index); System.arraycopy(data, index+1, data, index, size - index - 1);
data[size-1] = o; data[size-1] = o;
} }
return false; return false;
@@ -390,6 +397,12 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
for(int i = 0;i<size;action.accept(data[i++])); for(int i = 0;i<size;action.accept(data[i++]));
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;action.accept(i, data[i++]));
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -401,7 +414,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(data[i])) return true; if(filter.test(data[i])) return true;
} }
return false; return false;
} }
@@ -410,7 +423,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(data[i])) return false; if(filter.test(data[i])) return false;
} }
return true; return true;
} }
@@ -419,7 +432,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(!filter.TEST_VALUE(data[i])) return false; if(!filter.test(data[i])) return false;
} }
return true; return true;
} }
@@ -428,7 +441,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(data[i])) return data[i]; if(filter.test(data[i])) return data[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -477,7 +490,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(int i = 0;i<size;i++) { for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(data[i])) result++; if(filter.test(data[i])) result++;
} }
return result; return result;
} }
@@ -538,6 +551,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override @Override
@Deprecated @Deprecated
public Object[] toArray() { public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()]; Object[] obj = new Object[size()];
for(int i = 0;i<size();i++) for(int i = 0;i<size();i++)
obj[i] = KEY_TO_OBJ(data[i]); obj[i] = KEY_TO_OBJ(data[i]);
@@ -555,347 +569,6 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
return a; return a;
} }
// Disabled until a Proper Implementation can be thought out or it is decided that the interface is thrown out.
// private class SubSet extends ABSTRACT_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE {
// int offset;
// int length;
//
// SubSet(int offset, int length) {
// this.offset = offset;
// this.length = length;
// }
//
// int end() { return offset+length; }
//
// @Override
// public boolean add(KEY_TYPE o) {
// int index = findIndex(o);
// if(index == -1) {
// if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
// if(end() != size) System.arraycopy(data, end(), data, end()+1, size-(offset+length));
// data[end()] = o;
// size++;
// length++;
// return true;
// }
// return false;
// }
//
// @Override
// public boolean addAndMoveToFirst(KEY_TYPE o) {
// int index = findIndex(o);
// if(index == -1) {
// if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
// System.arraycopy(data, offset, data, offset+1, size-offset);
// data[offset] = o;
// size++;
// length++;
// return true;
// }
// else if(index != 0) {
// o = data[index];
// System.arraycopy(data, offset, data, offset+1, index-offset);
// data[offset] = o;
// }
// return false;
// }
//
// @Override
// public boolean addAndMoveToLast(KEY_TYPE o) {
// int index = findIndex(o);
// if(index == -1) {
// if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
// System.arraycopy(data, end()+1, data, end(), size-end());
// data[end()] = o;
// size++;
// length++;
// return true;
// }
// else if(index != 0) {
// o = data[index];
// System.arraycopy(data, offset+1, data, offset, index-offset);
// data[offset+length] = o;
// }
// return false;
// }
//
// @Override
// public boolean moveToFirst(KEY_TYPE o) {
// int index = findIndex(o);
// if(index > offset) {
// o = data[index];
// System.arraycopy(data, offset, data, offset+1, index-offset);
// data[offset] = o;
// return true;
// }
// return false;
// }
//
// @Override
// public boolean moveToLast(KEY_TYPE o) {
// int index = findIndex(o);
// if(index != -1 && index < end()-1) {
// o = data[index];
// System.arraycopy(data, index+1, data, index, end()-index-1);
// data[end()-1] = o;
// return true;
// }
// return false;
// }
//
//#if !TYPE_OBJECT
// @Override
// public boolean contains(KEY_TYPE e) {
// return findIndex(e) != -1;
// }
//
//#endif
// @Override
// public boolean contains(Object e) {
// return findIndex(e) != -1;
// }
//
// @Override
// public KEY_TYPE FIRST_KEY() {
// if(length == 0) throw new NoSuchElementException();
// return data[offset];
// }
//
// @Override
// public KEY_TYPE LAST_KEY() {
// if(length == 0) throw new NoSuchElementException();
// return data[end()-1];
// }
//
//#if !TYPE_OBJECT
// @Override
// public boolean remove(KEY_TYPE o) {
// int index = findIndex(o);
// if(index != -1) {
// size--;
// length--;
// if(index != size) System.arraycopy(data, index+1, data, index, size - index);
// return true;
// }
// return false;
// }
//
//#endif
// @Override
// public boolean remove(Object o) {
// int index = findIndex(o);
// if(index != -1) {
// size--;
// length--;
// if(index != size) System.arraycopy(data, index+1, data, index, size - index);
//#if TYPE_OBJECT
// data[size] = EMPTY_KEY_VALUE;
//#endif
// return true;
// }
// return false;
// }
//
// @Override
// public KEY_TYPE POLL_FIRST_KEY() {
// if(length == 0) throw new NoSuchElementException();
// size--;
// length--;
// KEY_TYPE result = data[offset];
// System.arraycopy(data, offset+1, data, offset, size-offset);
//#if TYPE_OBJECT
// data[size] = EMPTY_KEY_VALUE;
//#endif
// return result;
// }
//
// @Override
// public KEY_TYPE POLL_LAST_KEY() {
// if(length == 0) throw new NoSuchElementException();
// KEY_TYPE result = data[offset+length];
// size--;
// length--;
// System.arraycopy(data, end()+1, data, end(), size-end());
//#if TYPE_OBJECT
// data[size] = EMPTY_KEY_VALUE;
//#endif
// return result;
// }
//
// @Override
// public COMPARATOR KEY_GENERIC_TYPE comparator() {
// return null;
// }
//
// @Override
// public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
// return new SetIterator(offset);
// }
//
// @Override
// public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
// int index = findIndex(fromElement);
// if(index != -1) return new SetIterator(index);
// throw new NoSuchElementException();
// }
//
// @Override
// public SubSet copy() { throw new UnsupportedOperationException(); }
//
// @Override
// public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) {
// int fromIndex = findIndex(fromElement);
// int toIndex = findIndex(toElement);
// if(fromIndex == -1 || toIndex == -1) throw new NoSuchElementException();
// return new SubSet(fromIndex, toIndex - fromIndex + 1);
// }
//
// @Override
// public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) {
// int toIndex = findIndex(toElement);
// if(toIndex == -1) throw new NoSuchElementException();
// return new SubSet(0, toIndex+1);
// }
//
// @Override
// public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) {
// int fromIndex = findIndex(fromElement);
// if(fromIndex == -1) throw new NoSuchElementException();
// return new SubSet(fromIndex, size - fromIndex);
// }
//
// @Override
// public int size() {
// return length;
// }
//
//#if !TYPE_OBJECT
// @Override
// public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
// if(a == null || a.length < size()) return Arrays.copyOfRange(data, offset, end());
// System.arraycopy(data, offset, a, 0, size());
// return a;
// }
//
//#endif
// @Override
// @Deprecated
// public Object[] toArray() {
// Object[] obj = new Object[size()];
// for(int i = 0;i<size();i++)
// obj[i] = KEY_TO_OBJ(data[offset+i]);
// return obj;
// }
//
// @Override
// @Primitive
// public <E> E[] toArray(E[] a) {
// if(a == null) a = (E[])new Object[size()];
// else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
// for(int i = 0;i<size();i++)
// a[i] = (E)KEY_TO_OBJ(data[offset+i]);
// return a;
// }
//
//#if !TYPE_OBJECT
// protected int findIndex(KEY_TYPE o) {
// for(int i = length-1;i>=0;i--)
// if(KEY_EQUALS(data[offset+i], o)) return i + offset;
// return -1;
// }
//
//#endif
// protected int findIndex(Object o) {
// for(int i = length-1;i>=0;i--)
// if(EQUALS_KEY_TYPE(data[offset+i], o)) return i + offset;
// return -1;
// }
//
// private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
// int index;
// int lastReturned = -1;
//
// public SetIterator(int index) {
// this.index = index;
// }
//
// @Override
// public boolean hasNext() {
// return index < size();
// }
//
// @Override
// public KEY_TYPE NEXT() {
// if(!hasNext()) throw new NoSuchElementException();
// lastReturned = index;
// return data[index++];
// }
//
// @Override
// public boolean hasPrevious() {
// return index > 0;
// }
//
// @Override
// public KEY_TYPE PREVIOUS() {
// if(!hasPrevious()) throw new NoSuchElementException();
// lastReturned = index;
// return data[index--];
// }
//
// @Override
// public int nextIndex() {
// return index;
// }
//
// @Override
// public int previousIndex() {
// return index-1;
// }
//
// @Override
// public void remove() {
// if(lastReturned == -1)
// throw new IllegalStateException();
// SubSet.this.remove(data[lastReturned]);
// if(lastReturned < index)
// index--;
// lastReturned = -1;
// }
//
// #if TYPE_OBJECT
// @Override
// public void set(Object e) { throw new UnsupportedOperationException(); }
//
// @Override
// public void add(Object e) { throw new UnsupportedOperationException(); }
//
// #else
// @Override
// public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
//
// @Override
// public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
//
// #endif
// @Override
// public int skip(int amount) {
// if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
// int steps = Math.min(amount, (size() - 1) - index);
// index += steps;
// 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;
// return steps;
// }
// }
// }
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index; int index;
int lastReturned = -1; int lastReturned = -1;
@@ -924,8 +597,8 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = index; --index;
return data[index--]; return data[(lastReturned = index)];
} }
@Override @Override
@@ -964,8 +637,9 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
@Override @Override
public int skip(int amount) { public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (size() - 1) - index); int steps = Math.min(amount, size() - index);
index += steps; index += steps;
if(steps > 0) lastReturned = Math.min(index-1, size()-1);
return steps; return steps;
} }
@@ -974,6 +648,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
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);
return steps; return steps;
} }
} }
@@ -9,6 +9,9 @@ import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
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;
@@ -16,11 +19,17 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
#if !TYPE_OBJECT
import speiger.src.collections.objects.utils.ObjectArrays;
#endif
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
@@ -323,6 +332,17 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int count = 0;
int index = firstIndex;
while(index != -1) {
action.accept(count++, keys[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -338,7 +358,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return true; if(filter.test(keys[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -349,7 +369,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return false; if(filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -360,7 +380,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(!filter.TEST_VALUE(keys[index])) return false; if(!filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -415,7 +435,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return keys[index]; if(filter.test(keys[index])) return keys[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
@@ -427,7 +447,7 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) result++; if(filter.test(keys[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -443,6 +463,41 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
return new SetIterator(fromElement); return new SetIterator(fromElement);
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = keys[index];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
obj[i] = KEY_TO_OBJ(keys[index]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = (E)KEY_TO_OBJ(keys[index]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public IMMUTABLE_HASH_SET KEY_GENERIC_TYPE copy() { public IMMUTABLE_HASH_SET KEY_GENERIC_TYPE copy() {
IMMUTABLE_HASH_SET KEY_GENERIC_TYPE set = new IMMUTABLE_HASH_SETBRACES(); IMMUTABLE_HASH_SET KEY_GENERIC_TYPE set = new IMMUTABLE_HASH_SETBRACES();
@@ -502,6 +557,30 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
} }
} }
@Override
public int skip(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result;
return result;
}
@Override
public int back(int amount) {
int result = 0;
while(previous != -1 && result != amount) {
current = next = previous;
previous = (int)(links[current] >> 32);
result++;
}
if(index >= 0) index-=result;
return result;
}
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != -1; return next != -1;
@@ -530,9 +609,8 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@@ -540,9 +618,8 @@ public class IMMUTABLE_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERI
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = next; current = previous = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current;
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; return keys[current];
} }
@@ -9,6 +9,9 @@ import java.util.Objects;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -20,8 +23,12 @@ import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.utils.STRATEGY; import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
@@ -123,7 +130,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
* @throws IllegalStateException if offset and length causes to step outside of the arrays range * @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/ */
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(length < 0 ? 0 : length, strategy); this(length, strategy);
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
@@ -237,6 +244,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
} }
containsNull = true; containsNull = true;
onNodeAdded(nullIndex); onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex);
} }
else { else {
int pos = HashUtil.mix(strategy.hashCode(o)) & mask; int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
@@ -249,6 +257,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
} }
keys[pos] = o; keys[pos] = o;
onNodeAdded(pos); onNodeAdded(pos);
moveToFirstIndex(pos);
} }
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor)); if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return true; return true;
@@ -282,7 +291,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public boolean moveToFirst(KEY_TYPE o) { public boolean moveToFirst(KEY_TYPE o) {
if(strategy.equals(FIRST_KEY(), o)) return false; if(isEmpty() || strategy.equals(FIRST_KEY(), o)) return false;
if(strategy.equals(o, EMPTY_KEY_VALUE)) { if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex);
@@ -304,7 +313,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public boolean moveToLast(KEY_TYPE o) { public boolean moveToLast(KEY_TYPE o) {
if(strategy.equals(LAST_KEY(), o)) return false; if(isEmpty() || strategy.equals(LAST_KEY(), o)) return false;
if(strategy.equals(o, EMPTY_KEY_VALUE)) { if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) { if(containsNull) {
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex);
@@ -370,8 +379,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
public KEY_TYPE POLL_FIRST_KEY() { public KEY_TYPE POLL_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = firstIndex; int pos = firstIndex;
firstIndex = (int)links[pos]; onNodeRemoved(pos);
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
KEY_TYPE result = keys[pos]; KEY_TYPE result = keys[pos];
size--; size--;
if(strategy.equals(result, EMPTY_KEY_VALUE)) { if(strategy.equals(result, EMPTY_KEY_VALUE)) {
@@ -393,8 +401,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
public KEY_TYPE POLL_LAST_KEY() { public KEY_TYPE POLL_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = lastIndex; int pos = lastIndex;
lastIndex = (int)(links[pos] >>> 32); onNodeRemoved(pos);
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
KEY_TYPE result = keys[pos]; KEY_TYPE result = keys[pos];
size--; size--;
if(strategy.equals(result, EMPTY_KEY_VALUE)) { if(strategy.equals(result, EMPTY_KEY_VALUE)) {
@@ -508,7 +515,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public void clearAndTrim(int size) { public void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= nullIndex) {
clear(); clear();
return; return;
} }
@@ -522,6 +529,41 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
containsNull = false; containsNull = false;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = keys[index];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
obj[i] = KEY_TO_OBJ(keys[index]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = (E)KEY_TO_OBJ(keys[index]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -532,6 +574,17 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int count = 0;
int index = firstIndex;
while(index != -1) {
action.accept(count++, keys[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -547,7 +600,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return true; if(filter.test(keys[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -558,7 +611,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return false; if(filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -569,7 +622,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(!filter.TEST_VALUE(keys[index])) return false; if(!filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -624,7 +677,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return keys[index]; if(filter.test(keys[index])) return keys[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
@@ -636,7 +689,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) result++; if(filter.test(keys[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -715,6 +768,30 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
return previous != -1; return previous != -1;
} }
@Override
public int skip(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result;
return result;
}
@Override
public int back(int amount) {
int result = 0;
while(previous != -1 && result != amount) {
current = next = previous;
previous = (int)(links[current] >> 32);
result++;
}
if(index >= 0) index-=result;
return result;
}
@Override @Override
public int nextIndex() { public int nextIndex() {
ensureIndexKnown(); ensureIndexKnown();
@@ -773,9 +850,8 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@@ -783,9 +859,8 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = next; current = previous = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current;
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; return keys[current];
} }
@@ -9,6 +9,9 @@ import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#endif #endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
@@ -18,13 +21,17 @@ import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@@ -110,7 +117,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
* @throws IllegalStateException if offset and length causes to step outside of the arrays range * @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/ */
public LINKED_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor) { public LINKED_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor) {
this(length < 0 ? 0 : length); this(length);
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
@@ -208,6 +215,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
} }
containsNull = true; containsNull = true;
onNodeAdded(nullIndex); onNodeAdded(nullIndex);
moveToFirstIndex(nullIndex);
} }
else { else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask; int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
@@ -220,6 +228,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
} }
keys[pos] = o; keys[pos] = o;
onNodeAdded(pos); onNodeAdded(pos);
moveToFirstIndex(pos);
} }
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor)); if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return true; return true;
@@ -253,7 +262,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public boolean moveToFirst(KEY_TYPE o) { public boolean moveToFirst(KEY_TYPE o) {
if(KEY_EQUALS(FIRST_KEY(), o)) return false; if(isEmpty() || KEY_EQUALS(FIRST_KEY(), o)) return false;
if(KEY_EQUALS_NULL(o)) { if(KEY_EQUALS_NULL(o)) {
if(containsNull) { if(containsNull) {
moveToFirstIndex(nullIndex); moveToFirstIndex(nullIndex);
@@ -275,7 +284,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public boolean moveToLast(KEY_TYPE o) { public boolean moveToLast(KEY_TYPE o) {
if(KEY_EQUALS(LAST_KEY(), o)) return false; if(isEmpty() || KEY_EQUALS(LAST_KEY(), o)) return false;
if(KEY_EQUALS_NULL(o)) { if(KEY_EQUALS_NULL(o)) {
if(containsNull) { if(containsNull) {
moveToLastIndex(nullIndex); moveToLastIndex(nullIndex);
@@ -341,8 +350,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
public KEY_TYPE POLL_FIRST_KEY() { public KEY_TYPE POLL_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = firstIndex; int pos = firstIndex;
firstIndex = (int)links[pos]; onNodeRemoved(pos);
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
KEY_TYPE result = keys[pos]; KEY_TYPE result = keys[pos];
size--; size--;
if(KEY_EQUALS_NULL(result)) { if(KEY_EQUALS_NULL(result)) {
@@ -364,8 +372,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
public KEY_TYPE POLL_LAST_KEY() { public KEY_TYPE POLL_LAST_KEY() {
if(size == 0) throw new NoSuchElementException(); if(size == 0) throw new NoSuchElementException();
int pos = lastIndex; int pos = lastIndex;
lastIndex = (int)(links[pos] >>> 32); onNodeRemoved(pos);
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
KEY_TYPE result = keys[pos]; KEY_TYPE result = keys[pos];
size--; size--;
if(KEY_EQUALS_NULL(result)) { if(KEY_EQUALS_NULL(result)) {
@@ -377,6 +384,41 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
return result; return result;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = keys[index];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
obj[i] = KEY_TO_OBJ(keys[index]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
for(int i = 0, index = firstIndex;index != -1;i++,index = (int)links[index]) {
a[i] = (E)KEY_TO_OBJ(keys[index]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -387,6 +429,17 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int count = 0;
int index = firstIndex;
while(index != -1) {
action.accept(count++, keys[index]);
index = (int)links[index];
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -402,7 +455,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return true; if(filter.test(keys[index])) return true;
index = (int)links[index]; index = (int)links[index];
} }
return false; return false;
@@ -413,7 +466,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return false; if(filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -424,7 +477,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(!filter.TEST_VALUE(keys[index])) return false; if(!filter.test(keys[index])) return false;
index = (int)links[index]; index = (int)links[index];
} }
return true; return true;
@@ -479,7 +532,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) return keys[index]; if(filter.test(keys[index])) return keys[index];
index = (int)links[index]; index = (int)links[index];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
@@ -491,7 +544,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
int result = 0; int result = 0;
int index = firstIndex; int index = firstIndex;
while(index != -1) { while(index != -1) {
if(filter.TEST_VALUE(keys[index])) result++; if(filter.test(keys[index])) result++;
index = (int)links[index]; index = (int)links[index];
} }
return result; return result;
@@ -599,7 +652,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public void clearAndTrim(int size) { public void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= nullIndex) {
clear(); clear();
return; return;
} }
@@ -676,6 +729,30 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
} }
} }
@Override
public int skip(int amount) {
int result = 0;
while(next != -1 && result != amount) {
current = previous = next;
next = (int)(links[current]);
result++;
}
if(index >= 0) index+=result;
return result;
}
@Override
public int back(int amount) {
int result = 0;
while(previous != -1 && result != amount) {
current = next = previous;
previous = (int)(links[current] >> 32);
result++;
}
if(index >= 0) index-=result;
return result;
}
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return next != -1; return next != -1;
@@ -744,9 +821,8 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
current = previous; current = next = previous;
previous = (int)(links[current] >> 32); previous = (int)(links[current] >> 32);
next = current;
if(index >= 0) index--; if(index >= 0) index--;
return keys[current]; return keys[current];
} }
@@ -754,9 +830,8 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
current = next; current = previous = next;
next = (int)(links[current]); next = (int)(links[current]);
previous = current;
if(index >= 0) index++; if(index >= 0) index++;
return keys[current]; return keys[current];
} }
@@ -3,9 +3,13 @@ package speiger.src.collections.PACKAGE.sets;
import java.util.NavigableSet; import java.util.NavigableSet;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SETS;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
#if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS;
#endif
/** /**
* A Type Specific Navigable Set interface with a couple helper methods * A Type Specific Navigable Set interface with a couple helper methods
@@ -119,7 +123,7 @@ public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE copy(); public NAVIGABLE_SET KEY_GENERIC_TYPE copy();
#if !TYPE_BOOLEAN #if SETS_FEATURE
/** /**
* Creates a Wrapped NavigableSet that is Synchronized * Creates a Wrapped NavigableSet that is Synchronized
* @return a new NavigableSet that is synchronized * @return a new NavigableSet that is synchronized
@@ -143,6 +147,7 @@ public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>
public default NAVIGABLE_SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); } public default NAVIGABLE_SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); }
#endif #endif
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
@@ -150,6 +155,7 @@ public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
@Deprecated @Deprecated
@@ -10,19 +10,24 @@ import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#endif #endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#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;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.utils.STRATEGY; import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
@@ -373,10 +378,10 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
#endif #endif
@Override @Override
public boolean trim(int size) { public boolean trim(int size) {
int newSize = HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(newSize >= nullIndex || size >= Math.min((int)Math.ceil(newSize * loadFactor), newSize - 1)) return false; if(request >= nullIndex || this.size >= Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
try { try {
rehash(newSize); rehash(request);
} }
catch(OutOfMemoryError e) { return false; } catch(OutOfMemoryError e) { return false; }
return true; return true;
@@ -385,7 +390,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
@Override @Override
public void clearAndTrim(int size) { public void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= nullIndex) {
clear(); clear();
return; return;
} }
@@ -475,6 +480,44 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
return new SetIterator(); return new SetIterator();
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
if(containsNull) a[0] = EMPTY_KEY_VALUE;
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) a[index++] = keys[i];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
if(containsNull) obj[0] = KEY_TO_OBJ(EMPTY_KEY_VALUE);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) obj[index++] = KEY_TO_OBJ(keys[i]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
if(containsNull) a[0] = (E)KEY_TO_OBJ(EMPTY_KEY_VALUE);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) a[index++] = (E)KEY_TO_OBJ(keys[i]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public CUSTOM_HASH_SET KEY_GENERIC_TYPE copy() { public CUSTOM_HASH_SET KEY_GENERIC_TYPE copy() {
CUSTOM_HASH_SET KEY_GENERIC_TYPE set = new CUSTOM_HASH_SETBRACES(0, loadFactor, strategy); CUSTOM_HASH_SET KEY_GENERIC_TYPE set = new CUSTOM_HASH_SETBRACES(0, loadFactor, strategy);
@@ -503,6 +546,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return; if(size() <= 0) return;
if(containsNull) action.accept(keys[nullIndex]); if(containsNull) action.accept(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
@@ -510,6 +554,16 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
if(containsNull) action.accept(0, keys[nullIndex]);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(index++, keys[i]);
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -524,9 +578,9 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return true; if(containsNull && filter.test(keys[nullIndex])) 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) && filter.TEST_VALUE(keys[i])) return true; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return true;
} }
return false; return false;
} }
@@ -535,9 +589,9 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return false; if(containsNull && filter.test(keys[nullIndex])) 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) && filter.TEST_VALUE(keys[i])) return false; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -546,9 +600,9 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && !filter.TEST_VALUE(keys[nullIndex])) return false; if(containsNull && !filter.test(keys[nullIndex])) 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) && !filter.TEST_VALUE(keys[i])) return false; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && !filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -589,7 +643,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
state = keys[nullIndex]; state = keys[nullIndex];
empty = false; empty = false;
} }
for(int i = 0;i<size;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;
@@ -605,9 +659,9 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return EMPTY_VALUE;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return keys[nullIndex]; if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex];
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.TEST_VALUE(keys[i])) return keys[i]; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) return keys[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -617,9 +671,9 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
int result = 0; int result = 0;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) result++; if(containsNull && filter.test(keys[nullIndex])) 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) && filter.TEST_VALUE(keys[i])) result++; if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && filter.test(keys[i])) result++;
} }
return result; return result;
} }
@@ -630,7 +684,8 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
int lastReturned = -1; int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE; int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull; boolean returnNull = containsNull;
LIST KEY_GENERIC_TYPE wrapped = null; KEY_TYPE[] wrapped = null;
int wrappedIndex = 0;
@Override @Override
public boolean hasNext() { public boolean hasNext() {
@@ -642,7 +697,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
else { else {
while(true) { while(true) {
if(--pos < 0) { if(--pos < 0) {
if(wrapped == null || wrapped.size() <= -pos - 1) break; if(wrapped == null || wrappedIndex <= -pos - 1) break;
nextIndex = -pos - 1; nextIndex = -pos - 1;
break; break;
} }
@@ -662,7 +717,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
returnedPos = pos; returnedPos = pos;
if(nextIndex < 0){ if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE; lastReturned = Integer.MAX_VALUE;
KEY_TYPE value = wrapped.GET_KEY(nextIndex); KEY_TYPE value = wrapped[nextIndex];
nextIndex = Integer.MIN_VALUE; nextIndex = Integer.MIN_VALUE;
return value; return value;
} }
@@ -680,7 +735,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
} }
else if(returnedPos >= 0) shiftKeys(returnedPos); else if(returnedPos >= 0) shiftKeys(returnedPos);
else { else {
CUSTOM_HASH_SET.this.remove(wrapped.GET_KEY(-returnedPos - 1)); CUSTOM_HASH_SET.this.remove(wrapped[-returnedPos - 1]);
lastReturned = -1; lastReturned = -1;
return; return;
} }
@@ -702,12 +757,19 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break; if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask; startPos = ++startPos & mask;
} }
if(startPos < last) { if(startPos < last) addWrapper(keys[startPos]);
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
wrapped.add(keys[startPos]);
}
keys[last] = current; keys[last] = current;
} }
} }
private void addWrapper(KEY_TYPE value) {
if(wrapped == null) wrapped = NEW_KEY_ARRAY(2);
else if(wrappedIndex >= wrapped.length) {
KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2);
System.arraycopy(wrapped, 0, newArray, 0, wrapped.length);
wrapped = newArray;
}
wrapped[wrappedIndex++] = value;
}
} }
} }
@@ -10,18 +10,24 @@ import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#endif #endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#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;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
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
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
@@ -340,10 +346,10 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
#endif #endif
@Override @Override
public boolean trim(int size) { public boolean trim(int size) {
int newSize = HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(newSize >= nullIndex || size >= Math.min((int)Math.ceil(newSize * loadFactor), newSize - 1)) return false; if(request >= nullIndex || this.size >= Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
try { try {
rehash(newSize); rehash(request);
} }
catch(OutOfMemoryError e) { return false; } catch(OutOfMemoryError e) { return false; }
return true; return true;
@@ -352,7 +358,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
@Override @Override
public void clearAndTrim(int size) { public void clearAndTrim(int size) {
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
if(request >= size) { if(request >= nullIndex) {
clear(); clear();
return; return;
} }
@@ -364,6 +370,44 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
containsNull = false; containsNull = false;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
if(containsNull) a[0] = EMPTY_KEY_VALUE;
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) a[index++] = keys[i];
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
if(containsNull) obj[0] = KEY_TO_OBJ(EMPTY_KEY_VALUE);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) obj[index++] = KEY_TO_OBJ(keys[i]);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
if(containsNull) a[0] = (E)KEY_TO_OBJ(EMPTY_KEY_VALUE);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) a[index++] = (E)KEY_TO_OBJ(keys[i]);
}
if (a.length > size) a[size] = null;
return a;
}
@Override @Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
if(size() <= 0) return; if(size() <= 0) return;
@@ -373,6 +417,16 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(size() <= 0) return;
if(containsNull) action.accept(0, keys[nullIndex]);
for(int i = nullIndex-1, index = containsNull ? 1 : 0;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(index++, keys[i]);
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -387,9 +441,9 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return false; if(size() <= 0) return false;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return true; if(containsNull && filter.test(keys[nullIndex])) 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]) && filter.TEST_VALUE(keys[i])) return true; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return true;
} }
return false; return false;
} }
@@ -398,9 +452,9 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return false; if(containsNull && filter.test(keys[nullIndex])) 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]) && filter.TEST_VALUE(keys[i])) return false; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -409,9 +463,9 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return true; if(size() <= 0) return true;
if(containsNull && !filter.TEST_VALUE(keys[nullIndex])) return false; if(containsNull && !filter.test(keys[nullIndex])) 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]) && !filter.TEST_VALUE(keys[i])) return false; if(KEY_EQUALS_NOT_NULL(keys[i]) && !filter.test(keys[i])) return false;
} }
return true; return true;
} }
@@ -452,7 +506,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
state = keys[nullIndex]; state = keys[nullIndex];
empty = false; empty = false;
} }
for(int i = 0;i<size;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;
@@ -468,9 +522,9 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return EMPTY_VALUE; if(size() <= 0) return EMPTY_VALUE;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) return keys[nullIndex]; if(containsNull && filter.test(keys[nullIndex])) return keys[nullIndex];
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.TEST_VALUE(keys[i])) return keys[i]; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) return keys[i];
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -480,9 +534,9 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
if(size() <= 0) return 0; if(size() <= 0) return 0;
int result = 0; int result = 0;
if(containsNull && filter.TEST_VALUE(keys[nullIndex])) result++; if(containsNull && filter.test(keys[nullIndex])) result++;
for(int i = nullIndex-1;i>=0;i--) { for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.TEST_VALUE(keys[i])) result++; if(KEY_EQUALS_NOT_NULL(keys[i]) && filter.test(keys[i])) result++;
} }
return result; return result;
} }
@@ -597,7 +651,8 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
int lastReturned = -1; int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE; int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull; boolean returnNull = containsNull;
LIST KEY_GENERIC_TYPE wrapped = null; KEY_TYPE[] wrapped = null;
int wrappedIndex = 0;
@Override @Override
public boolean hasNext() { public boolean hasNext() {
@@ -610,7 +665,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
{ {
while(true) { while(true) {
if(--pos < 0) { if(--pos < 0) {
if(wrapped == null || wrapped.size() <= -pos - 1) break; if(wrapped == null || wrappedIndex <= -pos - 1) break;
nextIndex = -pos - 1; nextIndex = -pos - 1;
break; break;
} }
@@ -630,7 +685,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
returnedPos = pos; returnedPos = pos;
if(nextIndex < 0){ if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE; lastReturned = Integer.MAX_VALUE;
KEY_TYPE value = wrapped.GET_KEY(nextIndex); KEY_TYPE value = wrapped[nextIndex];
nextIndex = Integer.MIN_VALUE; nextIndex = Integer.MIN_VALUE;
return value; return value;
} }
@@ -648,7 +703,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
} }
else if(returnedPos >= 0) shiftKeys(returnedPos); else if(returnedPos >= 0) shiftKeys(returnedPos);
else { else {
HASH_SET.this.remove(wrapped.GET_KEY(-returnedPos - 1)); HASH_SET.this.remove(wrapped[-returnedPos - 1]);
lastReturned = -1; lastReturned = -1;
return; return;
} }
@@ -670,12 +725,19 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break; if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask; startPos = ++startPos & mask;
} }
if(startPos < last) { if(startPos < last) addWrapper(keys[startPos]);
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
wrapped.add(keys[startPos]);
}
keys[last] = current; keys[last] = current;
} }
} }
private void addWrapper(KEY_TYPE value) {
if(wrapped == null) wrapped = NEW_KEY_ARRAY(2);
else if(wrappedIndex >= wrapped.length) {
KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2);
System.arraycopy(wrapped, 0, newArray, 0, wrapped.length);
wrapped = newArray;
}
wrapped[wrappedIndex++] = value;
}
} }
} }
@@ -1,9 +1,13 @@
package speiger.src.collections.PACKAGE.sets; package speiger.src.collections.PACKAGE.sets;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
import speiger.src.collections.PACKAGE.utils.SETS;
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
#if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS;
#endif
/** /**
* A Special Set Interface giving Access to some really usefull functions * A Special Set Interface giving Access to some really usefull functions
@@ -59,6 +63,7 @@ public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
*/ */
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement); public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement);
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
@@ -66,6 +71,7 @@ public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
/** /**
* A method to get the first element in the set * A method to get the first element in the set
* @return first element in the set * @return first element in the set
@@ -87,7 +93,7 @@ public interface ORDERED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE
*/ */
public KEY_TYPE POLL_LAST_KEY(); public KEY_TYPE POLL_LAST_KEY();
#if !TYPE_BOOLEAN #if SETS_FEATURE
/** /**
* Creates a Wrapped OrderedSet that is Synchronized * Creates a Wrapped OrderedSet that is Synchronized
* @return a new OrderedSet that is synchronized * @return a new OrderedSet that is synchronized
@@ -10,16 +10,24 @@ import java.util.function.BiFunction;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_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.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
@@ -353,6 +361,14 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
action.accept(index++, entry.key);
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -364,7 +380,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.TEST_VALUE(entry.key)) return true; if(filter.test(entry.key)) return true;
} }
return false; return false;
} }
@@ -373,7 +389,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.TEST_VALUE(entry.key)) return false; if(filter.test(entry.key)) return false;
} }
return true; return true;
} }
@@ -382,7 +398,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(!filter.TEST_VALUE(entry.key)) return false; if(!filter.test(entry.key)) return false;
} }
return true; return true;
} }
@@ -430,7 +446,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.TEST_VALUE(entry.key)) return entry.key; if(filter.test(entry.key)) return entry.key;
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -440,7 +456,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
if(filter.TEST_VALUE(entry.key)) result++; if(filter.test(entry.key)) result++;
} }
return result; return result;
} }
@@ -637,6 +653,44 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
tree = null; tree = null;
} }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
a[index++] = entry.key;
}
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
@Override
@Deprecated
public Object[] toArray() {
if(isEmpty()) return ObjectArrays.EMPTY_ARRAY;
Object[] obj = new Object[size()];
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
obj[index++] = KEY_TO_OBJ(entry.key);
}
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size()];
else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size());
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
a[index++] = (E)KEY_TO_OBJ(entry.key);
}
if (a.length > size) a[size] = null;
return a;
}
public RB_TREE_SET KEY_GENERIC_TYPE copy() { public RB_TREE_SET KEY_GENERIC_TYPE copy() {
RB_TREE_SET KEY_GENERIC_TYPE set = new RB_TREE_SETBRACES(); RB_TREE_SET KEY_GENERIC_TYPE set = new RB_TREE_SETBRACES();
set.size = size; set.size = size;
@@ -949,15 +1003,11 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; } public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; }
public KEY_TYPE getDefaultMaxValue() { return super.getDefaultMinValue(); }
public KEY_TYPE getDefaultMinValue() { return super.getDefaultMaxValue(); }
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) {
if(!inRange(fromElement, fromInclusive)) throw new IllegalArgumentException("fromElement out of range"); if(!inRange(fromElement, fromInclusive)) throw new IllegalArgumentException("fromElement out of range");
if(!inRange(toElement, toInclusive)) throw new IllegalArgumentException("toElement out of range"); if(!inRange(toElement, toInclusive)) throw new IllegalArgumentException("toElement out of range");
return new DescendingSubSetBRACES(set, false, fromElement, fromInclusive, false, toElement, toInclusive); return new DescendingSubSetBRACES(set, false, toElement, toInclusive, false, fromElement, fromInclusive);
} }
@Override @Override
@@ -1034,21 +1084,15 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public void setDefaultMaxValue(KEY_TYPE value) { set.setDefaultMaxValue(value); } public void setDefaultMaxValue(KEY_TYPE value) { set.setDefaultMaxValue(value); }
@Override @Override
public KEY_TYPE getDefaultMaxValue() { return set.getDefaultMaxValue(); } public KEY_TYPE getDefaultMaxValue() { return set.getDefaultMaxValue(); }
@Override @Override
public void setDefaultMinValue(KEY_TYPE value) { set.setDefaultMinValue(value); } public void setDefaultMinValue(KEY_TYPE value) { set.setDefaultMinValue(value); }
@Override @Override
public KEY_TYPE getDefaultMinValue() { return set.getDefaultMinValue(); } public KEY_TYPE getDefaultMinValue() { return set.getDefaultMinValue(); }
#else #else
public KEY_TYPE getDefaultMaxValue() { return null; } public KEY_TYPE getDefaultMaxValue() { return null; }
public KEY_TYPE getDefaultMinValue() { return null; } public KEY_TYPE getDefaultMinValue() { return null; }
#endif #endif
@Override @Override
public abstract BI_ITERATOR KEY_GENERIC_TYPE iterator(); public abstract BI_ITERATOR KEY_GENERIC_TYPE iterator();
@@ -1263,6 +1307,15 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
} }
} }
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
int index = 0;
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
action.accept(index++, entry.key);
}
}
@Override @Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) { public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
@@ -1274,7 +1327,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.TEST_VALUE(entry.key)) return true; if(filter.test(entry.key)) return true;
} }
return false; return false;
} }
@@ -1283,7 +1336,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.TEST_VALUE(entry.key)) return false; if(filter.test(entry.key)) return false;
} }
return true; return true;
} }
@@ -1292,7 +1345,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(!filter.TEST_VALUE(entry.key)) return false; if(!filter.test(entry.key)) return false;
} }
return true; return true;
} }
@@ -1340,7 +1393,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.TEST_VALUE(entry.key)) return entry.key; if(filter.test(entry.key)) return entry.key;
} }
return EMPTY_VALUE; return EMPTY_VALUE;
} }
@@ -1350,7 +1403,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
Objects.requireNonNull(filter); Objects.requireNonNull(filter);
int result = 0; int result = 0;
for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) {
if(filter.TEST_VALUE(entry.key)) result++; if(filter.test(entry.key)) result++;
} }
return result; return result;
} }
@@ -1359,6 +1412,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE lastReturned;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE previous;
boolean forwards = false; boolean forwards = false;
boolean unboundForwardFence; boolean unboundForwardFence;
boolean unboundBackwardFence; boolean unboundBackwardFence;
@@ -1368,6 +1422,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public AscendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence) public AscendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence)
{ {
next = first; next = first;
previous = first == null ? null : first.previous();
this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key; this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key;
this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key; this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key;
unboundForwardFence = forwardFence == null; unboundForwardFence = forwardFence == null;
@@ -1383,6 +1438,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = next; lastReturned = next;
previous = next;
KEY_TYPE result = next.key; KEY_TYPE result = next.key;
next = next.next(); next = next.next();
forwards = true; forwards = true;
@@ -1391,15 +1447,16 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return next != null && (unboundBackwardFence || next.key != backwardFence); return previous != null && (unboundBackwardFence || previous.key != backwardFence);
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next; lastReturned = previous;
KEY_TYPE result = next.key; next = previous;
next = next.previous(); KEY_TYPE result = previous.key;
previous = previous.previous();
forwards = false; forwards = false;
return result; return result;
} }
@@ -1407,6 +1464,8 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public void remove() { public void remove() {
if(lastReturned == null) throw new IllegalStateException(); if(lastReturned == null) throw new IllegalStateException();
if(previous == lastReturned) previous = previous.previous();
if(next == lastReturned) next = next.next();
if(forwards && lastReturned.needsSuccessor()) next = lastReturned; if(forwards && lastReturned.needsSuccessor()) next = lastReturned;
set.removeNode(lastReturned); set.removeNode(lastReturned);
lastReturned = null; lastReturned = null;
@@ -1417,6 +1476,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE lastReturned;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE previous;
boolean forwards = false; boolean forwards = false;
boolean unboundForwardFence; boolean unboundForwardFence;
boolean unboundBackwardFence; boolean unboundBackwardFence;
@@ -1426,6 +1486,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public DescendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence) public DescendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence)
{ {
next = first; next = first;
previous = first == null ? null : first.next();
this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key; this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key;
this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key; this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key;
unboundForwardFence = forwardFence == null; unboundForwardFence = forwardFence == null;
@@ -1441,6 +1502,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = next; lastReturned = next;
previous = next;
KEY_TYPE result = next.key; KEY_TYPE result = next.key;
next = next.previous(); next = next.previous();
forwards = false; forwards = false;
@@ -1449,15 +1511,16 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return next != null && (unboundBackwardFence || next.key != backwardFence); return previous != null && (unboundBackwardFence || previous.key != backwardFence);
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next; lastReturned = previous;
KEY_TYPE result = next.key; next = previous;
next = next.next(); KEY_TYPE result = previous.key;
previous = previous.next();
forwards = true; forwards = true;
return result; return result;
} }
@@ -1465,6 +1528,8 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public void remove() { public void remove() {
if(lastReturned == null) throw new IllegalStateException(); if(lastReturned == null) throw new IllegalStateException();
if(previous == lastReturned) previous = previous.next();
if(next == lastReturned) next = next.previous();
if(forwards && lastReturned.needsSuccessor()) next = lastReturned; if(forwards && lastReturned.needsSuccessor()) next = lastReturned;
set.removeNode(lastReturned); set.removeNode(lastReturned);
lastReturned = null; lastReturned = null;
@@ -1476,11 +1541,13 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE lastReturned;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE previous;
boolean forwards = false; boolean forwards = false;
public AscendingSetIterator(Entry KEY_GENERIC_TYPE first) public AscendingSetIterator(Entry KEY_GENERIC_TYPE first)
{ {
next = first; next = first;
previous = first == null ? null : first.previous();
} }
@Override @Override
@@ -1492,6 +1559,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = next; lastReturned = next;
previous = next;
KEY_TYPE result = next.key; KEY_TYPE result = next.key;
next = next.next(); next = next.next();
forwards = true; forwards = true;
@@ -1500,15 +1568,16 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return next != null; return previous != null;
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next; lastReturned = previous;
KEY_TYPE result = next.key; next = previous;
next = next.previous(); KEY_TYPE result = previous.key;
previous = previous.previous();
forwards = false; forwards = false;
return result; return result;
} }
@@ -1516,6 +1585,8 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public void remove() { public void remove() {
if(lastReturned == null) throw new IllegalStateException(); if(lastReturned == null) throw new IllegalStateException();
if(lastReturned == previous) previous = previous.previous();
if(lastReturned == next) next = next.next();
if(forwards && lastReturned.needsSuccessor()) next = lastReturned; if(forwards && lastReturned.needsSuccessor()) next = lastReturned;
removeNode(lastReturned); removeNode(lastReturned);
lastReturned = null; lastReturned = null;
@@ -1526,11 +1597,13 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE lastReturned;
Entry KEY_GENERIC_TYPE next; Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE previous;
boolean forwards = false; boolean forwards = false;
public DescendingSetIterator(Entry KEY_GENERIC_TYPE first) public DescendingSetIterator(Entry KEY_GENERIC_TYPE first)
{ {
next = first; next = first;
previous = first == null ? null : first.next();
} }
@Override @Override
@@ -1542,6 +1615,7 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException(); if(!hasNext()) throw new NoSuchElementException();
lastReturned = next; lastReturned = next;
previous = next;
KEY_TYPE result = next.key; KEY_TYPE result = next.key;
next = next.previous(); next = next.previous();
forwards = false; forwards = false;
@@ -1550,15 +1624,16 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() {
return next != null; return previous != null;
} }
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException(); if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = next; lastReturned = previous;
KEY_TYPE result = next.key; next = previous;
next = next.next(); KEY_TYPE result = previous.key;
previous = previous.next();
forwards = true; forwards = true;
return result; return result;
} }
@@ -1566,6 +1641,8 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
@Override @Override
public void remove() { public void remove() {
if(lastReturned == null) throw new IllegalStateException(); if(lastReturned == null) throw new IllegalStateException();
if(lastReturned == previous) previous = previous.next();
if(lastReturned == next) next = next.previous();
if(forwards && lastReturned.needsSuccessor()) next = lastReturned; if(forwards && lastReturned.needsSuccessor()) next = lastReturned;
removeNode(lastReturned); removeNode(lastReturned);
lastReturned = null; lastReturned = null;
@@ -4,11 +4,13 @@ import java.util.Set;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#if !TYPE_BOOLEAN import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
#if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS; import speiger.src.collections.PACKAGE.utils.SETS;
#endif #endif
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
/** /**
@@ -64,7 +66,7 @@ public interface SET KEY_GENERIC_TYPE extends Set<CLASS_TYPE>, COLLECTION KEY_GE
public KEY_TYPE addOrGet(KEY_TYPE o); public KEY_TYPE addOrGet(KEY_TYPE o);
#endif #endif
#if !TYPE_BOOLEAN #if SETS_FEATURE
/** /**
* Creates a Wrapped Set that is Synchronized * Creates a Wrapped Set that is Synchronized
* @return a new Set that is synchronized * @return a new Set that is synchronized
@@ -88,10 +90,12 @@ public interface SET KEY_GENERIC_TYPE extends Set<CLASS_TYPE>, COLLECTION KEY_GE
public default SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); } public default SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); }
#endif #endif
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
*/ */
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
} }
@@ -3,14 +3,20 @@ package speiger.src.collections.PACKAGE.sets;
import java.util.SortedSet; import java.util.SortedSet;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR;
#endif
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.Comparator; import java.util.Comparator;
#else #else
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
#if SETS_FEATURE
import speiger.src.collections.PACKAGE.utils.SETS; import speiger.src.collections.PACKAGE.utils.SETS;
#endif
#if SPLIT_ITERATOR_FEATURE
import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS;
#endif
/** /**
* A Type Specific SortedSet implementation to reduce boxing/unboxing * A Type Specific SortedSet implementation to reduce boxing/unboxing
@@ -41,7 +47,7 @@ public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, Sorte
*/ */
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement); public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement);
#if !TYPE_BOOLEAN #if SETS_FEATURE
/** /**
* Creates a Wrapped SortedSet that is Synchronized * Creates a Wrapped SortedSet that is Synchronized
* @return a new SortedSet that is synchronized * @return a new SortedSet that is synchronized
@@ -65,6 +71,7 @@ public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, Sorte
public default SORTED_SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); } public default SORTED_SET KEY_GENERIC_TYPE unmodifiable() { return SETS.unmodifiable(this); }
#endif #endif
#if SPLIT_ITERATOR_FEATURE
/** /**
* A Type Specific Type Splititerator to reduce boxing/unboxing * A Type Specific Type Splititerator to reduce boxing/unboxing
* @return type specific splititerator * @return type specific splititerator
@@ -72,6 +79,7 @@ public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, Sorte
@Override @Override
default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); } default SPLIT_ITERATOR KEY_GENERIC_TYPE spliterator() { return SPLIT_ITERATORS.createSplititerator(this, 0); }
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
/** /**
* A Type Specific SubSet method to reduce boxing/unboxing * A Type Specific SubSet method to reduce boxing/unboxing
@@ -1,18 +1,21 @@
package speiger.src.collections.PACKAGE.utils; package speiger.src.collections.PACKAGE.utils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Random; #if JAVA_VERSION>=17
import java.util.random.RANDOM;
#else
import java.util.RANDOM;
#endif
import java.util.concurrent.RecursiveAction; import java.util.concurrent.RecursiveAction;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#else #else
import java.util.Comparator; import java.util.Comparator;
import java.util.function.IntFunction;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
@@ -132,10 +135,41 @@ public class ARRAYS
* @return array with all requested elements of the iterator * @return array with all requested elements of the iterator
*/ */
public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max) { public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max) {
ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE list = COLLECTIONS.wrapper();
ITERATORS.pour(iter, list, max); ITERATORS.pour(iter, list, max);
return list.TO_ARRAY(NEW_KEY_ARRAY(list.size())); return list.TO_ARRAY(NEW_KEY_ARRAY(list.size()));
} }
#if TYPE_OBJECT
/**
* A Helper function that pours all elements of a iterator into a Array
* @param iter the elements that should be gathered.
* @ArrayType(T)
* @ArrayType(E)
* @param action that is creating the Array to be poured into
* @return array with all elements of the iterator
*/
public static <T, E> E[] pour(ITERATOR KEY_GENERIC_TYPE iter, IntFunction<E[]> action) {
return pour(iter, Integer.MAX_VALUE, action);
}
/**
* A Helper function that pours all elements of a iterator into a Array
* @param iter the elements that should be gathered.
* @param max how many elements should be added
* @param action that is creating the Array to be poured into
* @ArrayType(T)
* @ArrayType(E)
* @return array with all requested elements of the iterator
*/
public static <T, E> E[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max, IntFunction<E[]> action) {
COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE list = COLLECTIONS.wrapper();
ITERATORS.pour(iter, list, max);
return list.TO_ARRAY(action.apply(list.size()));
}
#endif
/** /**
* Method to validate if the current value is the lowest value in the heap * Method to validate if the current value is the lowest value in the heap
* @param data the current heap. * @param data the current heap.
@@ -262,7 +296,7 @@ public class ARRAYS
* @ArrayType(T) * @ArrayType(T)
* @return the provided sorted array * @return the provided sorted array
*/ */
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, Random random) { public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, RANDOM random) {
for(int i = array.length-1; i>=0;i--) { for(int i = array.length-1; i>=0;i--) {
int p = random.nextInt(i + 1); int p = random.nextInt(i + 1);
KEY_TYPE t = array[i]; KEY_TYPE t = array[i];
@@ -280,7 +314,7 @@ public class ARRAYS
* @ArrayType(T) * @ArrayType(T)
* @return the provided sorted array * @return the provided sorted array
*/ */
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length, Random random) { public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length, RANDOM random) {
return shuffle(array, 0, length, random); return shuffle(array, 0, length, random);
} }
@@ -293,7 +327,7 @@ public class ARRAYS
* @ArrayType(T) * @ArrayType(T)
* @return the provided sorted array * @return the provided sorted array
*/ */
public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length, Random random) { public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length, RANDOM random) {
for(int i = length-1; i>=0;i--) { for(int i = length-1; i>=0;i--) {
int p = offset + random.nextInt(i + 1); int p = offset + random.nextInt(i + 1);
KEY_TYPE t = array[offset+i]; KEY_TYPE t = array[offset+i];
@@ -348,9 +382,11 @@ public class ARRAYS
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @ArrayType(T) * @ArrayType(T)
* @param comp the Comparator that decides the sorting order * @param comp the Comparator that decides the sorting order
* @return input array.
*/ */
public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES KEY_TYPE[] stableSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
stableSort(array, 0, array.length, comp); stableSort(array, 0, array.length, comp);
return array;
} }
/** /**
@@ -386,9 +422,11 @@ public class ARRAYS
* Stable sort referres to Mergesort or Insertionsort * Stable sort referres to Mergesort or Insertionsort
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES KEY_TYPE[] stableSort(KEY_TYPE[] array) {
stableSort(array, 0, array.length); stableSort(array, 0, array.length);
return array;
} }
/** /**
@@ -423,9 +461,11 @@ public class ARRAYS
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order * @param comp the Comparator that decides the sorting order
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES KEY_TYPE[] unstableSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
unstableSort(array, 0, array.length, comp); unstableSort(array, 0, array.length, comp);
return array;
} }
/** /**
@@ -461,9 +501,11 @@ public class ARRAYS
* Unstable sort referres to QuickSort or SelectionSort * Unstable sort referres to QuickSort or SelectionSort
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES KEY_TYPE[] unstableSort(KEY_TYPE[] array) {
unstableSort(array, 0, array.length); unstableSort(array, 0, array.length);
return array;
} }
/** /**
@@ -496,9 +538,11 @@ public class ARRAYS
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order * @param comp the Comparator that decides the sorting order
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES KEY_TYPE[] insertionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
insertionSort(array, 0, array.length, comp); insertionSort(array, 0, array.length, comp);
return array;
} }
/** /**
@@ -535,9 +579,11 @@ public class ARRAYS
* Sorts an array according to the natural ascending order using InsertionSort, * Sorts an array according to the natural ascending order using InsertionSort,
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES KEY_TYPE[] insertionSort(KEY_TYPE[] array) {
insertionSort(array, 0, array.length); insertionSort(array, 0, array.length);
return array;
} }
/** /**
@@ -573,9 +619,11 @@ public class ARRAYS
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order * @param comp the Comparator that decides the sorting order
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES KEY_TYPE[] selectionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
selectionSort(array, 0, array.length, comp); selectionSort(array, 0, array.length, comp);
return array;
} }
/** /**
@@ -617,9 +665,11 @@ public class ARRAYS
* Sorts an array according to the natural ascending order using Selection Sort, * Sorts an array according to the natural ascending order using Selection Sort,
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES KEY_TYPE[] selectionSort(KEY_TYPE[] array) {
selectionSort(array, 0, array.length); selectionSort(array, 0, array.length);
return array;
} }
/** /**
@@ -640,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++) {
@@ -661,9 +711,11 @@ public class ARRAYS
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order * @param comp the Comparator that decides the sorting order
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES KEY_TYPE[] mergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
mergeSort(array, null, 0, array.length, comp); mergeSort(array, null, 0, array.length, comp);
return array;
} }
/** /**
@@ -713,9 +765,11 @@ public class ARRAYS
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations * This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES KEY_TYPE[] mergeSort(KEY_TYPE[] array) {
mergeSort(array, null, 0, array.length); mergeSort(array, null, 0, array.length);
return array;
} }
/** /**
@@ -922,9 +976,11 @@ public class ARRAYS
* @author Speiger * @author Speiger
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES KEY_TYPE[] memFreeMergeSort(KEY_TYPE[] array) {
memFreeMergeSort(array, 0, array.length); memFreeMergeSort(array, 0, array.length);
return array;
} }
/** /**
@@ -1099,9 +1155,11 @@ public class ARRAYS
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @param comp the Comparator that decides the sorting order * @param comp the Comparator that decides the sorting order
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { public static GENERIC_KEY_BRACES KEY_TYPE[] quickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
quickSort(array, 0, array.length, comp); quickSort(array, 0, array.length, comp);
return array;
} }
/** /**
@@ -1157,9 +1215,11 @@ public class ARRAYS
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages12491265, 1993. * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages12491265, 1993.
* @param array the array that needs to be sorted * @param array the array that needs to be sorted
* @ArrayType(T) * @ArrayType(T)
* @return input array
*/ */
public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array) { public static GENERIC_KEY_BRACES KEY_TYPE[] quickSort(KEY_TYPE[] array) {
quickSort(array, 0, array.length); quickSort(array, 0, array.length);
return array;
} }
/** /**
@@ -12,35 +12,81 @@ import java.util.function.Consumer;
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 #else
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
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#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;
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
#if !TYPE_BOOLEAN
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.sets.LINKED_HASH_SET;
#endif #endif
#if !TYPE_BOOLEAN #if OBJECT_ASYNC_MODULE
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE
import speiger.src.collections.PACKAGE.lists.LIST;
#if ARRAY_LIST_FEATURE
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
#else if LINKED_LIST_FEATURE
import speiger.src.collections.PACKAGE.lists.LINKED_LIST;
#endif
#endif
#if !TYPE_BOOLEAN && OBJECT_ASYNC_MODULE
#if SET_MODULE
#if LINKED_SET_FEATURE || LINKED_CUSTOM_SET_FEATURE || SET_FEATURE || CUSTOM_SET_FEATURE || RB_TREE_SET_FEATURE || AVL_TREE_SET_FEATURE || ARRAY_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.SET;
#if LINKED_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.LINKED_HASH_SET;
#else if LINKED_CUSTOM_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.LINKED_CUSTOM_HASH_SET;
#else if SET_FEATURE
import speiger.src.collections.PACKAGE.sets.HASH_SET;
#else if CUSTOM_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.CUSTOM_HASH_SET;
#else if RB_TREE_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.RB_TREE_SET;
#else if AVL_TREE_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.AVL_TREE_SET;
#else if ARRAY_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.ARRAY_SET;
#endif
#endif
#endif
#endif
#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 #if !TYPE_OBJECT && OBJECT_ASYNC_MODULE
import speiger.src.collections.objects.utils.ObjectAsyncBuilder; 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 #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.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
@@ -113,6 +159,19 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return new ASYNC_BUILDERBRACES(ITERABLES.wrap(iterable)); return new ASYNC_BUILDERBRACES(ITERABLES.wrap(iterable));
} }
#if ARRAY_LIST_FEATURE
/**
* Helper function that automatically wraps a array into a AsyncBuilder since it forces this collections Iterable.
* @param values that should be wrapped
* @Type(T)
* @return a AsyncBuilder with the values wrapped
*/
public static GENERIC_KEY_BRACES ASYNC_BUILDER KEY_GENERIC_TYPE of(KEY_TYPE...values) {
return new ASYNC_BUILDERBRACES(ARRAY_LIST.wrap(values));
}
#endif
#if OBJECT_ASYNC_MODULE
/** /**
* Maps the elements to something else * Maps the elements to something else
* @param mapper the mapping function * @param mapper the mapping function
@@ -144,6 +203,26 @@ 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
/** /**
* Filters out the unwanted elements out of the Iterable * Filters out the unwanted elements out of the Iterable
* @param filter the elements that should be kept * @param filter the elements that should be kept
@@ -163,6 +242,16 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return this; return this;
} }
/**
* Repeats the elements inside of the Iterable
* @param repeats the amount of times the elements should be repeated
* @return self with a repeater applied
*/
public ASYNC_BUILDER KEY_GENERIC_TYPE repeat(int repeats) {
iterable = ITERABLES.repeat(iterable, repeats);
return this;
}
/** /**
* Limits how many elements are inside of the Iterable * Limits how many elements are inside of the Iterable
* @param limit how many elements should max be iterated through * @param limit how many elements should max be iterated through
@@ -194,6 +283,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return this; return this;
} }
#if OBJECT_ASYNC_MODULE
/** /**
* Iterates over the Iterable with a desired action * Iterates over the Iterable with a desired action
* @param action that should be applied * @param action that should be applied
@@ -203,6 +293,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return new ObjectAsyncBuilder<>(new ForEachTask<>(iterable.iterator(), action)); return new ObjectAsyncBuilder<>(new ForEachTask<>(iterable.iterator(), action));
} }
#endif
/** /**
* Reduces the elements inside of the Iterable down to one element * Reduces the elements inside of the Iterable down to one element
* @param operator that reduces the elements. * @param operator that reduces the elements.
@@ -237,23 +328,66 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
#endif #endif
#if OBJECT_ASYNC_MODULE
#if TYPE_OBJECT
/**
* Pours all elements of the Iterable down into a Array.
* @param action creates the final array that should be copied into.
* @return a new Builder with the ToArray function applied
*/
public ObjectAsyncBuilder<KEY_TYPE[]> TO_ARRAY(IntFunction<KEY_TYPE[]> action) {
return new ObjectAsyncBuilder<>(new ArrayTaskBRACES(iterable, action));
}
#else
/**
* Pours all elements of the Iterable down into a Array.
* @return a new Builder with the ToArray function applied
*/
public ObjectAsyncBuilder<KEY_TYPE[]> TO_ARRAY() {
return new ObjectAsyncBuilder<>(new ArrayTaskBRACES(iterable));
}
#endif
#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE
/** /**
* Pours all elements into a List that can be later * Pours all elements into a List that can be later
* @return a new Builder with the pour function applied * @return a new Builder with the pour function applied
*/ */
public ObjectAsyncBuilder<LIST KEY_GENERIC_TYPE> pourAsList() { public ObjectAsyncBuilder<LIST KEY_GENERIC_TYPE> pourAsList() {
#if ARRAY_LIST_FEATURE
return pour(new ARRAY_LISTBRACES()); return pour(new ARRAY_LISTBRACES());
#else
return pour(new LINKED_LISTBRACES());
#endif
} }
#if !TYPE_BOOLEAN #endif
#if !TYPE_BOOLEAN && SET_MODULE
#if LINKED_SET_FEATURE || LINKED_CUSTOM_SET_FEATURE || SET_FEATURE || CUSTOM_SET_FEATURE || RB_TREE_SET_FEATURE || AVL_TREE_SET_FEATURE || ARRAY_SET_FEATURE
/** /**
* Pours all elements into a Set that can be later * Pours all elements into a Set that can be later
* @return a new Builder with the pour function applied * @return a new Builder with the pour function applied
*/ */
public ObjectAsyncBuilder<SET KEY_GENERIC_TYPE> pourAsSet() { public ObjectAsyncBuilder<SET KEY_GENERIC_TYPE> pourAsSet() {
#if LINKED_SET_FEATURE
return pour(new LINKED_HASH_SETBRACES()); return pour(new LINKED_HASH_SETBRACES());
#else if LINKED_CUSTOM_SET_FEATURE
return pour(new LINKED_CUSTOM_HASH_SETBRACES(STRATEGY.normalStrategy()));
#else if SET_FEATURE
return pour(new HASH_SETBRACES());
#else if CUSTOM_SET_FEATURE
return pour(new CUSTOM_HASH_SETBRACES(STRATEGY.normalStrategy()));
#else if RB_TREE_SET_FEATURE
return pour(new RB_Tree_SETBRACES());
#else if AVL_TREE_SET_FEATURE
return pour(new AVL_Tree_SETBRACES());
#else if ARRAY_SET_FEATURE
return pour(new ARRAY_SETBRACES());
#endif
} }
#endif
#endif #endif
/** /**
* Pours all elements into a collection that can be later * Pours all elements into a collection that can be later
@@ -265,6 +399,8 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return new ObjectAsyncBuilder<>(new CollectTask<>(iterable.iterator(), collection)); return new ObjectAsyncBuilder<>(new CollectTask<>(iterable.iterator(), collection));
} }
#endif
#if BOOLEAN_ASYNC_MODULE
/** /**
* Searches through the elements of the Iterable to find if the desired element is present. * Searches through the elements of the Iterable to find if the desired element is present.
* @param filter that decides the desired elements * @param filter that decides the desired elements
@@ -292,6 +428,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return new BooleanAsyncBuilder(new MatchTaskBRACES(iterable.iterator(), filter, 2)); return new BooleanAsyncBuilder(new MatchTaskBRACES(iterable.iterator(), filter, 2));
} }
#endif
/** /**
* Searches through the elements of the Iterable to find if the desired element. * Searches through the elements of the Iterable to find if the desired element.
* If not present it will return the default value of the type * If not present it will return the default value of the type
@@ -303,6 +440,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return this; return this;
} }
#if INT_ASYNC_MODULE
/** /**
* Counts all desired elements inside the Iterable * Counts all desired elements inside the Iterable
* @param filter that decides the desired elements * @param filter that decides the desired elements
@@ -312,6 +450,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
return new IntAsyncBuilder(new CountTaskBRACES(iterable.iterator(), filter)); return new IntAsyncBuilder(new CountTaskBRACES(iterable.iterator(), filter));
} }
#endif
/** /**
* Optional way to add a custom executor that runs this offthread task. * Optional way to add a custom executor that runs this offthread task.
* Can only be set after the action was decided on. * Can only be set after the action was decided on.
@@ -492,6 +631,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
} }
#if BOOLEAN_ASYNC_MODULE
private static class MatchTask KEY_GENERIC_TYPE extends BaseBooleanTask private static class MatchTask KEY_GENERIC_TYPE extends BaseBooleanTask
{ {
ITERATOR KEY_GENERIC_TYPE iter; ITERATOR KEY_GENERIC_TYPE iter;
@@ -510,11 +650,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
switch(type) { switch(type) {
case 0: case 0:
while(shouldRun() && iter.hasNext()) { while(shouldRun() && iter.hasNext()) {
#if TYPE_OBJECT if(filter.test(iter.NEXT())) {
if(filter.getBoolean(iter.NEXT())) {
#else
if(filter.GET_VALUE(iter.NEXT())) {
#endif
setResult(true); setResult(true);
return true; return true;
} }
@@ -522,11 +658,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
break; break;
case 1: case 1:
while(shouldRun() && iter.hasNext()) { while(shouldRun() && iter.hasNext()) {
#if TYPE_OBJECT if(filter.test(iter.NEXT())) {
if(filter.getBoolean(iter.NEXT())) {
#else
if(filter.GET_VALUE(iter.NEXT())) {
#endif
setResult(false); setResult(false);
return true; return true;
} }
@@ -534,11 +666,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
break; break;
case 2: case 2:
while(shouldRun() && iter.hasNext()) { while(shouldRun() && iter.hasNext()) {
#if TYPE_OBJECT if(!filter.test(iter.NEXT())) {
if(!filter.getBoolean(iter.NEXT())) {
#else
if(!filter.GET_VALUE(iter.NEXT())) {
#endif
setResult(false); setResult(false);
return true; return true;
} }
@@ -560,6 +688,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
} }
#endif
private static class FindFirstTask KEY_GENERIC_TYPE extends BASE_TASK KEY_GENERIC_TYPE private static class FindFirstTask KEY_GENERIC_TYPE extends BASE_TASK KEY_GENERIC_TYPE
{ {
ITERATOR KEY_GENERIC_TYPE iter; ITERATOR KEY_GENERIC_TYPE iter;
@@ -574,11 +703,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
protected boolean execute() throws Exception { protected boolean execute() throws Exception {
while(shouldRun() && iter.hasNext()) { while(shouldRun() && iter.hasNext()) {
KEY_TYPE entry = iter.NEXT(); KEY_TYPE entry = iter.NEXT();
#if TYPE_OBJECT if(filter.test(iter.NEXT())) {
if(filter.getBoolean(iter.NEXT())) {
#else
if(filter.GET_VALUE(iter.NEXT())) {
#endif
setResult(entry); setResult(entry);
return true; return true;
} }
@@ -594,6 +719,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
} }
#if INT_ASYNC_MODULE
private static class CountTask KEY_GENERIC_TYPE extends BaseIntTask private static class CountTask KEY_GENERIC_TYPE extends BaseIntTask
{ {
ITERATOR KEY_GENERIC_TYPE iter; ITERATOR KEY_GENERIC_TYPE iter;
@@ -608,7 +734,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
@Override @Override
protected boolean execute() throws Exception { protected boolean execute() throws Exception {
while(shouldRun() && iter.hasNext()) { while(shouldRun() && iter.hasNext()) {
if(filter.TEST_VALUE(iter.NEXT())) { if(filter.test(iter.NEXT())) {
counted++; counted++;
} }
} }
@@ -628,6 +754,8 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
} }
#endif
#if OBJECT_ASYNC_MODULE
private static class CollectTask KSS_GENERIC_TYPE<V, T extends COLLECTION KEY_SPECIAL_GENERIC_TYPE<V>> extends BaseObjectTask<T> private static class CollectTask KSS_GENERIC_TYPE<V, T extends COLLECTION KEY_SPECIAL_GENERIC_TYPE<V>> extends BaseObjectTask<T>
{ {
ITERATOR KEY_SPECIAL_GENERIC_TYPE<V> iter; ITERATOR KEY_SPECIAL_GENERIC_TYPE<V> iter;
@@ -658,6 +786,52 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
} }
private static class ArrayTask KEY_GENERIC_TYPE extends BaseObjectTask<KEY_TYPE[]>
{
ITERATOR KEY_GENERIC_TYPE iter;
COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE wrapper;
#if TYPE_OBJECT
IntFunction<KEY_TYPE[]> builder;
public ArrayTask(ITERABLE KEY_GENERIC_TYPE iterable, IntFunction<KEY_TYPE[]> builder) {
this.builder = builder;
#else
public ArrayTask(ITERABLE KEY_GENERIC_TYPE iterable) {
#endif
iter = iterable.iterator();
ISizeProvider prov = ISizeProvider.of(iterable);
int size = prov == null ? -1 : prov.size();
wrapper = size < 0 ? COLLECTIONS.wrapper() : COLLECTIONS.wrapper(size);
}
@Override
protected boolean execute() throws Exception {
while(shouldRun() && iter.hasNext()) {
wrapper.add(iter.NEXT());
}
if(!iter.hasNext()) {
#if TYPE_OBJECT
setResult(wrapper.TO_ARRAY(builder));
#else
setResult(wrapper.TO_ARRAY());
#endif
wrapper = null;
return true;
}
return false;
}
@Override
protected void onCompletion() {
super.onCompletion();
iter = null;
#if TYPE_OBJECT
builder = null;
#endif
}
}
private static class ForEachTask<T> extends BaseObjectTask<Void> private static class ForEachTask<T> extends BaseObjectTask<Void>
{ {
ITERATOR KEY_GENERIC_TYPE iter; ITERATOR KEY_GENERIC_TYPE iter;
@@ -684,6 +858,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE
} }
} }
#endif
/** /**
* Base Task of the Actions that can be performed. * Base Task of the Actions that can be performed.
* Allows to simplify the actions that get executed. * Allows to simplify the actions that get executed.
@@ -1,11 +1,22 @@
package speiger.src.collections.PACKAGE.utils; package speiger.src.collections.PACKAGE.utils;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
#if !TYPE_BOOLEAN
import java.util.ConcurrentModificationException;
#endif
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
#if TYPE_OBJECT #if TYPE_OBJECT
import java.util.Comparator;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#endif #endif
import java.util.function.Predicate; import java.util.function.Predicate;
#if PRIMITIVES #if JDK_FUNCTION && !TYPE_OBJECT
import java.util.function.PREDICATE;
#endif
#if PRIMITIVES && !JDK_FUNCTION
import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_PREDICATE;
#endif #endif
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -13,14 +24,25 @@ import java.util.function.Consumer;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif #endif
#if !TYPE_OBJECT
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
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 !TYPE_BOOLEAN
import speiger.src.collections.utils.HashUtil;
#endif
import speiger.src.collections.utils.ITrimmable;
import speiger.src.collections.utils.SanityChecks;
/** /**
* A Helper class for Collections * A Helper class for Collections
*/ */
@@ -75,6 +97,578 @@ public class COLLECTIONS
return c instanceof SynchronizedCollection ? c : new SynchronizedCollectionBRACES(c, mutex); return c instanceof SynchronizedCollection ? c : new SynchronizedCollectionBRACES(c, mutex);
} }
/**
* Creates a Singleton Collection of a given element
* @param element the element that should be converted into a singleton collection
* @Type(T)
* @return a singletoncollection of the given element
*/
public static GENERIC_KEY_BRACES COLLECTION KEY_GENERIC_TYPE singleton(KEY_TYPE element) {
return new SingletonCollectionBRACES(element);
}
protected static GENERIC_KEY_BRACES CollectionWrapper KEY_GENERIC_TYPE wrapper() {
return new CollectionWrapperBRACES();
}
protected static GENERIC_KEY_BRACES CollectionWrapper KEY_GENERIC_TYPE wrapper(int size) {
return new CollectionWrapperBRACES(size);
}
#if !TYPE_BOOLEAN
protected static GENERIC_KEY_BRACES DistinctCollectionWrapper KEY_GENERIC_TYPE distinctWrapper() {
return new DistinctCollectionWrapperBRACES();
}
protected static GENERIC_KEY_BRACES DistinctCollectionWrapper KEY_GENERIC_TYPE distinctWrapper(int size) {
return new DistinctCollectionWrapperBRACES(size);
}
#endif
protected static class CollectionWrapper KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements ITrimmable {
KEY_TYPE[] elements;
int size = 0;
public CollectionWrapper() {
this(10);
}
public CollectionWrapper(int size) {
if(size < 0) throw new IllegalStateException("Size has to be 0 or greater");
elements = NEW_KEY_ARRAY(size);
}
@Override
public boolean add(KEY_TYPE o) {
if(size >= elements.length) elements = Arrays.copyOf(elements, (int)Math.min((long)elements.length + (elements.length >> 1), SanityChecks.MAX_ARRAY_SIZE));
elements[size++] = o;
return true;
}
public KEY_TYPE GET_KEY(int index) {
if(index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
return elements[index];
}
#if TYPE_OBJECT
@Override
public boolean remove(Object e) {
for(int i = 0;i<size;i++) {
if(KEY_EQUALS(elements[i], e)) {
removeIndex(i);
return true;
}
}
return false;
}
#else
@Override
public boolean REMOVE_KEY(KEY_TYPE e) {
for(int i = 0;i<size;i++) {
if(KEY_EQUALS(elements[i], e)) {
removeIndex(i);
return true;
}
}
return false;
}
#endif
private void removeIndex(int index) {
if(index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
size--;
if(index != size) System.arraycopy(elements, index+1, elements, index, size - index);
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new ITERATOR KEY_GENERIC_TYPE() {
int index = 0;
int lastReturned = -1;
@Override
public boolean hasNext() {
return index < size;
}
@Override
public KEY_TYPE NEXT() {
int i = index++;
return elements[(lastReturned = i)];
}
@Override
public void remove() {
if(lastReturned == -1) throw new IllegalStateException();
removeIndex(lastReturned);
index = lastReturned;
lastReturned = -1;
}
};
}
@Override
public int size() {
return size;
}
@Override
public void clear() {
#if TYPE_OBJECT
for(int i = 0;i<size;elements[i] = null,i++);
#endif
size = 0;
}
#if TYPE_OBJECT
public void sort(Comparator<? super CLASS_TYPE> c) {
if(c != null) ARRAYS.stableSort(elements, size, c);
else ARRAYS.stableSort(elements, size);
}
public void unstableSort(Comparator<? super CLASS_TYPE> c) {
if(c != null) ARRAYS.unstableSort(elements, size, c);
else ARRAYS.unstableSort(elements, size);
}
#else
public void sort(COMPARATOR c) {
if(c != null) ARRAYS.stableSort(elements, size, c);
else ARRAYS.stableSort(elements, size);
}
public void unstableSort(COMPARATOR c) {
if(c != null) ARRAYS.unstableSort(elements, size, c);
else ARRAYS.unstableSort(elements, size);
}
#endif
@Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;i++)
action.accept(elements[i]);
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;i++)
action.accept(input, elements[i]);
}
@Override
public boolean trim(int size) {
if(size > size() || size() == elements.length) return false;
int value = Math.max(size, size());
elements = value == 0 ? EMPTY_KEY_ARRAY : Arrays.copyOf(elements, value);
return true;
}
@Override
public void clearAndTrim(int size) {
if(elements.length <= size) {
clear();
return;
}
elements = size == 0 ? EMPTY_KEY_ARRAY : NEW_KEY_ARRAY(size);
this.size = size;
}
@Override
@Primitive
public Object[] toArray() {
Object[] obj = new Object[size];
for(int i = 0;i<size;i++)
obj[i] = KEY_TO_OBJ(elements[i]);
return obj;
}
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size];
else if(a.length < size) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size);
#if TYPE_OBJECT
System.arraycopy(elements, 0, a, 0, size);
#else
for(int i = 0;i<size;i++)
a[i] = (E)KEY_TO_OBJ(elements[i]);
#endif
if (a.length > size) a[size] = null;
return a;
}
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a.length < size) a = new KEY_TYPE[size];
System.arraycopy(elements, 0, a, 0, size);
if (a.length > size) a[size] = EMPTY_KEY_VALUE;
return a;
}
#endif
}
#if !TYPE_BOOLEAN
protected static class DistinctCollectionWrapper KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE {
KEY_TYPE[] keys;
boolean containsNull;
int minCapacity;
int nullIndex;
int maxFill;
int mask;
int size;
public DistinctCollectionWrapper() {
this(HashUtil.DEFAULT_MIN_CAPACITY);
}
public DistinctCollectionWrapper(int size) {
if(minCapacity < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed");
minCapacity = nullIndex = HashUtil.arraySize(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR);
mask = nullIndex - 1;
maxFill = Math.min((int)Math.ceil(nullIndex * HashUtil.DEFAULT_LOAD_FACTOR), nullIndex - 1);
keys = NEW_KEY_ARRAY(nullIndex + 1);
}
@Override
public boolean add(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) {
if(containsNull) return false;
containsNull = true;
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NOT_NULL(current)) {
if(KEY_EQUALS(current, o)) return false;
while(KEY_EQUALS_NOT_NULL((current = keys[pos = (++pos & mask)])))
if(KEY_EQUALS(current, o)) return false;
}
keys[pos] = o;
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, HashUtil.DEFAULT_LOAD_FACTOR));
return true;
}
@Override
public boolean contains(Object o) {
#if TYPE_OBJECT
if(o == null) return containsNull;
#else
if(o == null) return false;
if(o instanceof CLASS_TYPE && KEY_EQUALS(CLASS_TO_KEY(o), EMPTY_KEY_VALUE)) return containsNull;
#endif
int pos = HashUtil.mix(o.hashCode()) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(EQUALS_KEY_TYPE(current, o)) return true;
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(EQUALS_KEY_TYPE(current, o)) return true;
}
}
@Override
public boolean remove(Object o) {
#if TYPE_OBJECT
if(o == null) return (containsNull ? removeNullIndex() : false);
#else
if(o == null) return false;
if(o instanceof CLASS_TYPE && KEY_EQUALS(CLASS_TO_KEY(o), EMPTY_KEY_VALUE)) return (containsNull ? removeNullIndex() : false);
#endif
int pos = HashUtil.mix(o.hashCode()) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(EQUALS_KEY_TYPE(current, o)) return removeIndex(pos);
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(EQUALS_KEY_TYPE(current, o)) return removeIndex(pos);
}
}
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) return containsNull;
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(KEY_EQUALS(current, o)) return true;
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(KEY_EQUALS(current, o)) return true;
}
}
@Override
public boolean REMOVE_KEY(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) return containsNull ? removeNullIndex() : false;
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(KEY_EQUALS(current, o)) return removeIndex(pos);
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(KEY_EQUALS(current, o)) return removeIndex(pos);
}
}
#endif
protected boolean removeIndex(int pos) {
if(pos == nullIndex) return containsNull ? removeNullIndex() : false;
keys[pos] = EMPTY_KEY_VALUE;
size--;
shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return true;
}
protected boolean removeNullIndex() {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
size--;
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return true;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator();
}
@Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
if(size() <= 0) return;
if(containsNull) action.accept(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(keys[i]);
}
}
@Override
public DistinctCollectionWrapper KEY_GENERIC_TYPE copy() {
DistinctCollectionWrapper KEY_GENERIC_TYPE set = new DistinctCollectionWrapperBRACES(0);
set.minCapacity = minCapacity;
set.mask = mask;
set.maxFill = maxFill;
set.nullIndex = nullIndex;
set.containsNull = containsNull;
set.size = size;
set.keys = Arrays.copyOf(keys, keys.length);
return set;
}
protected void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(KEY_EQUALS_NULL((current = keys[startPos]))) {
keys[last] = EMPTY_KEY_VALUE;
return;
}
slot = HashUtil.mix(KEY_TO_HASH(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
keys[last] = current;
}
}
protected void rehash(int newSize) {
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(true) {
if(--i < 0) throw new ConcurrentModificationException("Set was modified during rehash");
if(KEY_EQUALS_NOT_NULL(keys[i])) break;
}
if(KEY_EQUALS_NOT_NULL(newKeys[pos = HashUtil.mix(KEY_TO_HASH(keys[i])) & newMask]))
while(KEY_EQUALS_NOT_NULL(newKeys[pos = (++pos & newMask)]));
newKeys[pos] = keys[i];
}
nullIndex = newSize;
mask = newMask;
maxFill = Math.min((int)Math.ceil(nullIndex * HashUtil.DEFAULT_LOAD_FACTOR), nullIndex - 1);
keys = newKeys;
}
@Override
public void clear() {
if(size == 0) return;
size = 0;
containsNull = false;
Arrays.fill(keys, EMPTY_KEY_VALUE);
}
@Override
public int size() {
return size;
}
private class SetIterator implements ITERATOR KEY_GENERIC_TYPE {
int pos = nullIndex;
int returnedPos = -1;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
KEY_TYPE[] wrapped = null;
int wrappedIndex = 0;
@Override
public boolean hasNext() {
if(nextIndex == Integer.MIN_VALUE) {
if(returnNull) {
returnNull = false;
nextIndex = nullIndex;
}
else
{
while(true) {
if(--pos < 0) {
if(wrapped == null || wrappedIndex <= -pos - 1) break;
nextIndex = -pos - 1;
break;
}
if(KEY_EQUALS_NOT_NULL(keys[pos])){
nextIndex = pos;
break;
}
}
}
}
return nextIndex != Integer.MIN_VALUE;
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
returnedPos = pos;
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
KEY_TYPE value = wrapped[nextIndex];
nextIndex = Integer.MIN_VALUE;
return value;
}
KEY_TYPE value = keys[(lastReturned = nextIndex)];
nextIndex = Integer.MIN_VALUE;
return value;
}
@Override
public void remove() {
if(lastReturned == -1) throw new IllegalStateException();
if(lastReturned == nullIndex) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else if(returnedPos >= 0) shiftKeys(returnedPos);
else {
#if TYPE_OBJECT
DistinctCollectionWrapper.this.remove(wrapped[-returnedPos - 1]);
#else
DistinctCollectionWrapper.this.REMOVE_KEY(wrapped[-returnedPos - 1]);
#endif
lastReturned = -1;
return;
}
size--;
lastReturned = -1;
}
private void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(KEY_EQUALS_NULL((current = keys[startPos]))) {
keys[last] = EMPTY_KEY_VALUE;
return;
}
slot = HashUtil.mix(KEY_TO_HASH(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
if(startPos < last) addWrapper(keys[startPos]);
keys[last] = current;
}
}
private void addWrapper(KEY_TYPE value) {
if(wrapped == null) wrapped = NEW_KEY_ARRAY(2);
else if(wrappedIndex >= wrapped.length) {
KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2);
System.arraycopy(wrapped, 0, newArray, 0, wrapped.length);
wrapped = newArray;
}
wrapped[wrappedIndex++] = value;
}
}
}
#endif
private static class SingletonCollection KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE
{
KEY_TYPE element;
SingletonCollection(KEY_TYPE element) {
this.element = element;
}
#if !TYPE_OBJECT
@Override
public boolean REMOVE_KEY(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif
@Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public ITERATOR KEY_GENERIC_TYPE iterator()
{
return new ITERATOR KEY_GENERIC_TYPE() {
boolean next = true;
@Override
public boolean hasNext() { return next; }
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
next = false;
return element;
}
};
}
@Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Collection))
return false;
Collection<?> l = (Collection<?>)o;
if(l.size() != size()) return false;
Iterator<?> iter = l.iterator();
if (iter.hasNext() && !Objects.equals(element, iter.next())) {
return false;
}
return !iter.hasNext();
}
@Override
public int hashCode() {
return KEY_TO_HASH(element);
}
@Override
public int size() { return 1; }
@Override
public SingletonCollection KEY_GENERIC_TYPE copy() { return new SingletonCollectionBRACES(element); }
}
/** /**
* Synchronized Collection Wrapper for the synchronizedCollection function * Synchronized Collection Wrapper for the synchronizedCollection function
* @Type(T) * @Type(T)
@@ -183,10 +777,15 @@ public class COLLECTIONS
@Override @Override
public void forEach(Consumer<? super CLASS_TYPE> action) { synchronized(mutex) { c.forEach(action); } } public void forEach(Consumer<? super CLASS_TYPE> action) { synchronized(mutex) { c.forEach(action); } }
#endif #endif
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { synchronized(mutex) { c.forEachIndexed(action); } }
@Override @Override
public int hashCode() { synchronized(mutex) { return c.hashCode(); } } public int hashCode() { synchronized(mutex) { return c.hashCode(); } }
@Override @Override
public boolean equals(Object obj) { synchronized(mutex) { return c.equals(obj); } } public boolean equals(Object obj) {
if(obj == this) return true;
synchronized(mutex) { return c.equals(obj); }
}
@Override @Override
public String toString() { synchronized(mutex) { return c.toString(); } } public String toString() { synchronized(mutex) { return c.toString(); } }
@Override @Override
@@ -305,10 +904,12 @@ public class COLLECTIONS
@Override @Override
public void forEach(Consumer<? super CLASS_TYPE> action) { c.forEach(action); } public void forEach(Consumer<? super CLASS_TYPE> action) { c.forEach(action); }
#endif #endif
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { c.forEachIndexed(action); }
@Override @Override
public int hashCode() { return c.hashCode(); } public int hashCode() { return c.hashCode(); }
@Override @Override
public boolean equals(Object obj) { return c.equals(obj); } public boolean equals(Object obj) { return obj == this || c.equals(obj); }
@Override @Override
public String toString() { return c.toString(); } public String toString() { return c.toString(); }
@Override @Override
@@ -350,7 +951,7 @@ public class COLLECTIONS
@Override @Override
public boolean contains(KEY_TYPE o) { return false; } public boolean contains(KEY_TYPE o) { return false; }
@Override @Override
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) { return false; } public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) { return c.isEmpty(); }
@Override @Override
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) { return false; } public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) { return false; }
#else #else
@@ -362,7 +963,7 @@ public class COLLECTIONS
public boolean containsAny(Collection<?> c) { return false; } public boolean containsAny(Collection<?> c) { return false; }
@Override @Override
@Primitive @Primitive
public boolean containsAll(Collection<?> c) { return false; } public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
@Override @Override
public int hashCode() { return 0; } public int hashCode() { return 0; }
@@ -401,14 +1002,28 @@ public class COLLECTIONS
public Object[] toArray() { return ObjectArrays.EMPTY_ARRAY; } public Object[] toArray() { return ObjectArrays.EMPTY_ARRAY; }
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public <T> T[] toArray(T[] a) { return a; } public <T> T[] toArray(T[] a) {
if(a != null && a.length > 0)
a[0] = null;
return a;
}
@Override @Override
public KEY_TYPE[] TO_ARRAY() { return ARRAYS.EMPTY_ARRAY; } public KEY_TYPE[] TO_ARRAY() { return ARRAYS.EMPTY_ARRAY; }
@Override @Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) { return a; } public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a != null && a.length > 0)
a[0] = EMPTY_KEY_VALUE;
return a;
}
#else #else
@Override @Override
public <E> E[] toArray(E[] a) { return a; } public <E> E[] toArray(E[] a) {
if(a != null && a.length > 0)
a[0] = EMPTY_KEY_VALUE;
return a;
}
#endif #endif
@Override @Override
public ITERATOR KEY_GENERIC_TYPE iterator() { return ITERATORS.empty(); } public ITERATOR KEY_GENERIC_TYPE iterator() { return ITERATORS.empty(); }
@@ -7,7 +7,9 @@ import speiger.src.collections.utils.IArray;
/** /**
* Type-Specific Helper class to get the underlying array of array implementations. * Type-Specific Helper class to get the underlying array of array implementations.
#if ARRAY_LIST_FEATURE
* @see speiger.src.collections.PACKAGE.lists.ARRAY_LIST * @see speiger.src.collections.PACKAGE.lists.ARRAY_LIST
#endif
* @Type(T) * @Type(T)
*/ */
public interface IARRAY KEY_GENERIC_TYPE extends IArray public interface IARRAY KEY_GENERIC_TYPE extends IArray
@@ -8,23 +8,44 @@ import java.util.Comparator;
#endif #endif
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer; import java.util.function.Consumer;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.ITERABLE; import speiger.src.collections.PACKAGE.collections.ITERABLE;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.collections.ObjectIterable; 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.lists.LIST;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#if !TYPE_BOOLEAN
import speiger.src.collections.PACKAGE.sets.HASH_SET;
import speiger.src.collections.PACKAGE.sets.SET;
#endif #endif
import speiger.src.collections.utils.ISizeProvider;
/** /**
* A Helper class for Iterables * A Helper class for Iterables
@@ -55,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
@@ -147,6 +201,28 @@ public class ITERABLES
return new DistinctIterableBRACES(wrap(iterable)); return new DistinctIterableBRACES(wrap(iterable));
} }
/**
* A Helper function that repeats the Iterable a specific amount of times
* @param iterable that should be repeated
* @param repeats the amount of times the iterable should be repeated
* @Type(T)
* @return a repeating iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE repeat(ITERABLE KEY_GENERIC_TYPE iterable, int repeats) {
return new RepeatingIterableBRACES(iterable, repeats);
}
/**
* A Helper function that repeats the Iterable a specific amount of times from a Java Iterable
* @param iterable that should be repeated
* @param repeats the amount of times the iterable should be repeated
* @Type(T)
* @return a repeating iterable
*/
public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE repeat(Iterable<? extends CLASS_TYPE> iterable, int repeats) {
return new RepeatingIterableBRACES(wrap(iterable), repeats);
}
/** /**
* A Helper function that hard limits the Iterable to a specific size * A Helper function that hard limits the Iterable to a specific size
* @param iterable that should be limited * @param iterable that should be limited
@@ -225,7 +301,7 @@ public class ITERABLES
return new WrappedIterableBRACES(iterable); return new WrappedIterableBRACES(iterable);
} }
private static class WrappedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE private static class WrappedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{ {
Iterable<? extends CLASS_TYPE> iterable; Iterable<? extends CLASS_TYPE> iterable;
@@ -237,6 +313,12 @@ public class ITERABLES
return ITERATORS.wrap(iterable.iterator()); return ITERATORS.wrap(iterable.iterator());
} }
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : prov.size();
}
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public void forEach(CONSUMER action) { public void forEach(CONSUMER action) {
@@ -251,7 +333,48 @@ public class ITERABLES
#endif #endif
} }
private static class MappedIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T> #if TYPE_OBJECT
#iterate
#argument CONSUMER BooleanConsumer ByteConsumer ShortConsumer IntConsumer LongConsumer FloatConsumer DoubleConsumer
#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble
#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable
#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument APPLY test applyAsByte applyAsShort applyAsInt applyAsLong applyAsFloat applyAsDouble
#argument DATA_TYPE Boolean Byte Short Int Long Float Double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
private static class MAPPED_TYPEIterable<E> implements OUTPUT_ITERABLE, ISizeProvider
{
ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable;
MAPPER<E> mapper;
MAPPED_TYPEIterable(ITERABLE<E> iterable, MAPPER<E> mapper) {
this.iterable = iterable;
this.mapper = mapper;
}
public OUTPUT_ITERATOR iterator() {
return ITERATORS.mapToDATA_TYPE(iterable.iterator(), mapper);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(this);
return prov == null ? -1 : prov.size();
}
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterable.forEach(E -> action.accept(mapper.APPLY(E)));
}
}
#endif
#enditerate
#endif
private static class MappedIterable KSS_GENERIC_TYPE<E, T> implements ObjectIterable<T>, ISizeProvider
{ {
ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable; ITERABLE KEY_SPECIAL_GENERIC_TYPE<E> iterable;
TO_OBJECT_FUNCTION KSS_GENERIC_TYPE<E, T> mapper; TO_OBJECT_FUNCTION KSS_GENERIC_TYPE<E, T> mapper;
@@ -265,10 +388,16 @@ public class ITERABLES
return ITERATORS.map(iterable.iterator(), mapper); return ITERATORS.map(iterable.iterator(), mapper);
} }
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(this);
return prov == null ? -1 : prov.size();
}
@Override @Override
public void forEach(Consumer<? super T> action) { public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
iterable.forEach(E -> action.accept(mapper.GET_VALUE(E))); iterable.forEach(E -> action.accept(mapper.apply(E)));
} }
} }
@@ -290,7 +419,7 @@ public class ITERABLES
@Override @Override
public void forEach(Consumer<? super T> action) { public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
iterable.forEach(E -> mapper.GET_VALUE(E).forEach(action)); iterable.forEach(E -> mapper.apply(E).forEach(action));
} }
} }
@@ -314,12 +443,54 @@ public class ITERABLES
public void forEach(Consumer<? super T> action) { public void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
iterable.forEach(E -> { iterable.forEach(E -> {
T[] array = mapper.GET_VALUE(E); T[] array = mapper.apply(E);
for(int i = 0,m=array.length;i<m;action.accept(array[i++])); for(int i = 0,m=array.length;i<m;action.accept(array[i++]));
}); });
} }
} }
private static class RepeatingIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{
ITERABLE KEY_GENERIC_TYPE iterable;
int repeats;
public RepeatingIterable(ITERABLE KEY_GENERIC_TYPE iterable, int repeats) {
this.iterable = iterable;
this.repeats = repeats;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.repeat(iterable.iterator(), repeats);
}
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : prov.size() * (repeats+1);
}
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) {
Objects.requireNonNull(action);
COLLECTION KEY_GENERIC_TYPE repeater = COLLECTIONS.wrapper();
iterable.forEach(action.andThen(repeater::add));
for(int i = 0;i<repeats;i++)
repeater.forEach(action);
}
#else
@Override
public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
COLLECTION KEY_GENERIC_TYPE repeater = COLLECTIONS.wrapper();
iterable.forEach(T -> {action.accept(T); repeater.add(T);});
for(int i = 0;i<repeats;i++)
repeater.forEach(action);
}
#endif
}
private static class FilteredIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE private static class FilteredIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE
{ {
ITERABLE KEY_GENERIC_TYPE iterable; ITERABLE KEY_GENERIC_TYPE iterable;
@@ -339,17 +510,17 @@ public class ITERABLES
@Override @Override
public void forEach(CONSUMER action) { public void forEach(CONSUMER action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
iterable.forEach(T -> { if(!filter.TEST_VALUE(T)) action.accept(T); } ); iterable.forEach(T -> { if(!filter.test(T)) action.accept(T); } );
} }
#else #else
public void forEach(Consumer<? super CLASS_TYPE> action) { public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
iterable.forEach(T -> { if(!filter.TEST_VALUE(T)) action.accept(T); } ); iterable.forEach(T -> { if(!filter.test(T)) action.accept(T); } );
} }
#endif #endif
} }
private static class LimitedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE private static class LimitedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{ {
ITERABLE KEY_GENERIC_TYPE iterable; ITERABLE KEY_GENERIC_TYPE iterable;
long limit; long limit;
@@ -364,6 +535,12 @@ public class ITERABLES
return ITERATORS.limit(iterable.iterator(), limit); return ITERATORS.limit(iterable.iterator(), limit);
} }
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : (int)Math.min(prov.size(), limit);
}
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public void forEach(CONSUMER action) { public void forEach(CONSUMER action) {
@@ -388,7 +565,7 @@ public class ITERABLES
#endif #endif
} }
private static class SortedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE private static class SortedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{ {
ITERABLE KEY_GENERIC_TYPE iterable; ITERABLE KEY_GENERIC_TYPE iterable;
COMPARATOR KEY_GENERIC_TYPE sorter; COMPARATOR KEY_GENERIC_TYPE sorter;
@@ -403,23 +580,29 @@ public class ITERABLES
return ITERATORS.sorted(iterable.iterator(), sorter); return ITERATORS.sorted(iterable.iterator(), sorter);
} }
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : prov.size();
}
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public void forEach(CONSUMER action) { public void forEach(CONSUMER action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE wrapper = COLLECTIONS.wrapper();
iterable.forEach(list::add); iterable.forEach(wrapper::add);
list.unstableSort(sorter); wrapper.unstableSort(sorter);
list.forEach(action); wrapper.forEach(action);
} }
#else #else
@Override @Override
public void forEach(Consumer<? super CLASS_TYPE> action) { public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE wrapper = COLLECTIONS.wrapper();
iterable.forEach(list::add); iterable.forEach(wrapper::add);
list.unstableSort(sorter); wrapper.unstableSort(sorter);
list.forEach(action); wrapper.forEach(action);
} }
#endif #endif
} }
@@ -449,20 +632,20 @@ public class ITERABLES
action.accept(T); action.accept(T);
}); });
#else #else
SET KEY_GENERIC_TYPE filtered = new HASH_SETBRACES(); COLLECTION KEY_GENERIC_TYPE filtered = COLLECTIONS.distinctWrapper();
iterable.forEach(T -> { if(filtered.add(T)) action.accept(T); }); iterable.forEach(T -> { if(filtered.add(T)) action.accept(T); });
#endif #endif
} }
#else #else
public void forEach(Consumer<? super CLASS_TYPE> action) { public void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action); Objects.requireNonNull(action);
SET KEY_GENERIC_TYPE filtered = new HASH_SETBRACES(); COLLECTION KEY_GENERIC_TYPE filtered = COLLECTIONS.distinctWrapper();
iterable.forEach(T -> { if(filtered.add(T)) action.accept(T); }); iterable.forEach(T -> { if(filtered.add(T)) action.accept(T); });
} }
#endif #endif
} }
private static class PeekIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE private static class PeekIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE, ISizeProvider
{ {
ITERABLE KEY_GENERIC_TYPE iterable; ITERABLE KEY_GENERIC_TYPE iterable;
CONSUMER KEY_GENERIC_TYPE action; CONSUMER KEY_GENERIC_TYPE action;
@@ -477,6 +660,12 @@ public class ITERABLES
return ITERATORS.peek(iterable.iterator(), action); return ITERATORS.peek(iterable.iterator(), action);
} }
@Override
public int size() {
ISizeProvider prov = ISizeProvider.of(iterable);
return prov == null ? -1 : prov.size();
}
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public void forEach(CONSUMER action) { public void forEach(CONSUMER action) {
@@ -4,7 +4,10 @@ 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
import java.util.function.Consumer;
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
@@ -13,18 +16,39 @@ import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.utils.ObjectIterators; import speiger.src.collections.objects.utils.ObjectIterators;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#else
#if BOOLEAN_COLLECTION_MODULE
import speiger.src.collections.booleans.collections.BooleanIterator;
#endif
#iterate
#argument ITERATOR ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument PACKAGE bytes shorts ints longs floats doubles
#argument MAPPER ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument FILTER_TYPE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
import speiger.src.collections.objects.functions.function.MAPPER;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#endif
#enditerate
#endif #endif
import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION;
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; #endif
#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE
import speiger.src.collections.PACKAGE.lists.LIST; import speiger.src.collections.PACKAGE.lists.LIST;
#if ARRAY_LIST_FEATURE
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
#else if LINKED_LIST_FEATURE
import speiger.src.collections.PACKAGE.lists.LINKED_LIST;
#endif
#endif
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;
#if !TYPE_BOOLEAN import speiger.src.collections.PACKAGE.utils.COLLECTIONS.CollectionWrapper;
import speiger.src.collections.PACKAGE.sets.HASH_SET;
import speiger.src.collections.PACKAGE.sets.SET;
#endif
/** /**
* A Helper class for Iterators * A Helper class for Iterators
@@ -34,7 +58,7 @@ public class ITERATORS
/** /**
* Empty Iterator Reference * Empty Iterator Reference
*/ */
public static final EmptyIterator NO_GENERIC_TYPE EMPTY = new EmptyIteratorBRACES(); private static final EmptyIterator NO_GENERIC_TYPE EMPTY = new EmptyIteratorBRACES();
/** /**
* Returns a Immutable EmptyIterator instance that is automatically casted. * Returns a Immutable EmptyIterator instance that is automatically casted.
@@ -99,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
@@ -123,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
@@ -215,6 +274,48 @@ public class ITERATORS
return new DistinctIteratorBRACES(wrap(iterator)); return new DistinctIteratorBRACES(wrap(iterator));
} }
/**
* A Helper function that repeats the Iterator a specific amount of times
* @param iterator that should be repeated
* @param repeats the amount of times the iterator should be repeated
* @Type(T)
* @return a repeating iterator
*/
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE repeat(ITERATOR KEY_GENERIC_TYPE iterator, int repeats) {
return new RepeatingIteratorBRACES(iterator, repeats);
}
/**
* A Helper function that repeats the Iterator a specific amount of times from a Java Iterator
* @param iterator that should be repeated
* @param repeats the amount of times the iterator should be repeated
* @Type(T)
* @return a repeating iterator
*/
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE repeat(Iterator<? extends CLASS_TYPE> iterator, int 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
@@ -299,7 +400,7 @@ public class ITERATORS
* @ArrayType(T) * @ArrayType(T)
* @return a Iterator that is wrapping a array. * @return a Iterator that is wrapping a array.
*/ */
public static GENERIC_KEY_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE[] a) { public static GENERIC_KEY_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE... a) {
return wrap(a, 0, a.length); return wrap(a, 0, a.length);
} }
@@ -446,6 +547,8 @@ public class ITERATORS
} }
#endif #endif
#if LIST_MODULE
#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE
/** /**
* A Helper function to pours all elements of a Iterator into a List * A Helper function to pours all elements of a Iterator into a List
* @param iter the elements that should be poured into list. * @param iter the elements that should be poured into list.
@@ -464,12 +567,20 @@ public class ITERATORS
* @return A list of all requested elements of the Iterator * @return A list of all requested elements of the Iterator
*/ */
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE pour(ITERATOR KEY_GENERIC_TYPE iter, int max) { public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE pour(ITERATOR KEY_GENERIC_TYPE iter, int max) {
#if ARRAY_LIST_FEATURE
ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
#else
LINKED_LIST KEY_GENERIC_TYPE list = new LINKED_LISTBRACES();
#endif
pour(iter, list, max); pour(iter, list, max);
#if ARRAY_LIST_FEATURE
list.trim(); list.trim();
#endif
return list; return list;
} }
#endif
#endif
/** /**
* A Helper function to pours all elements of a Iterator into a Collection * A Helper function to pours all elements of a Iterator into a Collection
* @param iter the elements that should be poured into list. * @param iter the elements that should be poured into list.
@@ -729,41 +840,21 @@ public class ITERATORS
private static class EmptyIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE private static class EmptyIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE
{ {
@Override @Override
public boolean hasNext() { public boolean hasNext() { return false; }
return false;
}
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() { throw new NoSuchElementException(); }
return EMPTY_KEY_VALUE;
}
@Override @Override
public boolean hasPrevious() { public boolean hasPrevious() { return false; }
return false;
}
@Override @Override
public KEY_TYPE PREVIOUS() { public KEY_TYPE PREVIOUS() { throw new NoSuchElementException(); }
return EMPTY_KEY_VALUE;
}
@Override @Override
public int nextIndex() { public int nextIndex() { return 0; }
return 0;
}
@Override @Override
public int previousIndex() { public int previousIndex() { return -1; }
return 0;
}
@Override @Override
public void remove() { throw new UnsupportedOperationException(); } public void remove() { throw new UnsupportedOperationException(); }
@Override @Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); } public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override @Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); } public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
} }
@@ -787,6 +878,7 @@ public class ITERATORS
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
return a[from++]; return a[from++];
} }
@@ -816,7 +908,7 @@ public class ITERATORS
@Override @Override
public T next() { public T next() {
return mapper.GET_VALUE(iterator.NEXT()); return mapper.apply(iterator.NEXT());
} }
@Override @Override
@@ -825,6 +917,45 @@ public class ITERATORS
} }
} }
#if TYPE_OBJECT
#iterate
#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble
#argument NEXT_TYPE nextBoolean nextByte nextShort nextInt nextLong nextFloat nextDouble
#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator
#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction
#argument APPLY test applyAsByte applyAsShort applyAsInt applyAsLong applyAsFloat applyAsDouble
#argument DATA_TYPE boolean byte short int long float double
#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE
#if FILTER_TYPE
private static class MAPPED_TYPEIterator<E> implements OUTPUT_ITERATOR
{
ITERATOR<E> iterator;
MAPPER<E> mapper;
MAPPED_TYPEIterator(ITERATOR KEY_SPECIAL_GENERIC_TYPE<E> iterator, MAPPER<E> mapper) {
this.iterator = iterator;
this.mapper = mapper;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public DATA_TYPE NEXT_TYPE() {
return mapper.APPLY(iterator.NEXT());
}
@Override
public int skip(int amount) {
return iterator.skip(amount);
}
}
#endif
#enditerate
#endif
private static class FlatMappedIterator KSS_GENERIC_TYPE<E, T,[SPACE]V extends Iterable<T>> implements ObjectIterator<T> private static class FlatMappedIterator KSS_GENERIC_TYPE<E, T,[SPACE]V extends Iterable<T>> implements ObjectIterator<T>
{ {
ITERATOR KEY_SPECIAL_GENERIC_TYPE<E> iterator; ITERATOR KEY_SPECIAL_GENERIC_TYPE<E> iterator;
@@ -842,7 +973,7 @@ public class ITERATORS
foundNext = true; foundNext = true;
while(iterator.hasNext()) { while(iterator.hasNext()) {
if(last != null && last.hasNext()) return; if(last != null && last.hasNext()) return;
last = mapper.GET_VALUE(iterator.NEXT()).iterator(); last = mapper.apply(iterator.NEXT()).iterator();
} }
} }
@@ -854,7 +985,7 @@ public class ITERATORS
@Override @Override
public T next() { public T next() {
if(!hasNext()) throw new IllegalStateException("End of Iterator"); if(!hasNext()) throw new NoSuchElementException();
T result = last.next(); T result = last.next();
foundNext = false; foundNext = false;
return result; return result;
@@ -878,7 +1009,7 @@ public class ITERATORS
foundNext = true; foundNext = true;
while(iterator.hasNext()) { while(iterator.hasNext()) {
if(last != null && last.hasNext()) return; if(last != null && last.hasNext()) return;
last = ObjectIterators.wrap(mapper.GET_VALUE(iterator.NEXT())); last = ObjectIterators.wrap(mapper.apply(iterator.NEXT()));
} }
} }
@@ -890,18 +1021,86 @@ public class ITERATORS
@Override @Override
public T next() { public T next() {
if(!hasNext()) throw new IllegalStateException("End of Iterator"); if(!hasNext()) throw new NoSuchElementException();
T result = last.next(); T result = last.next();
foundNext = false; foundNext = false;
return result; return result;
} }
} }
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
{
final int repeats;
int index = 0;
ITERATOR KEY_GENERIC_TYPE iter;
COLLECTION KEY_GENERIC_TYPE repeater = COLLECTIONS.wrapper();
public RepeatingIterator(ITERATOR KEY_GENERIC_TYPE iter, int repeat) {
this.iter = iter;
this.repeats = repeat;
}
@Override
public boolean hasNext() {
if(iter.hasNext()) return true;
if(index < repeats) {
index++;
iter = repeater.iterator();
return iter.hasNext();
}
return false;
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
KEY_TYPE value = iter.NEXT();
if(index == 0) repeater.add(value);
return value;
}
}
private static class SortedIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE private static class SortedIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
{ {
ITERATOR KEY_GENERIC_TYPE iterator; ITERATOR KEY_GENERIC_TYPE iterator;
COMPARATOR KEY_GENERIC_TYPE sorter; COMPARATOR KEY_GENERIC_TYPE sorter;
LIST KEY_GENERIC_TYPE sortedElements = null; COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE sortedElements = null;
int index = 0; int index = 0;
public SortedIterator(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE sorter) { public SortedIterator(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE sorter) {
@@ -913,7 +1112,11 @@ public class ITERATORS
public boolean hasNext() { public boolean hasNext() {
if(sortedElements == null) { if(sortedElements == null) {
boolean hasNext = iterator.hasNext(); boolean hasNext = iterator.hasNext();
sortedElements = hasNext ? pour(iterator) : LISTS.empty(); if(hasNext) {
sortedElements = COLLECTIONS.wrapper();
pour(iterator, sortedElements);
}
else sortedElements = COLLECTIONS.wrapper();
if(hasNext) sortedElements.unstableSort(sorter); if(hasNext) sortedElements.unstableSort(sorter);
} }
return index < sortedElements.size(); return index < sortedElements.size();
@@ -921,7 +1124,7 @@ public class ITERATORS
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new IllegalStateException("End of Iterator"); if(!hasNext()) throw new NoSuchElementException();
return sortedElements.GET_KEY(index++); return sortedElements.GET_KEY(index++);
} }
} }
@@ -932,7 +1135,7 @@ public class ITERATORS
#if TYPE_BOOLEAN #if TYPE_BOOLEAN
int filtered; int filtered;
#else #else
SET KEY_GENERIC_TYPE filtered = new HASH_SETBRACES(); COLLECTION KEY_GENERIC_TYPE filtered = COLLECTIONS.distinctWrapper();
#endif #endif
KEY_TYPE lastFound; KEY_TYPE lastFound;
boolean foundNext = false; boolean foundNext = false;
@@ -971,7 +1174,7 @@ public class ITERATORS
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new IllegalStateException("End of Iterator"); if(!hasNext()) throw new NoSuchElementException();
foundNext = false; foundNext = false;
return lastFound; return lastFound;
} }
@@ -993,7 +1196,7 @@ public class ITERATORS
if(foundNext) return; if(foundNext) return;
while(iterator.hasNext()) { while(iterator.hasNext()) {
lastFound = iterator.NEXT(); lastFound = iterator.NEXT();
if(filter.TEST_VALUE(lastFound)) { if(filter.test(lastFound)) {
foundNext = true; foundNext = true;
break; break;
} }
@@ -1008,7 +1211,7 @@ public class ITERATORS
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new IllegalStateException("End of Iterator"); if(!hasNext()) throw new NoSuchElementException();
foundNext = false; foundNext = false;
return lastFound; return lastFound;
} }
@@ -1031,7 +1234,7 @@ public class ITERATORS
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new IllegalStateException("End of Iterator"); if(!hasNext()) throw new NoSuchElementException();
limit--; limit--;
return iterator.NEXT(); return iterator.NEXT();
} }
@@ -1054,7 +1257,7 @@ public class ITERATORS
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!hasNext()) throw new IllegalStateException("End of Iterator"); if(!hasNext()) throw new NoSuchElementException();
KEY_TYPE result = iterator.NEXT(); KEY_TYPE result = iterator.NEXT();
action.accept(result); action.accept(result);
return result; return result;
@@ -1,10 +1,19 @@
package speiger.src.collections.PACKAGE.utils; package speiger.src.collections.PACKAGE.utils;
import java.util.Collection; import java.util.Collection;
import java.util.List;
#if IARRAY_FEATURE
import java.util.Objects; import java.util.Objects;
import java.util.Random; #endif
#if JAVA_VERSION>=17
import java.util.random.RANDOM;
#else
import java.util.RANDOM;
#endif
import java.util.RandomAccess; import java.util.RandomAccess;
#if IARRAY_FEATURE || TYPE_OBJECT
import java.util.function.Consumer; import java.util.function.Consumer;
#endif
#if PRIMITIVES #if PRIMITIVES
import java.nio.JAVA_BUFFER; import java.nio.JAVA_BUFFER;
#endif #endif
@@ -15,8 +24,10 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
import speiger.src.collections.PACKAGE.lists.ABSTRACT_LIST; import speiger.src.collections.PACKAGE.lists.ABSTRACT_LIST;
import speiger.src.collections.PACKAGE.lists.LIST; import speiger.src.collections.PACKAGE.lists.LIST;
#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.PACKAGE.utils.ARRAYS;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/** /**
@@ -27,7 +38,7 @@ public class LISTS
/** /**
* Empty List reference * Empty List reference
*/ */
public static final EmptyList NO_GENERIC_TYPE EMPTY = new EmptyListBRACES(); private static final EmptyList NO_GENERIC_TYPE EMPTY = new EmptyListBRACES();
/** /**
* Returns a Immutable EmptyList instance that is automatically casted. * Returns a Immutable EmptyList instance that is automatically casted.
@@ -59,7 +70,11 @@ public class LISTS
* @return a synchronized list wrapper. If the list is implementing RandomAccess or IARRAY that is also transferred. If the List already a synchronized wrapper then it just returns itself. * @return a synchronized list wrapper. If the list is implementing RandomAccess or IARRAY that is also transferred. If the List already a synchronized wrapper then it just returns itself.
*/ */
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE synchronize(LIST KEY_GENERIC_TYPE l) { public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE synchronize(LIST KEY_GENERIC_TYPE l) {
#if IARRAY_FEATURE
return l instanceof SynchronizedList ? l : (l instanceof IARRAY ? new SynchronizedArrayListBRACES(l) : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l) : new SynchronizedListBRACES(l))); return l instanceof SynchronizedList ? l : (l instanceof IARRAY ? new SynchronizedArrayListBRACES(l) : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l) : new SynchronizedListBRACES(l)));
#else
return l instanceof SynchronizedList ? l : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l) : new SynchronizedListBRACES(l));
#endif
} }
/** /**
@@ -70,7 +85,11 @@ public class LISTS
* @return a synchronized list wrapper. If the list is implementing RandomAccess or IARRAY that is also transferred. If the List already a synchronized wrapper then it just returns itself. * @return a synchronized list wrapper. If the list is implementing RandomAccess or IARRAY that is also transferred. If the List already a synchronized wrapper then it just returns itself.
*/ */
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE synchronize(LIST KEY_GENERIC_TYPE l, Object mutex) { public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE synchronize(LIST KEY_GENERIC_TYPE l, Object mutex) {
#if IARRAY_FEATURE
return l instanceof SynchronizedList ? l : (l instanceof IARRAY ? new SynchronizedArrayListBRACES(l, mutex) : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l, mutex) : new SynchronizedListBRACES(l, mutex))); return l instanceof SynchronizedList ? l : (l instanceof IARRAY ? new SynchronizedArrayListBRACES(l, mutex) : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l, mutex) : new SynchronizedListBRACES(l, mutex)));
#else
return l instanceof SynchronizedList ? l : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l, mutex) : new SynchronizedListBRACES(l, mutex));
#endif
} }
/** /**
@@ -91,6 +110,7 @@ public class LISTS
*/ */
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE reverse(LIST KEY_GENERIC_TYPE list) { public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE reverse(LIST KEY_GENERIC_TYPE list) {
int size = list.size(); int size = list.size();
#if IARRAY_FEATURE
if(list instanceof IARRAY) { if(list instanceof IARRAY) {
IARRAY KEY_GENERIC_TYPE array = (IARRAY KEY_GENERIC_TYPE)list; IARRAY KEY_GENERIC_TYPE array = (IARRAY KEY_GENERIC_TYPE)list;
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -105,6 +125,7 @@ public class LISTS
return list; return list;
#endif #endif
} }
#endif
if(list instanceof RandomAccess) { if(list instanceof RandomAccess) {
for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) { for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) {
KEY_TYPE t = list.GET_KEY(i); KEY_TYPE t = list.GET_KEY(i);
@@ -140,8 +161,9 @@ public class LISTS
* @Type(T) * @Type(T)
* @return the input list * @return the input list
*/ */
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE shuffle(LIST KEY_GENERIC_TYPE list, Random random) { public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE shuffle(LIST KEY_GENERIC_TYPE list, RANDOM random) {
int size = list.size(); int size = list.size();
#if IARRAY_FEATURE
if(list instanceof IARRAY) { if(list instanceof IARRAY) {
IARRAY KEY_GENERIC_TYPE array = (IARRAY KEY_GENERIC_TYPE)list; IARRAY KEY_GENERIC_TYPE array = (IARRAY KEY_GENERIC_TYPE)list;
#if TYPE_OBJECT #if TYPE_OBJECT
@@ -163,7 +185,8 @@ public class LISTS
#endif #endif
return list; return list;
} }
for(int i = list.size(); i-- != 0;) { #endif
for(int i = size; i-- != 0;) {
int p = random.nextInt(i + 1); int p = random.nextInt(i + 1);
KEY_TYPE t = list.GET_KEY(i); KEY_TYPE t = list.GET_KEY(i);
list.set(i, list.GET_KEY(p)); list.set(i, list.GET_KEY(p));
@@ -230,6 +253,7 @@ public class LISTS
public SingletonList KEY_GENERIC_TYPE copy() { return new SingletonListBRACES(element); } public SingletonList KEY_GENERIC_TYPE copy() { return new SingletonListBRACES(element); }
} }
#if IARRAY_FEATURE
private static class SynchronizedArrayList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements IARRAY KEY_GENERIC_TYPE private static class SynchronizedArrayList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements IARRAY KEY_GENERIC_TYPE
{ {
IARRAY KEY_GENERIC_TYPE l; IARRAY KEY_GENERIC_TYPE l;
@@ -270,6 +294,7 @@ public class LISTS
} }
} }
#endif
private static class SynchronizedRandomAccessList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements RandomAccess private static class SynchronizedRandomAccessList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements RandomAccess
{ {
SynchronizedRandomAccessList(LIST KEY_GENERIC_TYPE l) { SynchronizedRandomAccessList(LIST KEY_GENERIC_TYPE l) {
@@ -356,7 +381,7 @@ public class LISTS
#endif #endif
@Override @Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) { synchronized(mutex) { addElements(from, a, offset, length); } } public void addElements(int from, KEY_TYPE[] a, int offset, int length) { synchronized(mutex) { l.addElements(from, a, offset, length); } }
@Override @Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { synchronized(mutex) { return l.getElements(from, a, offset, length); } } public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { synchronized(mutex) { return l.getElements(from, a, offset, length); } }
@@ -386,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); } }
@@ -508,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(); }
@@ -601,9 +660,34 @@ 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
public int hashCode() { return 1; }
@Override
public boolean equals(Object o) {
if(o == this) return true;
if(!(o instanceof List)) return false;
return ((List<?>)o).isEmpty();
}
@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(); }
@@ -5,18 +5,25 @@ import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.function.Consumer; import java.util.function.Consumer;
#endif #endif
#if JDK_FUNCTION
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
#if DEQUEUE_FEATURE
import speiger.src.collections.PACKAGE.queues.PRIORITY_DEQUEUE; import speiger.src.collections.PACKAGE.queues.PRIORITY_DEQUEUE;
#endif
import speiger.src.collections.PACKAGE.queues.PRIORITY_QUEUE; import speiger.src.collections.PACKAGE.queues.PRIORITY_QUEUE;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif #endif
#if !JDK_FUNCTION
import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
/** /**
@@ -46,6 +53,7 @@ public class PRIORITY_QUEUES
return queue instanceof SynchronizedPriorityQueue ? (SynchronizedPriorityQueue KEY_GENERIC_TYPE)queue : new SynchronizedPriorityQueueBRACES(queue, mutex); return queue instanceof SynchronizedPriorityQueue ? (SynchronizedPriorityQueue KEY_GENERIC_TYPE)queue : new SynchronizedPriorityQueueBRACES(queue, mutex);
} }
#if DEQUEUE_FEATURE
/** /**
* Returns a synchronized PriorityDequeue instance based on the instance given. * Returns a synchronized PriorityDequeue instance based on the instance given.
* @param dequeue that should be synchronized * @param dequeue that should be synchronized
@@ -67,6 +75,7 @@ public class PRIORITY_QUEUES
return dequeue instanceof SynchronizedPriorityDequeue ? (SynchronizedPriorityDequeue KEY_GENERIC_TYPE)dequeue : new SynchronizedPriorityDequeueBRACES(dequeue, mutex); return dequeue instanceof SynchronizedPriorityDequeue ? (SynchronizedPriorityDequeue KEY_GENERIC_TYPE)dequeue : new SynchronizedPriorityDequeueBRACES(dequeue, mutex);
} }
#endif
/** /**
* Wrapper class for synchronization * Wrapper class for synchronization
* @Type(T) * @Type(T)
@@ -107,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); } }
@@ -134,6 +145,7 @@ public class PRIORITY_QUEUES
public int count(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.count(filter); } } public int count(PREDICATE KEY_GENERIC_TYPE filter) { synchronized(mutex) { return queue.count(filter); } }
} }
#if DEQUEUE_FEATURE
/** /**
* Wrapper class for synchronization * Wrapper class for synchronization
* @Type(T) * @Type(T)
@@ -166,4 +178,5 @@ public class PRIORITY_QUEUES
@Override @Override
public PRIORITY_DEQUEUE KEY_GENERIC_TYPE copy() { synchronized(mutex) { return dequeue.copy(); } } public PRIORITY_DEQUEUE KEY_GENERIC_TYPE copy() { synchronized(mutex) { return dequeue.copy(); } }
} }
#endif
} }
@@ -1,30 +1,31 @@
package speiger.src.collections.PACKAGE.utils; package speiger.src.collections.PACKAGE.utils;
#if TYPE_BOOLEAN import java.util.NoSuchElementException;
import speiger.src.collections.booleans.collections.BooleanIterator; import java.util.Set;
import speiger.src.collections.booleans.sets.AbstractBooleanSet; #if TYPE_OBJECT && SORTED_SET_FEATURE
import speiger.src.collections.booleans.sets.BooleanSet;
import speiger.src.collections.booleans.utils.BooleanCollections.EmptyCollection;
#else
#if TYPE_OBJECT
import java.util.Comparator; import java.util.Comparator;
#endif #endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT && SORTED_SET_FEATURE
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if SORTED_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET; import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
#endif
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SET;
#if ORDERED_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.ORDERED_SET; import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
#endif
#if SORTED_SET_FEATURE
import speiger.src.collections.PACKAGE.sets.SORTED_SET; import speiger.src.collections.PACKAGE.sets.SORTED_SET;
#endif
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.EmptyCollection; import speiger.src.collections.PACKAGE.utils.COLLECTIONS.EmptyCollection;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.SynchronizedCollection; import speiger.src.collections.PACKAGE.utils.COLLECTIONS.SynchronizedCollection;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.UnmodifiableCollection; import speiger.src.collections.PACKAGE.utils.COLLECTIONS.UnmodifiableCollection;
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
#endif
/** /**
* A Helper class for sets * A Helper class for sets
@@ -34,7 +35,7 @@ public class SETS
/** /**
* Empty Set Variable * Empty Set Variable
*/ */
public static final SET NO_GENERIC_TYPE EMPTY = new EmptySetBRACES(); private static final SET NO_GENERIC_TYPE EMPTY = new EmptySetBRACES();
/** /**
* EmptySet getter * EmptySet getter
@@ -49,7 +50,6 @@ public class SETS
#endif #endif
} }
#if !TYPE_BOOLEAN
/** /**
* Creates a Synchronized set while preserving the ITrimmable interface * Creates a Synchronized set while preserving the ITrimmable interface
* @param s the set that should be synchronized * @param s the set that should be synchronized
@@ -73,6 +73,7 @@ public class SETS
return s instanceof SynchronizedSet ? s : (s instanceof ITrimmable ? new SynchronizedTrimSetBRACES(s, mutex) : new SynchronizedSetBRACES(s, mutex)); return s instanceof SynchronizedSet ? s : (s instanceof ITrimmable ? new SynchronizedTrimSetBRACES(s, mutex) : new SynchronizedSetBRACES(s, mutex));
} }
#if SORTED_SET_FEATURE
/** /**
* Creates a Synchronized SortedSet while preserving the ITrimmable interface * Creates a Synchronized SortedSet while preserving the ITrimmable interface
* @param s the set that should be synchronized * @param s the set that should be synchronized
@@ -96,6 +97,8 @@ public class SETS
return s instanceof SynchronizedSortedSet ? s : (s instanceof ITrimmable ? new SynchronizedSortedTrimSetBRACES(s, mutex) : new SynchronizedSortedSetBRACES(s, mutex)); return s instanceof SynchronizedSortedSet ? s : (s instanceof ITrimmable ? new SynchronizedSortedTrimSetBRACES(s, mutex) : new SynchronizedSortedSetBRACES(s, mutex));
} }
#endif
#if ORDERED_SET_FEATURE
/** /**
* Creates a Synchronized OrderedSet while preserving the ITrimmable interface * Creates a Synchronized OrderedSet while preserving the ITrimmable interface
* @param s the set that should be synchronized * @param s the set that should be synchronized
@@ -119,6 +122,8 @@ public class SETS
return s instanceof SynchronizedOrderedSet ? s : (s instanceof ITrimmable ? new SynchronizedOrderedTrimSetBRACES(s, mutex) : new SynchronizedOrderedSetBRACES(s, mutex)); return s instanceof SynchronizedOrderedSet ? s : (s instanceof ITrimmable ? new SynchronizedOrderedTrimSetBRACES(s, mutex) : new SynchronizedOrderedSetBRACES(s, mutex));
} }
#endif
#if SORTED_SET_FEATURE
/** /**
* Creates a Synchronized NavigableSet while preserving the ITrimmable interface * Creates a Synchronized NavigableSet while preserving the ITrimmable interface
* @param s the set that should be synchronized * @param s the set that should be synchronized
@@ -142,6 +147,7 @@ public class SETS
return s instanceof SynchronizedNavigableSet ? s : (s instanceof ITrimmable ? new SynchronizedNavigableTrimSetBRACES(s, mutex) : new SynchronizedNavigableSetBRACES(s, mutex)); return s instanceof SynchronizedNavigableSet ? s : (s instanceof ITrimmable ? new SynchronizedNavigableTrimSetBRACES(s, mutex) : new SynchronizedNavigableSetBRACES(s, mutex));
} }
#endif
/** /**
* Creates Unmodifyable Set wrapper * Creates Unmodifyable Set wrapper
* @param s set that should be made unmodifiable * @param s set that should be made unmodifiable
@@ -152,6 +158,7 @@ public class SETS
return s instanceof UnmodifiableSet ? s : new UnmodifiableSetBRACES(s); return s instanceof UnmodifiableSet ? s : new UnmodifiableSetBRACES(s);
} }
#if SORTED_SET_FEATURE
/** /**
* Creates Unmodifyable SortedSet wrapper * Creates Unmodifyable SortedSet wrapper
* @param s sortedSet that should be made unmodifiable * @param s sortedSet that should be made unmodifiable
@@ -162,6 +169,8 @@ public class SETS
return s instanceof UnmodifiableSortedSet ? s : new UnmodifiableSortedSetBRACES(s); return s instanceof UnmodifiableSortedSet ? s : new UnmodifiableSortedSetBRACES(s);
} }
#endif
#if ORDERED_SET_FEATURE
/** /**
* Creates Unmodifyable OrderedSet wrapper * Creates Unmodifyable OrderedSet wrapper
* @param s OrderedSet that should be made unmodifiable * @param s OrderedSet that should be made unmodifiable
@@ -172,6 +181,8 @@ public class SETS
return s instanceof UnmodifiableOrderedSet ? s : new UnmodifiableOrderedSetBRACES(s); return s instanceof UnmodifiableOrderedSet ? s : new UnmodifiableOrderedSetBRACES(s);
} }
#endif
#if SORTED_SET_FEATURE
/** /**
* Creates Unmodifyable NavigableSet wrapper * Creates Unmodifyable NavigableSet wrapper
* @param s navigableSet that should be made unmodifiable * @param s navigableSet that should be made unmodifiable
@@ -216,10 +227,10 @@ public class SETS
return new ITERATOR KEY_GENERIC_TYPE() { return new ITERATOR KEY_GENERIC_TYPE() {
boolean next = true; boolean next = true;
@Override @Override
public boolean hasNext() { return next = false; } public boolean hasNext() { return next; }
@Override @Override
public KEY_TYPE NEXT() { public KEY_TYPE NEXT() {
if(!next) throw new IllegalStateException(); if(!hasNext()) throw new NoSuchElementException();
next = false; next = false;
return element; return element;
} }
@@ -241,11 +252,18 @@ public class SETS
@Override @Override
public KEY_TYPE addOrGet(KEY_TYPE o) { throw new UnsupportedOperationException(); } public KEY_TYPE addOrGet(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif #endif
@Override
public boolean equals(Object o) {
if(o == this) return true;
if(!(o instanceof Set)) return false;
return ((Set<?>)o).isEmpty();
}
@Override @Override
public EmptySet KEY_GENERIC_TYPE copy() { return this; } public EmptySet KEY_GENERIC_TYPE copy() { return this; }
} }
#if !TYPE_BOOLEAN #if SORTED_SET_FEATURE
private static class UnmodifiableNavigableSet KEY_GENERIC_TYPE extends UnmodifiableSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE private static class UnmodifiableNavigableSet KEY_GENERIC_TYPE extends UnmodifiableSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{ {
NAVIGABLE_SET KEY_GENERIC_TYPE n; NAVIGABLE_SET KEY_GENERIC_TYPE n;
@@ -258,25 +276,38 @@ public class SETS
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public boolean contains(KEY_TYPE o) { return n.contains(o); } public boolean contains(KEY_TYPE o) { return n.contains(o); }
@Override
@SuppressWarnings("deprecation")
public CLASS_TYPE lower(CLASS_TYPE e) { return n.lower(e); }
@Override
@SuppressWarnings("deprecation")
public CLASS_TYPE floor(CLASS_TYPE e) { return n.floor(e); }
@Override
@SuppressWarnings("deprecation")
public CLASS_TYPE ceiling(CLASS_TYPE e) { return n.ceiling(e); }
@Override
@SuppressWarnings("deprecation")
public CLASS_TYPE higher(CLASS_TYPE e) { return n.higher(e); }
#endif #endif
@Override @Override
@Deprecated @Deprecated
public boolean contains(Object o) { return n.contains(o); } public boolean contains(Object o) { return n.contains(o); }
@Override @Override
public KEY_TYPE lower(KEY_TYPE e) { return n.lower(e); } public KEY_TYPE lower(KEY_TYPE e) { return n.lower(e); }
@Override @Override
public KEY_TYPE floor(KEY_TYPE e) { return n.floor(e); } public KEY_TYPE floor(KEY_TYPE e) { return n.floor(e); }
@Override @Override
public KEY_TYPE ceiling(KEY_TYPE e) { return n.ceiling(e); } public KEY_TYPE ceiling(KEY_TYPE e) { return n.ceiling(e); }
@Override @Override
public KEY_TYPE higher(KEY_TYPE e) { return n.higher(e); } public KEY_TYPE higher(KEY_TYPE e) { return n.higher(e); }
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override
public CLASS_TYPE pollFirst() { throw new UnsupportedOperationException(); }
@Override
public CLASS_TYPE pollLast() { throw new UnsupportedOperationException(); }
@Override @Override
public void setDefaultMaxValue(KEY_TYPE e) { throw new UnsupportedOperationException(); } public void setDefaultMaxValue(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@@ -291,7 +322,7 @@ public class SETS
#endif #endif
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public NAVIGABLE_SET KEY_GENERIC_TYPE copy() { return n.copy(); }
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { return SETS.unmodifiable(n.subSet(fromElement, fromInclusive, toElement, toInclusive)); } public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { return SETS.unmodifiable(n.subSet(fromElement, fromInclusive, toElement, toInclusive)); }
@@ -318,6 +349,8 @@ public class SETS
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return SETS.unmodifiable(n.tailSet(fromElement)); } public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return SETS.unmodifiable(n.tailSet(fromElement)); }
} }
#endif
#if ORDERED_SET_FEATURE
private static class UnmodifiableOrderedSet KEY_GENERIC_TYPE extends UnmodifiableSet KEY_GENERIC_TYPE implements ORDERED_SET KEY_GENERIC_TYPE private static class UnmodifiableOrderedSet KEY_GENERIC_TYPE extends UnmodifiableSet KEY_GENERIC_TYPE implements ORDERED_SET KEY_GENERIC_TYPE
{ {
ORDERED_SET KEY_GENERIC_TYPE s; ORDERED_SET KEY_GENERIC_TYPE s;
@@ -351,6 +384,8 @@ public class SETS
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); }
} }
#endif
#if SORTED_SET_FEATURE
private static class UnmodifiableSortedSet KEY_GENERIC_TYPE extends UnmodifiableSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE private static class UnmodifiableSortedSet KEY_GENERIC_TYPE extends UnmodifiableSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{ {
SORTED_SET KEY_GENERIC_TYPE s; SORTED_SET KEY_GENERIC_TYPE s;
@@ -384,6 +419,7 @@ public class SETS
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); }
} }
#endif
/** /**
* Unmodifyable Set wrapper that helps is used with unmodifyableSet function * Unmodifyable Set wrapper that helps is used with unmodifyableSet function
* @Type(T) * @Type(T)
@@ -412,6 +448,7 @@ public class SETS
#endif #endif
} }
#if SORTED_SET_FEATURE
private static class SynchronizedNavigableTrimSet KEY_GENERIC_TYPE extends SynchronizedNavigableSet KEY_GENERIC_TYPE implements ITrimmable private static class SynchronizedNavigableTrimSet KEY_GENERIC_TYPE extends SynchronizedNavigableSet KEY_GENERIC_TYPE implements ITrimmable
{ {
ITrimmable trim; ITrimmable trim;
@@ -454,27 +491,33 @@ public class SETS
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public boolean contains(KEY_TYPE o) { synchronized(mutex) { return n.contains(o); } } public boolean contains(KEY_TYPE o) { synchronized(mutex) { return n.contains(o); } }
@Override
@SuppressWarnings("deprecation")
public CLASS_TYPE lower(CLASS_TYPE e) { synchronized(mutex) { return n.lower(e); } }
@Override
@SuppressWarnings("deprecation")
public CLASS_TYPE floor(CLASS_TYPE e) { synchronized(mutex) { return n.floor(e); } }
@Override
@SuppressWarnings("deprecation")
public CLASS_TYPE ceiling(CLASS_TYPE e) { synchronized(mutex) { return n.ceiling(e); } }
@Override
@SuppressWarnings("deprecation")
public CLASS_TYPE higher(CLASS_TYPE e) { synchronized(mutex) { return n.higher(e); } }
#endif #endif
@Override @Override
public KEY_TYPE lower(KEY_TYPE e) { synchronized(mutex) { return n.lower(e); } } public KEY_TYPE lower(KEY_TYPE e) { synchronized(mutex) { return n.lower(e); } }
@Override @Override
public KEY_TYPE floor(KEY_TYPE e) { synchronized(mutex) { return n.floor(e); } } public KEY_TYPE floor(KEY_TYPE e) { synchronized(mutex) { return n.floor(e); } }
@Override @Override
public KEY_TYPE ceiling(KEY_TYPE e) { synchronized(mutex) { return n.ceiling(e); } } public KEY_TYPE ceiling(KEY_TYPE e) { synchronized(mutex) { return n.ceiling(e); } }
@Override @Override
public KEY_TYPE higher(KEY_TYPE e) { synchronized(mutex) { return n.higher(e); } } public KEY_TYPE higher(KEY_TYPE e) { synchronized(mutex) { return n.higher(e); } }
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
public void setDefaultMaxValue(KEY_TYPE e) { synchronized(mutex) { n.setDefaultMaxValue(e); } } public void setDefaultMaxValue(KEY_TYPE e) { synchronized(mutex) { n.setDefaultMaxValue(e); } }
@Override @Override
public KEY_TYPE getDefaultMaxValue() { synchronized(mutex) { return n.getDefaultMaxValue(); } } public KEY_TYPE getDefaultMaxValue() { synchronized(mutex) { return n.getDefaultMaxValue(); } }
@Override @Override
public void setDefaultMinValue(KEY_TYPE e) { synchronized(mutex) { n.setDefaultMinValue(e); } } public void setDefaultMinValue(KEY_TYPE e) { synchronized(mutex) { n.setDefaultMinValue(e); } }
@@ -569,6 +612,8 @@ public class SETS
public KEY_TYPE POLL_LAST_KEY() { synchronized(mutex) { return s.POLL_LAST_KEY(); } } public KEY_TYPE POLL_LAST_KEY() { synchronized(mutex) { return s.POLL_LAST_KEY(); } }
} }
#endif
#if ORDERED_SET_FEATURE
private static class SynchronizedOrderedTrimSet KEY_GENERIC_TYPE extends SynchronizedOrderedSet KEY_GENERIC_TYPE implements ITrimmable private static class SynchronizedOrderedTrimSet KEY_GENERIC_TYPE extends SynchronizedOrderedSet KEY_GENERIC_TYPE implements ITrimmable
{ {
ITrimmable trim; ITrimmable trim;
@@ -628,6 +673,7 @@ public class SETS
public KEY_TYPE POLL_LAST_KEY() { synchronized(mutex) { return s.POLL_LAST_KEY(); } } public KEY_TYPE POLL_LAST_KEY() { synchronized(mutex) { return s.POLL_LAST_KEY(); } }
} }
#endif
private static class SynchronizedTrimSet KEY_GENERIC_TYPE extends SynchronizedSet KEY_GENERIC_TYPE implements ITrimmable private static class SynchronizedTrimSet KEY_GENERIC_TYPE extends SynchronizedSet KEY_GENERIC_TYPE implements ITrimmable
{ {
ITrimmable trim; ITrimmable trim;
@@ -676,5 +722,4 @@ public class SETS
public boolean remove(KEY_TYPE o) { synchronized(mutex) { return s.remove(o); } } public boolean remove(KEY_TYPE o) { synchronized(mutex) { return s.remove(o); } }
#endif #endif
} }
#endif
} }
@@ -1,6 +1,7 @@
package speiger.src.collections.PACKAGE.utils; package speiger.src.collections.PACKAGE.utils;
import java.util.Comparator; import java.util.Comparator;
import java.util.NoSuchElementException;
import java.util.Spliterator; import java.util.Spliterator;
#if PRIMITIVES #if PRIMITIVES
import java.util.Spliterator.JAVA_SPLIT_ITERATOR; import java.util.Spliterator.JAVA_SPLIT_ITERATOR;
@@ -329,7 +330,11 @@ public class SPLIT_ITERATORS
} }
@Override @Override
public KEY_TYPE NEXT() { return array[index++]; } public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
return array[index++];
}
@Override @Override
public boolean hasNext() { return index < fence; } public boolean hasNext() { return index < fence; }
} }
@@ -1,5 +1,7 @@
package speiger.src.collections.PACKAGE.utils; package speiger.src.collections.PACKAGE.utils;
import java.util.Objects;
/** /**
* A Type Specific Strategy class that allows to give control hashcode generation and equals comparason for maps * A Type Specific Strategy class that allows to give control hashcode generation and equals comparason for maps
* @Type(T) * @Type(T)
@@ -19,6 +21,17 @@ public interface STRATEGY KEY_GENERIC_TYPE
public static GENERIC_KEY_BRACES STRATEGY KEY_GENERIC_TYPE identityStrategy() { return (STRATEGY<KEY_TYPE>)IDENTITY; } public static GENERIC_KEY_BRACES STRATEGY KEY_GENERIC_TYPE identityStrategy() { return (STRATEGY<KEY_TYPE>)IDENTITY; }
#endif #endif
/**
* Normal Strategy
*/
public static final STRATEGY NO_GENERIC_TYPE NORMAL = new NormalStrategyBRACES();
/**
* @Type(T)
* @return a Normal Strategy that is behaving exactly like the normal Hash Strategy in the Hash Collections
*/
public static GENERIC_KEY_BRACES STRATEGY KEY_GENERIC_TYPE normalStrategy() { return (STRATEGY KEY_GENERIC_TYPE)NORMAL; }
/** /**
* Type Specific HashCode function * Type Specific HashCode function
* @param o the element that the hashcode is requested for (if object may be null) * @param o the element that the hashcode is requested for (if object may be null)
@@ -47,5 +60,18 @@ public interface STRATEGY KEY_GENERIC_TYPE
@Override @Override
public boolean equals(KEY_TYPE key, KEY_TYPE value) { return key == value; } public boolean equals(KEY_TYPE key, KEY_TYPE value) { return key == value; }
} }
#endif #endif
/**
* A Strategy that simulates the normal Hash Collection Behavior if you want to use Hash Control Collections to replace normal ones.
* Only real reason to do that is you have to use this and want to get rid of implementations.
* @Type(T)
*/
public static class NormalStrategy KEY_GENERIC_TYPE implements STRATEGY KEY_GENERIC_TYPE
{
@Override
public int hashCode(KEY_TYPE o) { return KEY_TO_HASH(o); }
@Override
public boolean equals(KEY_TYPE key, KEY_TYPE value) { return EQUALS_KEY_TYPE(key, value); }
}
} }
@@ -3,9 +3,9 @@ package speiger.src.collections.PACKAGE.utils.maps;
#if !TYPE_BOOLEAN #if !TYPE_BOOLEAN
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
#if TYPE_OBJECT #if TYPE_OBJECT && SORTED_MAP_FEATURE
import java.util.Comparator; import java.util.Comparator;
#else #else if !TYPE_OBJECT
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
#endif #endif
@@ -14,26 +14,43 @@ import java.util.function.Consumer;
#if !TYPE_OBJECT && !TYPE_BOOLEAN #if !TYPE_OBJECT && !TYPE_BOOLEAN
import java.util.function.Function; import java.util.function.Function;
#endif #endif
#if VALUE_BOOLEAN && JDK_TYPE
import java.util.function.PREDICATE;
#endif
import speiger.src.collections.objects.collections.ObjectIterable; 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.objects.sets.ObjectSet; import speiger.src.collections.objects.sets.ObjectSet;
#if !TYPE_BOOLEAN import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
import speiger.src.collections.objects.utils.ObjectIterators;
import speiger.src.collections.objects.utils.ObjectSets; import speiger.src.collections.objects.utils.ObjectSets;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.objects.sets.ObjectOrderedSet;
#if SORTED_MAP_FEATURE
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
#endif
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
#if !VALUE_BOOLEAN || !JDK_TYPE
import speiger.src.collections.PACKAGE.functions.function.FUNCTION; import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
#endif
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
#endif
import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
#if !TYPE_BOOLEAN #if SORTED_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.interfaces.NAVIGABLE_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.NAVIGABLE_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.SORTED_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.SORTED_MAP;
#endif
#if ORDERED_MAP_FEATURE
import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.ORDERED_MAP;
#endif
#if SORTED_MAP_FEATURE
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET; import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
import speiger.src.collections.PACKAGE.sets.SORTED_SET;
#endif
#if ORDERED_MAP_FEATURE
import speiger.src.collections.PACKAGE.sets.ORDERED_SET;
#endif
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.utils.SETS; import speiger.src.collections.PACKAGE.utils.SETS;
@@ -42,11 +59,8 @@ import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
#if !SAME_TYPE #if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR; import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
#endif #endif
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER;
import speiger.src.collections.VALUE_PACKAGE.utils.VALUE_COLLECTIONS; import speiger.src.collections.VALUE_PACKAGE.utils.VALUE_COLLECTIONS;
#if !SAME_TYPE && !VALUE_OBJECT
import speiger.src.collections.VALUE_PACKAGE.utils.VALUE_SETS;
#endif
#endif
/** /**
* A Helper class that provides you with Singleton/Empty/Synchronized/Unmodifyable Maps * A Helper class that provides you with Singleton/Empty/Synchronized/Unmodifyable Maps
@@ -57,7 +71,21 @@ public class MAPS
/** /**
* Empty Map Variable * Empty Map Variable
*/ */
public static final MAP NO_KV_GENERIC_TYPE EMPTY = new EmptyMapKV_BRACES(); private static final MAP NO_KV_GENERIC_TYPE EMPTY = new EmptyMapKV_BRACES();
/**
* Empty Map getter function that autocasts to the desired Key and Value
* @Type(T)
* @ValueType(V)
* @return empty map of desired type
*/
public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE empty() {
#if TYPE_OBJECT || VALUE_OBJECT
return (MAP KEY_VALUE_GENERIC_TYPE)EMPTY;
#else
return EMPTY;
#endif
}
#endif #endif
/** /**
@@ -103,21 +131,6 @@ public class MAPS
else entries.forEach(action); else entries.forEach(action);
} }
#if !TYPE_BOOLEAN
/**
* Empty Map getter function that autocasts to the desired Key and Value
* @Type(T)
* @ValueType(V)
* @return empty map of desired type
*/
public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE empty() {
#if TYPE_OBJECT || VALUE_OBJECT
return (MAP KEY_VALUE_GENERIC_TYPE)EMPTY;
#else
return EMPTY;
#endif
}
/** /**
* Helper function that creates a Helper wrapper to synchronize access into the map. * Helper function that creates a Helper wrapper to synchronize access into the map.
* @param map the map that should be synchronized * @param map the map that should be synchronized
@@ -140,6 +153,7 @@ public class MAPS
*/ */
public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE synchronize(MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedMap ? map : new SynchronizedMapKV_BRACES(map, mutex); } public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE synchronize(MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedMap ? map : new SynchronizedMapKV_BRACES(map, mutex); }
#if SORTED_MAP_FEATURE
/** /**
* Helper function that creates a Helper wrapper to synchronize access into the SortedMap. * Helper function that creates a Helper wrapper to synchronize access into the SortedMap.
* @param map the SortedMap that should be synchronized * @param map the SortedMap that should be synchronized
@@ -162,6 +176,8 @@ public class MAPS
*/ */
public static GENERIC_KEY_VALUE_BRACES SORTED_MAP KEY_VALUE_GENERIC_TYPE synchronize(SORTED_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedSortedMap ? map : new SynchronizedSortedMapKV_BRACES(map, mutex); } public static GENERIC_KEY_VALUE_BRACES SORTED_MAP KEY_VALUE_GENERIC_TYPE synchronize(SORTED_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedSortedMap ? map : new SynchronizedSortedMapKV_BRACES(map, mutex); }
#endif
#if ORDERED_MAP_FEATURE
/** /**
* Helper function that creates a Helper wrapper to synchronize access into the OrderedMap. * Helper function that creates a Helper wrapper to synchronize access into the OrderedMap.
* @param map the OrderedMap that should be synchronized * @param map the OrderedMap that should be synchronized
@@ -184,6 +200,8 @@ public class MAPS
*/ */
public static GENERIC_KEY_VALUE_BRACES ORDERED_MAP KEY_VALUE_GENERIC_TYPE synchronize(ORDERED_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedOrderedMap ? map : new SynchronizedOrderedMapKV_BRACES(map, mutex); } public static GENERIC_KEY_VALUE_BRACES ORDERED_MAP KEY_VALUE_GENERIC_TYPE synchronize(ORDERED_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedOrderedMap ? map : new SynchronizedOrderedMapKV_BRACES(map, mutex); }
#endif
#if SORTED_MAP_FEATURE
/** /**
* Helper function that creates a Helper wrapper to synchronize access into the NavigableMap. * Helper function that creates a Helper wrapper to synchronize access into the NavigableMap.
* @param map the NavigableMap that should be synchronized * @param map the NavigableMap that should be synchronized
@@ -206,6 +224,7 @@ public class MAPS
*/ */
public static GENERIC_KEY_VALUE_BRACES NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE synchronize(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedNavigableMap ? map : new SynchronizedNavigableMapKV_BRACES(map, mutex); } public static GENERIC_KEY_VALUE_BRACES NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE synchronize(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedNavigableMap ? map : new SynchronizedNavigableMapKV_BRACES(map, mutex); }
#endif
/** /**
* A Helper function that creates a Helper wrapper to only allow Read Access into the Map * A Helper function that creates a Helper wrapper to only allow Read Access into the Map
* @param map the map that should be made Unmodifiable * @param map the map that should be made Unmodifiable
@@ -216,6 +235,7 @@ public class MAPS
*/ */
public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE unmodifiable(MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableMap ? map : new UnmodifyableMapKV_BRACES(map); } public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE unmodifiable(MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableMap ? map : new UnmodifyableMapKV_BRACES(map); }
#if ORDERED_MAP_FEATURE
/** /**
* A Helper function that creates a Helper wrapper to only allow Read Access into the OrderedMap * A Helper function that creates a Helper wrapper to only allow Read Access into the OrderedMap
* @param map the OrderedMap that should be made Unmodifiable * @param map the OrderedMap that should be made Unmodifiable
@@ -226,6 +246,8 @@ public class MAPS
*/ */
public static GENERIC_KEY_VALUE_BRACES ORDERED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable(ORDERED_MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableOrderedMap ? map : new UnmodifyableOrderedMapKV_BRACES(map); } public static GENERIC_KEY_VALUE_BRACES ORDERED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable(ORDERED_MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableOrderedMap ? map : new UnmodifyableOrderedMapKV_BRACES(map); }
#endif
#if SORTED_MAP_FEATURE
/** /**
* A Helper function that creates a Helper wrapper to only allow Read Access into the SortedMap * A Helper function that creates a Helper wrapper to only allow Read Access into the SortedMap
* @param map the SortedMap that should be made Unmodifiable * @param map the SortedMap that should be made Unmodifiable
@@ -246,6 +268,7 @@ public class MAPS
*/ */
public static GENERIC_KEY_VALUE_BRACES NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE unmodifiable(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableNavigableMap ? map : new UnmodifyableNavigableMapKV_BRACES(map); } public static GENERIC_KEY_VALUE_BRACES NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE unmodifiable(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableNavigableMap ? map : new UnmodifyableNavigableMapKV_BRACES(map); }
#endif
/** /**
* A Helper function that creates a Unmodifyable Entry * A Helper function that creates a Unmodifyable Entry
* @param entry the Entry that should be made unmodifiable * @param entry the Entry that should be made unmodifiable
@@ -253,7 +276,7 @@ public class MAPS
* @ValueType(V) * @ValueType(V)
* @return a Unmodifyable Entry * @return a Unmodifyable Entry
*/ */
public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifiable(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { return entry instanceof UnmodifyableEntry ? entry : new UnmodifyableEntryKV_BRACES(entry); } public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifiable(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { return entry instanceof UnmodifyableEntry ? entry : (entry == null ? null : new UnmodifyableEntryKV_BRACES(entry)); }
/** /**
* A Helper function that creates a Unmodifyable Entry * A Helper function that creates a Unmodifyable Entry
* @param entry the Entry that should be made unmodifiable * @param entry the Entry that should be made unmodifiable
@@ -261,7 +284,7 @@ public class MAPS
* @ValueType(V) * @ValueType(V)
* @return a Unmodifyable Entry * @return a Unmodifyable Entry
*/ */
public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifiable(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) { return entry instanceof UnmodifyableEntry ? (UnmodifyableEntry KEY_VALUE_GENERIC_TYPE)entry : new UnmodifyableEntryKV_BRACES(entry); } public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifiable(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) { return entry instanceof UnmodifyableEntry ? (UnmodifyableEntry KEY_VALUE_GENERIC_TYPE)entry : (entry == null ? null : new UnmodifyableEntryKV_BRACES(entry)); }
/** /**
* Creates a Singleton map from the provided values. * Creates a Singleton map from the provided values.
@@ -315,6 +338,28 @@ public class MAPS
@Override @Override
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return EQUALS_KEY_TYPE(key, this.key) ? value : defaultValue; } public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return EQUALS_KEY_TYPE(key, this.key) ? value : defaultValue; }
#endif #endif
@Override
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
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
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
public SingletonMap KEY_VALUE_GENERIC_TYPE copy() { return new SingletonMapKV_BRACES(key, value); } public SingletonMap KEY_VALUE_GENERIC_TYPE copy() { return new SingletonMapKV_BRACES(key, value); }
@Override @Override
@@ -325,7 +370,7 @@ public class MAPS
@Override @Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
if(values == null) values = VALUE_SETS.singleton(value); if(values == null) values = VALUE_COLLECTIONS.singleton(value);
return values; return values;
} }
@Override @Override
@@ -363,8 +408,30 @@ public class MAPS
public VALUE_TYPE GET_VALUE(KEY_TYPE key) { return getDefaultReturnValue(); } public VALUE_TYPE GET_VALUE(KEY_TYPE key) { return getDefaultReturnValue(); }
#if !TYPE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT || !VALUE_OBJECT
@Override @Override
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return EMPTY_VALUE; } public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return defaultValue; }
#endif #endif
@Override
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
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
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override @Override
public SET KEY_GENERIC_TYPE keySet() { return SETS.empty(); } public SET KEY_GENERIC_TYPE keySet() { return SETS.empty(); }
@Override @Override
@@ -394,6 +461,7 @@ public class MAPS
public void set(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } public void set(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
} }
#if SORTED_MAP_FEATURE
/** /**
* The Unmodifyable Navigable Map implementation that is sued for the unmodifyableMap function * The Unmodifyable Navigable Map implementation that is sued for the unmodifyableMap function
* @Type(T) * @Type(T)
@@ -408,10 +476,12 @@ public class MAPS
} }
@Override @Override
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE descendingMap() { return MAPS.synchronize(map.descendingMap()); } public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE descendingMap() { return MAPS.unmodifiable(map.descendingMap()); }
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE navigableKeySet() { return SETS.unmodifiable(map.navigableKeySet()); } public NAVIGABLE_SET KEY_GENERIC_TYPE navigableKeySet() { return SETS.unmodifiable(map.navigableKeySet()); }
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE keySet() { return SETS.unmodifiable(map.keySet()); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet() { return SETS.unmodifiable(map.descendingKeySet()); } public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet() { return SETS.unmodifiable(map.descendingKeySet()); }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { return MAPS.unmodifiable(map.firstEntry()); } public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { return MAPS.unmodifiable(map.firstEntry()); }
@@ -460,9 +530,11 @@ public class MAPS
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key) { return MAPS.unmodifiable(map.ceilingEntry(key)); } public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key) { return MAPS.unmodifiable(map.ceilingEntry(key)); }
@Override @Override
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE copy() { return map.copy(); }
} }
#endif
#if ORDERED_MAP_FEATURE
/** /**
* The Unmodifyable Ordered Map implementation that is sued for the unmodifyableMap function * The Unmodifyable Ordered Map implementation that is sued for the unmodifyableMap function
* @Type(T) * @Type(T)
@@ -491,19 +563,32 @@ public class MAPS
@Override @Override
public KEY_TYPE FIRST_ENTRY_KEY() { return map.FIRST_ENTRY_KEY(); } public KEY_TYPE FIRST_ENTRY_KEY() { return map.FIRST_ENTRY_KEY(); }
@Override @Override
public KEY_TYPE POLL_FIRST_ENTRY_KEY() { return map.POLL_FIRST_ENTRY_KEY(); } public KEY_TYPE POLL_FIRST_ENTRY_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public KEY_TYPE LAST_ENTRY_KEY() { return map.LAST_ENTRY_KEY(); } public KEY_TYPE LAST_ENTRY_KEY() { return map.LAST_ENTRY_KEY(); }
@Override @Override
public KEY_TYPE POLL_LAST_ENTRY_KEY() { return map.POLL_LAST_ENTRY_KEY(); } public KEY_TYPE POLL_LAST_ENTRY_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public VALUE_TYPE FIRST_ENTRY_VALUE() { return map.FIRST_ENTRY_VALUE(); } public VALUE_TYPE FIRST_ENTRY_VALUE() { return map.FIRST_ENTRY_VALUE(); }
@Override @Override
public VALUE_TYPE LAST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); } public VALUE_TYPE LAST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); }
@Override @Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { return map.copy(); }
@Override
public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keys == null) keys = SETS.unmodifiable(map.keySet());
return (ORDERED_SET KEY_GENERIC_TYPE)keys;
} }
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new UnmodifyableOrderedEntrySetKV_BRACES(map.ENTRY_SET());
return (ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE>)entrySet;
}
}
#endif
#if SORTED_MAP_FEATURE
/** /**
* The Unmodifyable Sorted Map implementation that is sued for the unmodifyableMap function * The Unmodifyable Sorted Map implementation that is sued for the unmodifyableMap function
* @Type(T) * @Type(T)
@@ -526,21 +611,24 @@ public class MAPS
@Override @Override
public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { return MAPS.unmodifiable(map.tailMap(fromKey)); } public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { return MAPS.unmodifiable(map.tailMap(fromKey)); }
@Override @Override
public SORTED_SET KEY_GENERIC_TYPE keySet() { return SETS.unmodifiable(map.keySet()); }
@Override
public KEY_TYPE FIRST_ENTRY_KEY() { return map.FIRST_ENTRY_KEY(); } public KEY_TYPE FIRST_ENTRY_KEY() { return map.FIRST_ENTRY_KEY(); }
@Override @Override
public KEY_TYPE POLL_FIRST_ENTRY_KEY() { return map.POLL_FIRST_ENTRY_KEY(); } public KEY_TYPE POLL_FIRST_ENTRY_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public KEY_TYPE LAST_ENTRY_KEY() { return map.LAST_ENTRY_KEY(); } public KEY_TYPE LAST_ENTRY_KEY() { return map.LAST_ENTRY_KEY(); }
@Override @Override
public KEY_TYPE POLL_LAST_ENTRY_KEY() { return map.POLL_LAST_ENTRY_KEY(); } public KEY_TYPE POLL_LAST_ENTRY_KEY() { throw new UnsupportedOperationException(); }
@Override @Override
public VALUE_TYPE FIRST_ENTRY_VALUE() { return map.FIRST_ENTRY_VALUE(); } public VALUE_TYPE FIRST_ENTRY_VALUE() { return map.FIRST_ENTRY_VALUE(); }
@Override @Override
public VALUE_TYPE LAST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); } public VALUE_TYPE LAST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); }
@Override @Override
public SORTED_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public SORTED_MAP KEY_VALUE_GENERIC_TYPE copy() { return map.copy(); }
} }
#endif
/** /**
* The Unmodifyable Map implementation that is sued for the unmodifyableMap function * The Unmodifyable Map implementation that is sued for the unmodifyableMap function
* @Type(T) * @Type(T)
@@ -575,13 +663,44 @@ public class MAPS
public boolean remove(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } public boolean remove(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); }
#endif #endif
@Override @Override
public VALUE_TYPE GET_VALUE(KEY_TYPE key) { return map.GET_VALUE(key); } public VALUE_TYPE GET_VALUE(KEY_TYPE key) {
VALUE_TYPE type = map.GET_VALUE(key);
return VALUE_EQUALS(type, map.getDefaultReturnValue()) && !map.containsKey(key) ? getDefaultReturnValue() : type;
}
#if !TYPE_OBJECT || !VALUE_OBJECT #if !TYPE_OBJECT || !VALUE_OBJECT
@Override @Override
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return map.getOrDefault(key, defaultValue); } public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return map.getOrDefault(key, defaultValue); }
#endif #endif
@Override @Override
public MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
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
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); }
@Override
public void REPLACE_VALUES(MAP KEY_VALUE_GENERIC_TYPE m) { throw new UnsupportedOperationException(); }
@Override
public MAP KEY_VALUE_GENERIC_TYPE copy() { return map.copy(); }
@Override
public void clear() { throw new UnsupportedOperationException(); }
@Override @Override
public SET KEY_GENERIC_TYPE keySet() { public SET KEY_GENERIC_TYPE keySet() {
@@ -602,6 +721,46 @@ public class MAPS
} }
} }
#if ORDERED_MAP_FEATURE
/**
* The Unmodifyable Ordered Set implementation for the Unmodifyable Ordered Map implementation
* @Type(T)
* @ValueType(V)
*/
public static class UnmodifyableOrderedEntrySet KEY_VALUE_GENERIC_TYPE extends UnmodifyableEntrySet KEY_VALUE_GENERIC_TYPE implements ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE>
{
ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> set;
UnmodifyableOrderedEntrySet(ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> c) {
super(c);
set = c;
}
@Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> copy() { return set.copy(); }
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { return ObjectIterators.unmodifiable(set.iterator()); }
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator(MAP.Entry KEY_VALUE_GENERIC_TYPE fromElement) { return ObjectIterators.unmodifiable(set.iterator(fromElement)); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() { return set.first(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() { throw new UnsupportedOperationException(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() { return set.last(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() { throw new UnsupportedOperationException(); }
}
#endif
/** /**
* The Unmodifyable Set implementation for the Unmodifyable Map implementation * The Unmodifyable Set implementation for the Unmodifyable Map implementation
* @Type(T) * @Type(T)
@@ -635,6 +794,7 @@ public class MAPS
} }
#if SORTED_MAP_FEATURE
/** /**
* The Synchronized Navigable Map implementation used by the synchronizedMap helper function * The Synchronized Navigable Map implementation used by the synchronizedMap helper function
* @Type(T) * @Type(T)
@@ -660,9 +820,11 @@ public class MAPS
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet() { synchronized(mutex) { return SETS.synchronize(map.descendingKeySet(), mutex); } } public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet() { synchronized(mutex) { return SETS.synchronize(map.descendingKeySet(), mutex); } }
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE keySet() { synchronized(mutex) { return SETS.synchronize(map.keySet(), mutex); } }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { synchronized(mutex) { return map.firstEntry(); } } public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { synchronized(mutex) { return map.firstEntry(); } }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() { synchronized(mutex) { return map.firstEntry(); } } public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() { synchronized(mutex) { return map.lastEntry(); } }
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() { synchronized(mutex) { return map.pollFirstEntry(); } } public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() { synchronized(mutex) { return map.pollFirstEntry(); } }
@Override @Override
@@ -696,8 +858,8 @@ public class MAPS
@Override @Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key) { synchronized(mutex) { return map.ceilingEntry(key); } } public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key) { synchronized(mutex) { return map.ceilingEntry(key); } }
@Override @Override
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE copy() { synchronized(mutex) { return map.copy(); } }
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
@Deprecated @Deprecated
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, boolean fromInclusive, CLASS_TYPE toKey, boolean toInclusive) { synchronized(mutex) { return MAPS.synchronize(map.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); } } public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, boolean fromInclusive, CLASS_TYPE toKey, boolean toInclusive) { synchronized(mutex) { return MAPS.synchronize(map.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); } }
@@ -751,6 +913,8 @@ public class MAPS
#endif #endif
} }
#endif
#if ORDERED_MAP_FEATURE
/** /**
* The Synchronized Ordered Map implementation used by the synchronizedMap helper function * The Synchronized Ordered Map implementation used by the synchronizedMap helper function
* @Type(T) * @Type(T)
@@ -794,9 +958,22 @@ public class MAPS
@Override @Override
public VALUE_TYPE LAST_ENTRY_VALUE() { synchronized(mutex) { return map.LAST_ENTRY_VALUE(); } } public VALUE_TYPE LAST_ENTRY_VALUE() { synchronized(mutex) { return map.LAST_ENTRY_VALUE(); } }
@Override @Override
public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public ORDERED_MAP KEY_VALUE_GENERIC_TYPE copy() { synchronized(mutex) { return map.copy(); } }
@Override
public ORDERED_SET KEY_GENERIC_TYPE keySet() {
if(keys == null) keys = SETS.synchronize(map.keySet(), mutex);
return (ORDERED_SET KEY_GENERIC_TYPE)keys;
} }
@Override
public ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = ObjectSets.synchronize(map.ENTRY_SET(), mutex);
return (ObjectOrderedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE>)entrySet;
}
}
#endif
#if SORTED_MAP_FEATURE
/** /**
* The Synchronized Sorted Map implementation used by the synchronizedMap helper function * The Synchronized Sorted Map implementation used by the synchronizedMap helper function
* @Type(T) * @Type(T)
@@ -824,6 +1001,8 @@ public class MAPS
@Override @Override
public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { synchronized(mutex) { return MAPS.synchronize(map.tailMap(fromKey), mutex); } } public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { synchronized(mutex) { return MAPS.synchronize(map.tailMap(fromKey), mutex); } }
@Override @Override
public SORTED_SET KEY_GENERIC_TYPE keySet() { synchronized(mutex) { return SETS.synchronize(map.keySet(), mutex); } }
@Override
public KEY_TYPE FIRST_ENTRY_KEY() { synchronized(mutex) { return map.FIRST_ENTRY_KEY(); } } public KEY_TYPE FIRST_ENTRY_KEY() { synchronized(mutex) { return map.FIRST_ENTRY_KEY(); } }
@Override @Override
public KEY_TYPE POLL_FIRST_ENTRY_KEY() { synchronized(mutex) { return map.POLL_FIRST_ENTRY_KEY(); } } public KEY_TYPE POLL_FIRST_ENTRY_KEY() { synchronized(mutex) { return map.POLL_FIRST_ENTRY_KEY(); } }
@@ -836,7 +1015,7 @@ public class MAPS
@Override @Override
public VALUE_TYPE LAST_ENTRY_VALUE() { synchronized(mutex) { return map.LAST_ENTRY_VALUE(); } } public VALUE_TYPE LAST_ENTRY_VALUE() { synchronized(mutex) { return map.LAST_ENTRY_VALUE(); } }
@Override @Override
public SORTED_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public SORTED_MAP KEY_VALUE_GENERIC_TYPE copy() { synchronized(mutex) { return map.copy(); } }
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
@Deprecated @Deprecated
@@ -856,6 +1035,7 @@ public class MAPS
#endif #endif
} }
#endif
/** /**
* The Synchronized Map implementation used by the synchronizedMap helper function * The Synchronized Map implementation used by the synchronizedMap helper function
* @Type(T) * @Type(T)
@@ -939,6 +1119,18 @@ public class MAPS
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_ABSENT(key, mappingFunction); } } public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_ABSENT(key, mappingFunction); } }
@Override @Override
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
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
@@ -950,9 +1142,9 @@ public class MAPS
@Override @Override
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) { synchronized(mutex) { map.forEach(action); } } public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) { synchronized(mutex) { map.forEach(action); } }
@Override @Override
public int size() { synchronized(mutex) { return super.size(); } } public int size() { synchronized(mutex) { return map.size(); } }
@Override @Override
public MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } public MAP KEY_VALUE_GENERIC_TYPE copy() { synchronized(mutex) { return map.copy(); } }
@Override @Override
public SET KEY_GENERIC_TYPE keySet() { public SET KEY_GENERIC_TYPE keySet() {
if(keys == null) keys = SETS.synchronize(map.keySet(), mutex); if(keys == null) keys = SETS.synchronize(map.keySet(), mutex);
@@ -1025,5 +1217,4 @@ public class MAPS
public void forEach(BiConsumer<? super CLASS_TYPE, ? super CLASS_VALUE_TYPE> action) { synchronized(mutex) { map.forEach(action); } } public void forEach(BiConsumer<? super CLASS_TYPE, ? super CLASS_VALUE_TYPE> action) { synchronized(mutex) { map.forEach(action); } }
#endif #endif
} }
#endif
} }
@@ -0,0 +1,93 @@
package speiger.src.testers.PACKAGE.builder;
import java.util.List;
import com.google.common.collect.testing.AbstractTester;
import com.google.common.collect.testing.CollectionTestSuiteBuilder;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.testers.CollectionRemoveIfTester;
import speiger.src.testers.base.tests.collection.JavaCollectionRemoveIfTester;
import speiger.src.testers.PACKAGE.generators.TEST_COLLECTION_GENERATOR;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionAddAllArrayTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionAddAllTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionAddTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionClearTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionContainsAllTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionContainsAnyTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionContainsTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionCopyTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionEqualsTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionForEachTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionIteratorTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionRemoveAllTester;
#if !TYPE_BOOLEAN
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionRemoveIfTester;
#if !TYPE_OBJECT
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionStreamTester;
#endif
#endif
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionRetainAllTester;
import speiger.src.testers.PACKAGE.tests.collection.FILE_KEY_TYPECollectionToArrayTester;
#if !TYPE_BOOLEAN
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableCountTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableDistinctTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableFilterTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableFindFirstTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableLimitTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableMapTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableMatchesTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterablePeekTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableReduceTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableRepeatTester;
import speiger.src.testers.PACKAGE.tests.iterable.FILE_KEY_TYPEIterableSortedTester;
#endif
@SuppressWarnings("javadoc")
public class COLLECTION_TEST_BUILDER KEY_GENERIC_TYPE extends CollectionTestSuiteBuilder<CLASS_TYPE> {
public static GENERIC_KEY_BRACES COLLECTION_TEST_BUILDER KEY_GENERIC_TYPE using(TEST_COLLECTION_GENERATOR KEY_GENERIC_TYPE generator) {
return (COLLECTION_TEST_BUILDER KEY_GENERIC_TYPE) new COLLECTION_TEST_BUILDER KEY_GENERIC_TYPE().usingGenerator(generator);
}
@Override
@SuppressWarnings("rawtypes")
protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
testers.remove(CollectionRemoveIfTester.class);
testers.add(JavaCollectionRemoveIfTester.class);
#if !TYPE_BOOLEAN
testers.add(FILE_KEY_TYPEIterableMapTester.class);
testers.add(FILE_KEY_TYPEIterableFilterTester.class);
testers.add(FILE_KEY_TYPEIterableDistinctTester.class);
testers.add(FILE_KEY_TYPEIterableLimitTester.class);
testers.add(FILE_KEY_TYPEIterableSortedTester.class);
testers.add(FILE_KEY_TYPEIterableMatchesTester.class);
testers.add(FILE_KEY_TYPEIterablePeekTester.class);
testers.add(FILE_KEY_TYPEIterableReduceTester.class);
testers.add(FILE_KEY_TYPEIterableRepeatTester.class);
testers.add(FILE_KEY_TYPEIterableCountTester.class);
testers.add(FILE_KEY_TYPEIterableFindFirstTester.class);
#endif
testers.add(FILE_KEY_TYPECollectionAddAllTester.class);
testers.add(FILE_KEY_TYPECollectionAddAllArrayTester.class);
testers.add(FILE_KEY_TYPECollectionAddTester.class);
testers.add(FILE_KEY_TYPECollectionClearTester.class);
testers.add(FILE_KEY_TYPECollectionContainsAllTester.class);
testers.add(FILE_KEY_TYPECollectionContainsAnyTester.class);
testers.add(FILE_KEY_TYPECollectionContainsTester.class);
testers.add(FILE_KEY_TYPECollectionCopyTester.class);
testers.add(FILE_KEY_TYPECollectionEqualsTester.class);
testers.add(FILE_KEY_TYPECollectionForEachTester.class);
testers.add(FILE_KEY_TYPECollectionIteratorTester.class);
testers.add(FILE_KEY_TYPECollectionRemoveAllTester.class);
testers.add(FILE_KEY_TYPECollectionRetainAllTester.class);
#if !TYPE_BOOLEAN
testers.add(FILE_KEY_TYPECollectionRemoveIfTester.class);
#if !TYPE_OBJECT
testers.add(FILE_KEY_TYPECollectionStreamTester.class);
#endif
#endif
testers.add(FILE_KEY_TYPECollectionToArrayTester.class);
return testers;
}
}
@@ -0,0 +1,28 @@
package speiger.src.testers.PACKAGE.builder;
import java.util.List;
import com.google.common.collect.testing.AbstractTester;
import speiger.src.testers.PACKAGE.generators.TEST_QUEUE_GENERATOR;
import speiger.src.testers.PACKAGE.tests.queue.FILE_KEY_TYPEDequeueDequeueTester;
import speiger.src.testers.PACKAGE.tests.queue.FILE_KEY_TYPEDequeueEnqueueTester;
import speiger.src.testers.PACKAGE.tests.queue.FILE_KEY_TYPEDequeueLastTester;
@SuppressWarnings("javadoc")
public class DEQUEUE_TEST_BUILDER KEY_GENERIC_TYPE extends QUEUE_TEST_BUILDER KEY_GENERIC_TYPE
{
public static GENERIC_KEY_BRACES DEQUEUE_TEST_BUILDER KEY_GENERIC_TYPE using(TEST_QUEUE_GENERATOR KEY_GENERIC_TYPE builder) {
return (DEQUEUE_TEST_BUILDER KEY_GENERIC_TYPE)new DEQUEUE_TEST_BUILDER KEY_GENERIC_TYPE().usingGenerator(builder);
}
@Override
@SuppressWarnings("rawtypes")
protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> tester = super.getTesters();
tester.add(FILE_KEY_TYPEDequeueDequeueTester.class);
tester.add(FILE_KEY_TYPEDequeueEnqueueTester.class);
tester.add(FILE_KEY_TYPEDequeueLastTester.class);
return tester;
}
}
@@ -0,0 +1,384 @@
package speiger.src.testers.PACKAGE.builder;
#ignore
import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE;
import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS;
#endignore
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.common.collect.testing.AbstractTester;
import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.OneSizeTestContainerGenerator;
import com.google.common.collect.testing.SampleElements;
import com.google.common.collect.testing.TestListGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.Feature;
import com.google.common.collect.testing.testers.CollectionSerializationEqualTester;
import com.google.common.collect.testing.testers.ListAddAllAtIndexTester;
import com.google.common.collect.testing.testers.ListAddAllTester;
import com.google.common.collect.testing.testers.ListAddAtIndexTester;
import com.google.common.collect.testing.testers.ListAddTester;
import com.google.common.collect.testing.testers.ListCreationTester;
import com.google.common.collect.testing.testers.ListEqualsTester;
import com.google.common.collect.testing.testers.ListGetTester;
import com.google.common.collect.testing.testers.ListHashCodeTester;
import com.google.common.collect.testing.testers.ListIndexOfTester;
import com.google.common.collect.testing.testers.ListLastIndexOfTester;
import com.google.common.collect.testing.testers.ListRemoveAllTester;
import com.google.common.collect.testing.testers.ListRemoveAtIndexTester;
import com.google.common.collect.testing.testers.ListRemoveTester;
import com.google.common.collect.testing.testers.ListReplaceAllTester;
import com.google.common.collect.testing.testers.ListRetainAllTester;
import com.google.common.collect.testing.testers.ListSetTester;
import com.google.common.collect.testing.testers.ListSubListTester;
import com.google.common.collect.testing.testers.ListToArrayTester;
import com.google.common.testing.SerializableTester;
import junit.framework.TestSuite;
import speiger.src.collections.PACKAGE.collections.ITERABLE;
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.testers.base.tests.list.JavaListListIteratorTester;
import speiger.src.testers.PACKAGE.generators.TEST_LIST_GENERATOR;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListAbsentTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListAddAllArrayAtIndexTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListAddAllAtIndexTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListAddAllListAtIndexTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListAddAllTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListAddAtIndexTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListAddTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListCreationTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListEqualsTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListExtractElementsTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListGetElementsTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListGetTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListIndexOfTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListLastIndexOfTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListListIteratorTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListPresentTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListRemoveAllTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListRemoveAtIndexTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListRemoveElementsTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListRemoveTester;
#if !TYPE_BOOLEAN
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListSortTester;
#if !TYPE_OBJECT
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListFillBufferTester;
#endif
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListReplaceAllTester;
#endif
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListRetainAllTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListSetTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListSubListTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListSwapRemoveAtIndexTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListSwapRemoveTester;
import speiger.src.testers.PACKAGE.tests.list.FILE_KEY_TYPEListToArrayTester;
import speiger.src.testers.PACKAGE.utils.SAMPLE_ELEMENTS;
#if !TYPE_BOOLEAN
import speiger.src.testers.utils.SpecialFeature;
#endif
@SuppressWarnings("javadoc")
public class LIST_TEST_BUILDER KEY_GENERIC_TYPE extends COLLECTION_TEST_BUILDER KEY_GENERIC_TYPE {
#if TYPE_OBJECT
KEY_TYPE[] prefixes;
KEY_TYPE[] suffixes;
#else
KEY_TYPE[] prefixes = createPrefixes();
KEY_TYPE[] suffixes = createSuffixes();
#endif
public static GENERIC_KEY_BRACES LIST_TEST_BUILDER KEY_GENERIC_TYPE using(TEST_LIST_GENERATOR KEY_GENERIC_TYPE generator) {
return (LIST_TEST_BUILDER KEY_GENERIC_TYPE) new LIST_TEST_BUILDER KEY_GENERIC_TYPE().usingGenerator(generator);
}
public LIST_TEST_BUILDER KEY_GENERIC_TYPE setPrefixes(KEY_TYPE[] prefixes) {
this.prefixes = prefixes;
return this;
}
public LIST_TEST_BUILDER KEY_GENERIC_TYPE setSuffixes(KEY_TYPE[] suffixes) {
this.suffixes = suffixes;
return this;
}
#if !TYPE_OBJECT
public KEY_TYPE[] createPrefixes() {
#if TYPE_BOOLEAN
return new KEY_TYPE[]{false, false, false};
#else if TYPE_BYTE
return new KEY_TYPE[]{(byte)-3, (byte)-2, (byte)-1};
#else if TYPE_SHORT
return new KEY_TYPE[]{(short)-3, (short)-2, (short)-1};
#else if TYPE_CHAR
return new KEY_TYPE[]{'^', '_', '`'};
#else
return new KEY_TYPE[]{-3, -2, -1};
#endif
}
public KEY_TYPE[] createSuffixes() {
#if TYPE_BOOLEAN
return new KEY_TYPE[]{true, true, true};
#else if TYPE_BYTE
return new KEY_TYPE[]{(byte)5, (byte)6, (byte)7};
#else if TYPE_SHORT
return new KEY_TYPE[]{(short)5, (short)6, (short)7};
#else if TYPE_CHAR
return new KEY_TYPE[]{'f', 'g', 'h'};
#else
return new KEY_TYPE[]{5, 6, 7};
#endif
}
#endif
@Override
@SuppressWarnings("rawtypes")
protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
testers.add(CollectionSerializationEqualTester.class);
testers.add(ListAddAllAtIndexTester.class);
testers.add(ListAddAllTester.class);
testers.add(ListAddAtIndexTester.class);
testers.add(ListAddTester.class);
testers.add(ListCreationTester.class);
testers.add(ListEqualsTester.class);
testers.add(ListGetTester.class);
testers.add(ListHashCodeTester.class);
testers.add(ListIndexOfTester.class);
testers.add(ListLastIndexOfTester.class);
testers.add(JavaListListIteratorTester.class);
testers.add(ListRemoveAllTester.class);
testers.add(ListRemoveAtIndexTester.class);
testers.add(ListRemoveTester.class);
testers.add(ListReplaceAllTester.class);
testers.add(ListRetainAllTester.class);
testers.add(ListSetTester.class);
testers.add(ListSubListTester.class);
testers.add(ListToArrayTester.class);
testers.add(FILE_KEY_TYPEListAddAllAtIndexTester.class);
testers.add(FILE_KEY_TYPEListAddAllListAtIndexTester.class);
testers.add(FILE_KEY_TYPEListAddAllArrayAtIndexTester.class);
testers.add(FILE_KEY_TYPEListAddAllTester.class);
testers.add(FILE_KEY_TYPEListAddAtIndexTester.class);
testers.add(FILE_KEY_TYPEListAddTester.class);
testers.add(FILE_KEY_TYPEListAbsentTester.class);
testers.add(FILE_KEY_TYPEListPresentTester.class);
testers.add(FILE_KEY_TYPEListCreationTester.class);
testers.add(FILE_KEY_TYPEListEqualsTester.class);
testers.add(FILE_KEY_TYPEListGetTester.class);
testers.add(FILE_KEY_TYPEListGetElementsTester.class);
testers.add(FILE_KEY_TYPEListExtractElementsTester.class);
testers.add(FILE_KEY_TYPEListIndexOfTester.class);
testers.add(FILE_KEY_TYPEListLastIndexOfTester.class);
testers.add(FILE_KEY_TYPEListListIteratorTester.class);
testers.add(FILE_KEY_TYPEListRemoveAllTester.class);
testers.add(FILE_KEY_TYPEListRemoveAtIndexTester.class);
testers.add(FILE_KEY_TYPEListRemoveTester.class);
testers.add(FILE_KEY_TYPEListRemoveElementsTester.class);
testers.add(FILE_KEY_TYPEListSwapRemoveAtIndexTester.class);
testers.add(FILE_KEY_TYPEListSwapRemoveTester.class);
#if !TYPE_BOOLEAN
testers.add(FILE_KEY_TYPEListSortTester.class);
#if !TYPE_OBJECT
testers.add(FILE_KEY_TYPEListFillBufferTester.class);
#endif
testers.add(FILE_KEY_TYPEListReplaceAllTester.class);
#endif
testers.add(FILE_KEY_TYPEListRetainAllTester.class);
testers.add(FILE_KEY_TYPEListSetTester.class);
testers.add(FILE_KEY_TYPEListSubListTester.class);
testers.add(FILE_KEY_TYPEListToArrayTester.class);
return testers;
}
@Override
public TestSuite createTestSuite() {
#ignore
withFeatures(KNOWN_ORDER);
#endignore
return super.createTestSuite();
}
@Override
protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Collection<CLASS_TYPE>, CLASS_TYPE>> parentBuilder) {
List<TestSuite> derivedSuites = new ArrayList<>(super.createDerivedSuites(parentBuilder));
#ignore
if (parentBuilder.getFeatures().contains(SERIALIZABLE)) {
#endignore
derivedSuites.add(ListTestSuiteBuilder.using(new ReserializedListGenerator<CLASS_TYPE>(parentBuilder.getSubjectGenerator()))
.named(getName() + " reserialized")
.withFeatures(computeReserializedCollectionFeatures(parentBuilder.getFeatures()))
.suppressing(parentBuilder.getSuppressedTests()).withSetUp(parentBuilder.getSetUp())
.withTearDown(parentBuilder.getTearDown()).createTestSuite());
}
#ignore
if(!parentBuilder.getFeatures().contains(CollectionFeature.SUBSET_VIEW)) {
#endignore
#if !TYPE_BOOLEAN
if(prefixes != null) {
derivedSuites.add(LIST_TEST_BUILDER.using(new SubListListGeneratorBRACES(parentBuilder.getSubjectGenerator(), prefixes, null))
.named(getName() + " subSet_prefix")
.withFeatures(computeSubListFeatures(parentBuilder.getFeatures()))
.suppressing(parentBuilder.getSuppressedTests()).withSetUp(parentBuilder.getSetUp())
.withTearDown(parentBuilder.getTearDown()).createTestSuite());
}
if(suffixes != null) {
derivedSuites.add(LIST_TEST_BUILDER.using(new SubListListGeneratorBRACES(parentBuilder.getSubjectGenerator(), null, suffixes))
.named(getName() + " subSet_suffixes")
.withFeatures(computeSubListFeatures(parentBuilder.getFeatures()))
.suppressing(parentBuilder.getSuppressedTests()).withSetUp(parentBuilder.getSetUp())
.withTearDown(parentBuilder.getTearDown()).createTestSuite());
}
if(prefixes != null && suffixes != null) {
derivedSuites.add(LIST_TEST_BUILDER.using(new SubListListGeneratorBRACES(parentBuilder.getSubjectGenerator(), prefixes, suffixes))
.named(getName() + " subSet")
.withFeatures(computeSubListFeatures(parentBuilder.getFeatures()))
.suppressing(parentBuilder.getSuppressedTests()).withSetUp(parentBuilder.getSetUp())
.withTearDown(parentBuilder.getTearDown()).createTestSuite());
}
#endif
}
return derivedSuites;
}
static class SubListListGenerator KEY_GENERIC_TYPE implements TEST_LIST_GENERATOR KEY_GENERIC_TYPE {
TEST_LIST_GENERATOR KEY_GENERIC_TYPE generator;
KEY_TYPE[] prefix;
KEY_TYPE[] suffix;
public SubListListGenerator(OneSizeTestContainerGenerator<Collection<CLASS_TYPE>, CLASS_TYPE> gen, KEY_TYPE[] prefix, KEY_TYPE[] suffix) {
generator = (TEST_LIST_GENERATOR KEY_GENERIC_TYPE)gen.getInnerGenerator();
this.prefix = prefix;
this.suffix = suffix;
}
@Override
public SampleElements<CLASS_TYPE> samples() {
return generator.samples();
}
@Override
public CLASS_TYPE[] createArray(int length) {
return generator.createArray(length);
}
@Override
public Iterable<CLASS_TYPE> order(List<CLASS_TYPE> insertionOrder) {
return generator.order(insertionOrder);
}
@Override
public SAMPLE_ELEMENTS KEY_GENERIC_TYPE getSamples() {
return generator.getSamples();
}
@Override
public ITERABLE KEY_GENERIC_TYPE order(LIST KEY_GENERIC_TYPE insertionOrder) {
return generator.order(insertionOrder);
}
#if !TYPE_OBJECT
@Override
public LIST KEY_GENERIC_TYPE create(Object... elements) {
KEY_TYPE[] array = NEW_KEY_ARRAY(elements.length);
int i = 0;
for (Object e : elements) {
array[i++] = CLASS_TO_KEY(e);
}
return create(array);
}
@Override
public LIST KEY_GENERIC_TYPE create(KEY_TYPE... elements) {
int length = getLength(prefix);
return generator.create(merge(elements)).subList(length, length+elements.length);
}
#else
@Override
public LIST KEY_GENERIC_TYPE create(Object... elements) {
KEY_TYPE[] array = NEW_KEY_ARRAY(elements.length);
int i = 0;
for (Object e : elements) {
array[i++] = CLASS_TO_KEY(e);
}
int length = getLength(prefix);
return generator.create(merge(array)).subList(length, length+elements.length);
}
#endif
private int getLength(KEY_TYPE[] keys) {
return keys == null ? 0 : keys.length;
}
private KEY_TYPE[] merge(KEY_TYPE[] input) {
int prefixLength = getLength(prefix);
int suffixLength = getLength(suffix);
KEY_TYPE[] result = NEW_KEY_ARRAY(input.length+prefixLength+suffixLength);
if(prefixLength != 0) System.arraycopy(prefix, 0, result, 0, prefixLength);
System.arraycopy(input, 0, result, prefixLength, input.length);
if(suffixLength != 0) System.arraycopy(suffix, 0, result, prefixLength+input.length, suffixLength);
return result;
}
}
static class ReserializedListGenerator<E> implements TestListGenerator<E> {
final OneSizeTestContainerGenerator<Collection<E>, E> gen;
private ReserializedListGenerator(OneSizeTestContainerGenerator<Collection<E>, E> gen) {
this.gen = gen;
}
@Override
public SampleElements<E> samples() {
return gen.samples();
}
@Override
public List<E> create(Object... elements) {
return (List<E>) SerializableTester.reserialize(gen.create(elements));
}
@Override
public E[] createArray(int length) {
return gen.createArray(length);
}
@Override
public Iterable<E> order(List<E> insertionOrder) {
return gen.order(insertionOrder);
}
}
#if !TYPE_BOOLEAN
private static Set<Feature<?>> computeSubListFeatures(Set<Feature<?>> features) {
Set<Feature<?>> derivedFeatures = new HashSet<>(features);
#ignore
derivedFeatures.add(CollectionFeature.SUBSET_VIEW);
derivedFeatures.remove(SpecialFeature.COPYING);
derivedFeatures.remove(SpecialFeature.CHILDREN_COPY);
#endignore
return derivedFeatures;
}
#endif
private static Set<Feature<?>> computeReserializedCollectionFeatures(Set<Feature<?>> features) {
Set<Feature<?>> derivedFeatures = new HashSet<>(features);
#ignore
derivedFeatures.remove(SERIALIZABLE);
derivedFeatures.remove(SERIALIZABLE_INCLUDING_VIEWS);
#endignore
return derivedFeatures;
}
}
@@ -0,0 +1,140 @@
package speiger.src.testers.PACKAGE.builder;
#ignore
import static com.google.common.collect.testing.features.CollectionFeature.DESCENDING_VIEW;
import static com.google.common.collect.testing.features.CollectionFeature.SUBSET_VIEW;
#endignore
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.google.common.collect.testing.AbstractTester;
import com.google.common.collect.testing.DerivedCollectionGenerators.Bound;
import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.OneSizeTestContainerGenerator;
import com.google.common.collect.testing.SampleElements;
import com.google.common.collect.testing.features.Feature;
import com.google.common.collect.testing.testers.NavigableSetNavigationTester;
import junit.framework.TestSuite;
import speiger.src.collections.PACKAGE.collections.ITERABLE;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
import speiger.src.collections.PACKAGE.utils.LISTS;
import speiger.src.testers.PACKAGE.generators.TEST_NAVIGABLE_SET_GENERATOR;
import speiger.src.testers.PACKAGE.generators.TEST_SORTED_SET_GENERATOR;
import speiger.src.testers.PACKAGE.impl.SUB_SORTED_SET_CLASS_GENERATOR.SUB_NAVIGABLE_SET_CLASS_GENERATOR;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPENavigableSetNavigationTester;
import speiger.src.testers.PACKAGE.utils.SAMPLE_ELEMENTS;
import speiger.src.testers.utils.SpecialFeature;
@SuppressWarnings("javadoc")
public class NAVIGABLE_SET_TEST_BUILDER KEY_GENERIC_TYPE extends SORTED_SET_TEST_BUILDER KEY_GENERIC_TYPE {
public static GENERIC_KEY_BRACES NAVIGABLE_SET_TEST_BUILDER KEY_GENERIC_TYPE using(TEST_NAVIGABLE_SET_GENERATOR KEY_GENERIC_TYPE generator) {
return (NAVIGABLE_SET_TEST_BUILDER KEY_GENERIC_TYPE) new NAVIGABLE_SET_TEST_BUILDER KEY_GENERIC_TYPE().usingGenerator(generator);
}
@Override
@SuppressWarnings("rawtypes")
protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
testers.add(NavigableSetNavigationTester.class);
testers.add(FILE_KEY_TYPENavigableSetNavigationTester.class);
return testers;
}
@Override
protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Collection<CLASS_TYPE>, CLASS_TYPE>> parentBuilder) {
List<TestSuite> derivedSuites = new ArrayList<>(super.createDerivedSuites(parentBuilder));
#ignore
if (!parentBuilder.getFeatures().contains(SUBSET_VIEW)) {
#endignore
// Other combinations are inherited from SortedSetTestSuiteBuilder.
derivedSuites.add(createSubsetSuite(parentBuilder, Bound.NO_BOUND, Bound.INCLUSIVE));
derivedSuites.add(createSubsetSuite(parentBuilder, Bound.EXCLUSIVE, Bound.NO_BOUND));
derivedSuites.add(createSubsetSuite(parentBuilder, Bound.EXCLUSIVE, Bound.EXCLUSIVE));
derivedSuites.add(createSubsetSuite(parentBuilder, Bound.EXCLUSIVE, Bound.INCLUSIVE));
derivedSuites.add(createSubsetSuite(parentBuilder, Bound.INCLUSIVE, Bound.INCLUSIVE));
}
#ignore
if (!parentBuilder.getFeatures().contains(DESCENDING_VIEW)) {
#endignore
derivedSuites.add(createDescendingSuite(parentBuilder));
}
return derivedSuites;
}
@Override
SORTED_SET_TEST_BUILDER KEY_GENERIC_TYPE newBuilderUsing(TEST_SORTED_SET_GENERATOR KEY_GENERIC_TYPE delegate, Bound to, Bound from) {
return NAVIGABLE_SET_TEST_BUILDER.using(new SUB_NAVIGABLE_SET_CLASS_GENERATORBRACES(delegate, to, from));
}
private TestSuite createDescendingSuite(FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<Collection<CLASS_TYPE>, CLASS_TYPE>> parentBuilder) {
TEST_NAVIGABLE_SET_GENERATOR KEY_GENERIC_TYPE delegate = (TEST_NAVIGABLE_SET_GENERATOR KEY_GENERIC_TYPE) parentBuilder.getSubjectGenerator().getInnerGenerator();
List<Feature<?>> features = new ArrayList<>();
#ignore
features.add(DESCENDING_VIEW);
features.addAll(parentBuilder.getFeatures());
features.remove(SpecialFeature.COPYING);
features.remove(SpecialFeature.CHILDREN_COPY);
#endignore
return NAVIGABLE_SET_TEST_BUILDER.using(new TEST_NAVIGABLE_SET_GENERATOR KEY_GENERIC_TYPE() {
@Override
public SampleElements<CLASS_TYPE> samples() {
return delegate.samples();
}
@Override
public SAMPLE_ELEMENTS KEY_GENERIC_TYPE getSamples() {
return delegate.getSamples();
}
@Override
public ITERABLE KEY_GENERIC_TYPE order(LIST KEY_GENERIC_TYPE insertionOrder) {
LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
delegate.order(insertionOrder).forEach(list::add);
LISTS.reverse(list);
return list;
}
@Override
public Iterable<CLASS_TYPE> order(List<CLASS_TYPE> insertionOrder) {
LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
for(CLASS_TYPE entry : delegate.order(insertionOrder))
{
list.add(OBJ_TO_KEY(entry));
}
LISTS.reverse(list);
return list;
}
@Override
public KEY_TYPE belowSamplesLesser() { return delegate.aboveSamplesGreater(); }
@Override
public KEY_TYPE belowSamplesGreater() { return delegate.aboveSamplesLesser(); }
@Override
public KEY_TYPE aboveSamplesLesser() { return delegate.belowSamplesGreater(); }
@Override
public KEY_TYPE aboveSamplesGreater() { return delegate.belowSamplesLesser(); }
#if !TYPE_OBJECT
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE create(KEY_TYPE... elements) {
return delegate.create(elements).descendingSet();
}
#endif
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE create(Object... elements) {
return delegate.create(elements).descendingSet();
}
}).named(parentBuilder.getName() + " descending").withFeatures(features)
.suppressing(parentBuilder.getSuppressedTests()).createTestSuite();
}
}
@@ -0,0 +1,38 @@
package speiger.src.testers.PACKAGE.builder;
import java.util.List;
import com.google.common.collect.testing.AbstractTester;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import junit.framework.TestSuite;
import speiger.src.testers.PACKAGE.generators.TEST_ORDERED_SET_GENERATOR;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetMoveTester;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetIterationTester;
import speiger.src.testers.PACKAGE.tests.set.FILE_KEY_TYPEOrderedSetNavigationTester;
@SuppressWarnings("javadoc")
public class ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE extends SET_TEST_BUILDER KEY_GENERIC_TYPE {
public static GENERIC_KEY_BRACES ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE using(TEST_ORDERED_SET_GENERATOR KEY_GENERIC_TYPE generator) {
return (ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE) new ORDERED_SET_TEST_BUILDER KEY_GENERIC_TYPE().usingGenerator(generator);
}
@Override
@SuppressWarnings("rawtypes")
protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
testers.add(FILE_KEY_TYPEOrderedSetNavigationTester.class);
testers.add(FILE_KEY_TYPEOrderedSetMoveTester.class);
testers.add(FILE_KEY_TYPEOrderedSetIterationTester.class);
return testers;
}
@Override
public TestSuite createTestSuite() {
#ignore
withFeatures(CollectionFeature.KNOWN_ORDER);
#endignore
return super.createTestSuite();
}
}

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