diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a2f53f --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.* +!.gitignore +!.gitlab-ci.yml +build/ +out/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..420e6f2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +# Change Log diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..418de4c --- /dev/null +++ b/LICENSE @@ -0,0 +1,174 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..50b7ba9 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +[![Build Status](https://dev.azure.com/bakdata/public/_apis/build/status/bakdata.seq2?branchName=master)](https://dev.azure.com/bakdata/public/_build/latest?definitionId=19&branchName=master) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=com.bakdata.seq2%3Aseq2&metric=alert_status)](https://sonarcloud.io/dashboard?id=com.bakdata.seq2%3Aseq2) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=com.bakdata.seq2%3Aseq2&metric=coverage)](https://sonarcloud.io/dashboard?id=com.bakdata.seq2%3Aseq2) +[![Maven](https://img.shields.io/maven-central/v/com.bakdata.seq2/seq2.svg)](https://search.maven.org/search?q=g:com.bakdata.seq2%20AND%20a:seq2&core=gav) + +# seq2 + +This library is an extension to the great [jOOλ library](https://github.com/jOOQ/jOOL). +It mainly provides native handling of pair streams. + +## Usage + +```java +final Seq2 words = Seq2.of("foo", "bar", "foo"); +final Map wordCounts = words.mapToPair(Function.identity(), s -> 1) + .reduceByKey(Integer::sum) + .toMap(); +System.out.println(wordCounts); +// {bar=1, foo=2} +``` + +## Getting Started + +You can add seq2 via Maven Central. + +#### Gradle +```gradle +compile group: 'com.bakdata.seq2', name: 'seq2', version: '1.0.0' +``` + +#### Maven +```xml + + com.bakdata.seq2 + seq2 + 1.0.0 + +``` + + +For other build tools or versions, refer to the [latest version in MvnRepository](https://mvnrepository.com/artifact/com.bakdata.seq2/seq2/latest). + +## Development + +If you want to contribute to this project, you can simply clone the repository and build it via Gradle. +All dependencies should be included in the Gradle files, there are no external prerequisites. + +```bash +> git clone git@github.com:bakdata/seq2.git +> cd seq2 && ./gradlew build +``` + +Please note, that we have [code styles](https://github.com/bakdata/bakdata-code-styles) for Java. +They are basically the Google style guide, with some small modifications. + +## Contributing + +We are happy if you want to contribute to this project. +If you find any bugs or have suggestions for improvements, please open an issue. +We are also happy to accept your PRs. +Just open an issue beforehand and let us know what you want to do and why. + +## License +This project is licensed under the MIT license. +Have a look at the [LICENSE](https://github.com/bakdata/seq2/blob/master/LICENSE) for more details. diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..ceb0cba --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,27 @@ +trigger: + branches: + include: + - refs/heads/* + - refs/tags/* +pr: + branches: + include: + - master + +variables: +- group: sonarqube +- group: sign +- group: ossrh + +resources: + repositories: + - repository: templates + type: github + name: bakdata/bakdata-project-templates + endpoint: bot + +jobs: +- template: azure/gradle/build.yml@templates +- template: azure/gradle/create_tag_version.yml@templates +- template: azure/gradle/upload_release.yml@templates +- template: azure/gradle/upload_snapshot.yml@templates diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..64994fb --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,59 @@ +description = "This library is an extension to the great jOOλ library" + + +plugins { + id("net.researchgate.release") version "2.8.1" + id("com.bakdata.sonar") version "1.1.4" + id("com.bakdata.sonatype") version "1.1.4" + id("org.hildan.github.changelog") version "0.8.0" + id("io.freefair.lombok") version "3.8.0" +} + +allprojects { + group = "com.bakdata.${rootProject.name}" + + tasks.withType { + maxParallelForks = 4 + } + + repositories { + mavenCentral() + } +} + +configure { + developers { + developer { + name.set("Philipp Schirmer") + id.set("philipp94831") + } + } +} + +configure { + githubUser = "bakdata" + futureVersionTag = findProperty("changelog.releaseVersion")?.toString() + sinceTag = findProperty("changelog.sinceTag")?.toString() +} + +allprojects { + apply(plugin = "java-library") + + configure { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + dependencies { + "api"(group = "org.jooq", name = "jool", version = "0.9.14") + + "testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:5.5.1") + "testImplementation"("org.junit.jupiter:junit-jupiter-params:5.5.1") + "testImplementation"("org.junit.jupiter:junit-jupiter-api:5.5.1") + "testImplementation"(group = "org.assertj", name = "assertj-core", version = "3.13.2") + } +} + +tasks.withType { + useJUnitPlatform() +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..01f8cfb --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +version=1.0.0-SNAPSHOT +org.gradle.caching=true +org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..5c2d1cf Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..46ec9c5 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Jul 30 10:32:13 CEST 2019 +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lombok.config b/lombok.config new file mode 100644 index 0000000..189c0be --- /dev/null +++ b/lombok.config @@ -0,0 +1,3 @@ +# This file is generated by the 'io.freefair.lombok' Gradle plugin +config.stopBubbling = true +lombok.addLombokGeneratedAnnotation = true diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..15cdabe --- /dev/null +++ b/settings.gradle @@ -0,0 +1,12 @@ +pluginManagement { + repositories { + gradlePluginPortal() + jcenter() + maven { + name "JCenter Gradle Plugins" + url "https://dl.bintray.com/gradle/gradle-plugins" + } + } +} + +rootProject.name = 'seq2' diff --git a/src/main/java/com/bakdata/util/seq2/BaseSeq.java b/src/main/java/com/bakdata/util/seq2/BaseSeq.java new file mode 100644 index 0000000..6032e94 --- /dev/null +++ b/src/main/java/com/bakdata/util/seq2/BaseSeq.java @@ -0,0 +1,656 @@ +/* + * Copyright (c), 2019 bakdata GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bakdata.util.seq2; + +import java.io.PrintStream; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntFunction; +import java.util.function.ToLongFunction; +import java.util.stream.Collector; +import java.util.stream.Stream; +import org.jooq.lambda.Seq; +import org.jooq.lambda.exception.TooManyElementsException; + +public interface BaseSeq { + /** + * @see Seq#avg() + */ + default Optional avg() { + return this.toSeq().avg(); + } + + /** + * @see Seq#avg(Function) + */ + default Optional avg(final Function function) { + return this.toSeq().avg(function); + } + + /** + * @see Seq#avgDouble(ToDoubleFunction) + */ + default double avgDouble(final ToDoubleFunction function) { + return this.toSeq().avgDouble(function); + } + + /** + * @see Seq#avgInt(ToIntFunction) + */ + default double avgInt(final ToIntFunction function) { + return this.toSeq().avgInt(function); + } + + /** + * @see Seq#avgLong(ToLongFunction) + */ + default double avgLong(final ToLongFunction function) { + return this.toSeq().avgLong(function); + } + + /** + * @see Seq#bitAnd() + */ + default Optional bitAnd() { + return this.toSeq().bitAnd(); + } + + /** + * @see Seq#bitAnd(Function) + */ + default Optional bitAnd(final Function function) { + return this.toSeq().bitAnd(function); + } + + /** + * @see Seq#bitAndInt(ToIntFunction) + */ + default int bitAndInt(final ToIntFunction function) { + return this.toSeq().bitAndInt(function); + } + + /** + * @see Seq#bitAndLong(ToLongFunction) + */ + default long bitAndLong(final ToLongFunction function) { + return this.toSeq().bitAndLong(function); + } + + /** + * @see Seq#bitOr() + */ + default Optional bitOr() { + return this.toSeq().bitOr(); + } + + /** + * @see Seq#bitOr(Function) + */ + default Optional bitOr(final Function function) { + return this.toSeq().bitOr(function); + } + + /** + * @see Seq#bitOrInt(ToIntFunction) + */ + default int bitOrInt(final ToIntFunction function) { + return this.toSeq().bitOrInt(function); + } + + /** + * @see Seq#bitOrLong(ToLongFunction) + */ + default long bitOrLong(final ToLongFunction function) { + return this.toSeq().bitAndLong(function); + } + + /** + * @see Seq#commonPrefix() + */ + default String commonPrefix() { + return this.toSeq().commonPrefix(); + } + + /** + * @see Seq#commonSuffix() + */ + default String commonSuffix() { + return this.toSeq().commonSuffix(); + } + + /** + * @see Seq#contains(Object) + */ + default boolean contains(final T other) { + return this.toSeq().contains(other); + } + + /** + * @see Seq#containsAll(Object[]) + */ + default boolean containsAll(final T... other) { + return this.toSeq().containsAll(other); + } + + /** + * @see Seq#containsAll(Stream) + */ + default boolean containsAll(final Stream other) { + return this.toSeq().containsAll(other); + } + + /** + * @see Seq#containsAll(Iterable) + */ + default boolean containsAll(final Iterable other) { + return this.toSeq().containsAll(other); + } + + /** + * @see Seq#containsAll(Seq) + */ + default boolean containsAll(final Seq other) { + return this.toSeq().containsAll(other); + } + + /** + * @see Seq#containsAll(Seq) + */ + default boolean containsAll(final Seq2 other) { + return this.containsAll(other.toSeq()); + } + + /** + * @see Seq#containsAny(Object[]) + */ + default boolean containsAny(final T... other) { + return this.toSeq().containsAny(other); + } + + /** + * @see Seq#containsAny(Stream) + */ + default boolean containsAny(final Stream other) { + return this.toSeq().containsAny(other); + } + + /** + * @see Seq#containsAny(Iterable) + */ + default boolean containsAny(final Iterable other) { + return this.toSeq().containsAny(other); + } + + /** + * @see Seq#containsAny(Seq) + */ + default boolean containsAny(final Seq other) { + return this.toSeq().containsAny(other); + } + + /** + * @see Seq#containsAny(Seq) + */ + default boolean containsAny(final Seq2 other) { + return this.containsAny(other.toSeq()); + } + + /** + * @see Seq#count(Predicate) + */ + default long count(final Predicate predicate) { + return this.toSeq().count(predicate); + } + + /** + * @see Seq#countDistinct() + */ + default long countDistinct() { + return this.toSeq().countDistinct(); + } + + /** + * @see Seq#countDistinct(Predicate) + */ + default long countDistinct(final Predicate predicate) { + return this.toSeq().countDistinct(predicate); + } + + /** + * @see Seq#countDistinctBy(Function) + */ + default long countDistinctBy(final Function function) { + return this.toSeq().countDistinctBy(function); + } + + /** + * @see Seq#countDistinctBy(Function, Predicate) + */ + default long countDistinctBy(final Function function, + final Predicate predicate) { + return this.toSeq().countDistinctBy(function, predicate); + } + + /** + * @see Seq#findFirst(Predicate) + */ + default Optional findFirst(final Predicate predicate) { + return this.toSeq().findFirst(predicate); + } + + /** + * @see Seq#findLast() + */ + default Optional findLast() { + return this.toSeq().findLast(); + } + + /** + * @see Seq#findLast(Predicate) + */ + default Optional findLast(final Predicate predicate) { + return this.toSeq().findLast(predicate); + } + + /** + * @see Seq#findSingle() + */ + default Optional findSingle() throws TooManyElementsException { + return this.toSeq().findSingle(); + } + + /** + * @see Seq#foldLeft(Object, BiFunction) + */ + default U foldLeft(final U seed, final BiFunction function) { + return this.toSeq().foldLeft(seed, function); + } + + /** + * @see Seq#foldRight(Object, BiFunction) + */ + default U foldRight(final U seed, final BiFunction function) { + return this.toSeq().foldRight(seed, function); + } + + /** + * @see Seq#format() + */ + default String format() { + return this.toSeq().format(); + } + + /** + * @see Seq#get(long) + */ + default Optional get(final long index) { + return this.toSeq().get(index); + } + + /** + * @see Seq#groupBy(Function) + */ + default Map> groupBy(final Function classifier) { + return this.toSeq().groupBy(classifier); + } + + /** + * @see Seq#groupBy(Function, Collector) + */ + default Map groupBy(final Function classifier, + final Collector downstream) { + return this.toSeq().groupBy(classifier, downstream); + } + + /** + * @see Seq#groupBy(Function, Supplier, Collector) + */ + default > M groupBy(final Function classifier, + final Supplier mapFactory, final Collector downstream) { + return this.toSeq().groupBy(classifier, mapFactory, downstream); + } + + /** + * @see Seq#indexOf(Object) + */ + default OptionalLong indexOf(final T element) { + return this.toSeq().indexOf(element); + } + + /** + * @see Seq#indexOf(Predicate) + */ + default OptionalLong indexOf(final Predicate predicate) { + return this.toSeq().indexOf(predicate); + } + + /** + * @see Seq#isEmpty() + */ + default boolean isEmpty() { + return this.toSeq().isEmpty(); + } + + /** + * @see Seq#isNotEmpty() + */ + default boolean isNotEmpty() { + return this.toSeq().isNotEmpty(); + } + + /** + * @see Seq#max() + */ + default Optional max() { + return this.toSeq().max(); + } + + /** + * @see Seq#max(Function) + */ + default > Optional max(final Function function) { + return this.toSeq().max(function); + } + + /** + * @see Seq#max(Function, Comparator) + */ + default Optional max(final Function function, + final Comparator comparator) { + return this.toSeq().max(function, comparator); + } + + /** + * @see Seq#maxBy(Function) + */ + default > Optional maxBy(final Function function) { + return this.toSeq().maxBy(function); + } + + /** + * @see Seq#maxBy(Function, Comparator) + */ + default Optional maxBy(final Function function, + final Comparator comparator) { + return this.toSeq().maxBy(function, comparator); + } + + /** + * @see Seq#median() + */ + default Optional median() { + return this.toSeq().median(); + } + + /** + * @see Seq#median(Comparator) + */ + default Optional median(final Comparator comparator) { + return this.toSeq().median(comparator); + } + + /** + * @see Seq#medianBy(Function) + */ + default > Optional medianBy(final Function function) { + return this.toSeq().medianBy(function); + } + + /** + * @see Seq#medianBy(Function, Comparator) + */ + default Optional medianBy(final Function function, + final Comparator comparator) { + return this.toSeq().medianBy(function, comparator); + } + + /** + * @see Seq#min() + */ + default Optional min() { + return this.toSeq().min(); + } + + /** + * @see Seq#min(Function) + */ + default > Optional min(final Function function) { + return this.toSeq().min(function); + } + + /** + * @see Seq#min(Function, Comparator) + */ + default Optional min(final Function function, + final Comparator comparator) { + return this.toSeq().min(function, comparator); + } + + /** + * @see Seq#minBy(Function) + */ + default > Optional minBy(final Function function) { + return this.toSeq().minBy(function); + } + + /** + * @see Seq#minBy(Function, Comparator) + */ + default Optional minBy(final Function function, + final Comparator comparator) { + return this.toSeq().minBy(function, comparator); + } + + /** + * @see Seq#mode() + */ + default Optional mode() { + return this.toSeq().mode(); + } + + /** + * @see Seq#modeBy(Function) + */ + default Optional modeBy(final Function function) { + return this.toSeq().modeBy(function); + } + + /** + * @see Seq#percentile(double) + */ + default Optional percentile(final double percentile) { + return this.toSeq().percentile(percentile); + } + + /** + * @see Seq#percentile(double, Comparator) + */ + default Optional percentile(final double percentile, final Comparator comparator) { + return this.toSeq().percentile(percentile, comparator); + } + + /** + * @see Seq#percentileBy(double, Function) + */ + default > Optional percentileBy(final double percentile, + final Function function) { + return this.toSeq().percentileBy(percentile, function); + } + + /** + * @see Seq#percentileBy(double, Function, Comparator) + */ + default Optional percentileBy(final double percentile, final Function function, + final Comparator comparator) { + return this.toSeq().percentileBy(percentile, function, comparator); + } + + /** + * @see Seq#print(PrintWriter) + */ + default void print(final PrintWriter writer) { + this.toSeq().print(writer); + } + + /** + * @see Seq#print(PrintStream) + */ + default void print(final PrintStream stream) { + this.toSeq().print(stream); + } + + /** + * @see Seq#printErr() + */ + default void printErr() { + this.toSeq().printErr(); + } + + /** + * @see Seq#printOut() + */ + default void printOut() { + this.toSeq().printOut(); + } + + /** + * @see Seq#sum() + */ + default Optional sum() { + return this.toSeq().sum(); + } + + /** + * @see Seq#sum(Function) + */ + default Optional sum(final Function function) { + return this.toSeq().sum(function); + } + + /** + * @see Seq#sumDouble(ToDoubleFunction) + */ + default double sumDouble(final ToDoubleFunction function) { + return this.toSeq().sumDouble(function); + } + + /** + * @see Seq#sumInt(ToIntFunction) + */ + default int sumInt(final ToIntFunction function) { + return this.toSeq().sumInt(function); + } + + /** + * @see Seq#sumLong(ToLongFunction) + */ + default long sumLong(final ToLongFunction function) { + return this.toSeq().sumLong(function); + } + + /** + * @see Seq#toCollection(Supplier) + */ + default > C toCollection(final Supplier factory) { + return this.toSeq().toCollection(factory); + } + + /** + * @see Seq#toList() + */ + default List toList() { + return this.toSeq().toList(); + } + + /** + * @see Seq#toList(Supplier) + */ + default > L toList(final Supplier factory) { + return this.toSeq().toList(factory); + } + + /** + * @see Seq#toMap(Function, Function) + */ + default Map toMap(final Function keyMapper, + final Function valueMapper) { + return this.toSeq().toMap(keyMapper, valueMapper); + } + + /** + * @see Seq#toMap(Function) + */ + default Map toMap(final Function keyMapper) { + return this.toSeq().toMap(keyMapper); + } + + /** + * Fallback to {@code Seq}. If methods of {@link Seq} are missing, implement them. + */ + @Deprecated + Seq toSeq(); + + /** + * @see Seq#toSet() + */ + default Set toSet() { + return this.toSeq().toSet(); + } + + /** + * @see Seq#toSet(Supplier) + */ + default > S toSet(final Supplier factory) { + return this.toSeq().toSet(factory); + } + + /** + * @see Seq#toString(CharSequence) + */ + default String toString(final String delimiter) { + return this.toSeq().toString(delimiter); + } + + /** + * @see Seq#toString(CharSequence, CharSequence, CharSequence) + */ + default String toString(final String delimiter, final String prefix, final String suffix) { + return this.toSeq().toString(delimiter, prefix, suffix); + } + + /** + * @see Seq#toUnmodifiableList() + */ + default List toUnmodifiableList() { + return this.toSeq().toUnmodifiableList(); + } + + /** + * @see Seq#toUnmodifiableSet() + */ + default Set toUnmodifiableSet() { + return this.toSeq().toUnmodifiableSet(); + } +} diff --git a/src/main/java/com/bakdata/util/seq2/PairSeq.java b/src/main/java/com/bakdata/util/seq2/PairSeq.java new file mode 100644 index 0000000..1f113b3 --- /dev/null +++ b/src/main/java/com/bakdata/util/seq2/PairSeq.java @@ -0,0 +1,2696 @@ +/* + * Copyright (c), 2019 bakdata GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bakdata.util.seq2; + +import java.util.Comparator; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.Random; +import java.util.Spliterator; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.BinaryOperator; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.function.ToDoubleBiFunction; +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntBiFunction; +import java.util.function.ToIntFunction; +import java.util.function.ToLongBiFunction; +import java.util.function.ToLongFunction; +import java.util.stream.Collector; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.Stream; +import org.jooq.lambda.Seq; +import org.jooq.lambda.Window; +import org.jooq.lambda.tuple.Tuple2; + +@SuppressWarnings("deprecation") +public interface PairSeq extends Stream>, Iterable>, BaseSeq> { + /** + * @see Seq#empty() + */ + static PairSeq empty() { + final Seq2> seq = Seq2.empty(); + return seq(seq); + } + + /** + * @see Seq#generate(Supplier) + */ + static PairSeq generate(final Supplier> s) { + final Seq2> seq = Seq2.generate(s); + return seq(seq); + } + + /** + * @see Seq#generate(Object) + */ + static PairSeq generate(final Tuple2 value) { + final Seq2> seq = Seq2.generate(value); + return seq(seq); + } + + /** + * @see Seq#generate(Object) + */ + static PairSeq generate(final K key, final V value) { + final Seq2> seq = Seq2.generate(new Tuple2<>(key, value)); + return seq(seq); + } + + /** + * @see Seq#of(Object[]) + */ + static PairSeq of(final Tuple2... values) { + final Seq2> seq = Seq2.of(values); + return seq(seq); + } + + /** + * @see Seq#of(Object) + */ + static PairSeq of(final Tuple2 value) { + final Seq2> seq = Seq2.of(value); + return seq(seq); + } + + /** + * @see Seq#of(Object) + */ + static PairSeq of(final K key, final V value) { + final Seq2> seq = Seq2.of(new Tuple2<>(key, value)); + return seq(seq); + } + + /** + * @see Seq#seq(Stream) + */ + static PairSeq seq(final Stream> stream) { + final Seq2> seq = Seq2.seq(stream); + return seq(seq); + } + + /** + * @see Seq#seq(Supplier) + */ + static PairSeq seq(final Supplier> s) { + final Seq2> seq = Seq2.seq(s); + return seq(seq); + } + + /** + * @see Seq#seq(Iterator) + */ + static PairSeq seq(final Iterator> iterator) { + final Seq2> seq = Seq2.seq(iterator); + return seq(seq); + } + + /** + * @see Seq#seq(Enumeration) + */ + static PairSeq seq(final Enumeration> enumeration) { + final Seq2> seq = Seq2.seq(enumeration); + return seq(seq); + } + + /** + * @see Seq#seq(Spliterator) + */ + static PairSeq seq(final Spliterator> spliterator) { + final Seq2> seq = Seq2.seq(spliterator); + return seq(seq); + } + + /** + * @see Seq#seq(Object[], int, int) + */ + static PairSeq seq(final Tuple2[] values, final int startIndex, final int endIndex) { + final Seq2> seq = Seq2.seq(values, startIndex, endIndex); + return seq(seq); + } + + /** + * @see Seq#seq(Iterable) + */ + static PairSeq seq(final Iterable> iterable) { + final Seq2> seq = Seq2.seq(iterable); + return seq(seq); + } + + /** + * Wrap a {@code Stream} into a {@code PairSeq}. + */ + static PairSeq seq(final Seq2> seq2) { + return new PairSeqImpl<>(seq2); + } + + /** + * @see Seq#seq(Seq) + */ + static PairSeq seq(final Seq> seq) { + final Seq2> seq2 = Seq2.seq(seq); + return seq(seq2); + } + + /** + * @see Seq#seq(Map) + */ + static PairSeq seq(final Map map) { + final Seq> seq = Seq.seq(map); + return seq(seq); + } + + /** + * @see Stream#allMatch(Predicate) + */ + default boolean allMatch(final BiPredicate predicate) { + return this.allMatch(this.unwrap(predicate)); + } + + /** + * @deprecated Use {@link #allMatch(BiPredicate)} + */ + @Override + @Deprecated + default boolean allMatch(final Predicate> predicate) { + return this.toSeq2().allMatch(predicate); + } + + /** + * @see Stream#anyMatch(Predicate) + */ + default boolean anyMatch(final BiPredicate predicate) { + return this.anyMatch(this.unwrap(predicate)); + } + + /** + * @deprecated Use {@link #anyMatch(BiPredicate)} + */ + @Override + @Deprecated + default boolean anyMatch(final Predicate> predicate) { + return this.toSeq2().anyMatch(predicate); + } + + /** + * @see Seq#append(Stream) + */ + default PairSeq append(final Stream> other) { + return seq(this.toSeq2().append(other)); + } + + /** + * @see Seq#append(Iterable) + */ + default PairSeq append(final Iterable> other) { + return seq(this.toSeq2().append(other)); + } + + /** + * @see Seq#append(Seq) + */ + default PairSeq append(final Seq> other) { + return seq(this.toSeq2().append(other)); + } + + /** + * @see Seq#append(Seq) + */ + default PairSeq append(final Seq2> other) { + return seq(this.toSeq2().append(other)); + } + + /** + * @see Seq#append(Seq) + */ + default PairSeq append(final PairSeq other) { + return this.append(other.toSeq2()); + } + + /** + * @see Seq#append(Object) + * @deprecated Use {@link #append(Object, Object)} + */ + @Deprecated + default PairSeq append(final Tuple2 other) { + return seq(this.toSeq2().append(other)); + } + + /** + * @see Seq#append(Object) + */ + default PairSeq append(final K otherKey, final V otherValue) { + return this.append(new Tuple2<>(otherKey, otherValue)); + } + + /** + * @see Seq#append(Object[]) + */ + default PairSeq append(final Tuple2... other) { + return seq(this.toSeq2().append(other)); + } + + /** + * @see Seq#append(Optional) + */ + default PairSeq append(final Optional> other) { + return seq(this.toSeq2().append(other)); + } + + /** + * @deprecated Use {@link #avg(BiFunction)} + */ + @Override + @Deprecated + default Optional avg(final Function, ? extends U> function) { + return BaseSeq.super.avg(function); + } + + /** + * @see Seq#avg(Function) + */ + default Optional avg(final BiFunction function) { + return this.avg(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #avgDouble(ToDoubleBiFunction)} + */ + @Override + @Deprecated + default double avgDouble(final ToDoubleFunction> function) { + return BaseSeq.super.avgDouble(function); + } + + /** + * @see Seq#avgDouble(ToDoubleFunction) + */ + default double avgDouble(final ToDoubleBiFunction function) { + return this.avgDouble(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #avgInt(ToIntBiFunction)} + */ + @Override + @Deprecated + default double avgInt(final ToIntFunction> function) { + return BaseSeq.super.avgInt(function); + } + + /** + * @see Seq#avgInt(ToIntFunction) + */ + default double avgInt(final ToIntBiFunction function) { + return this.avgInt(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #avgLong(ToLongBiFunction)} + */ + @Override + @Deprecated + default double avgLong(final ToLongFunction> function) { + return BaseSeq.super.avgLong(function); + } + + /** + * @see Seq#avgLong(ToLongFunction) + */ + default double avgLong(final ToLongBiFunction function) { + return this.avgLong(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #bitAnd(BiFunction)} + */ + @Override + @Deprecated + default Optional bitAnd(final Function, ? extends U> function) { + return BaseSeq.super.bitAnd(function); + } + + /** + * @see Seq#bitAnd(Function) + */ + default Optional bitAnd(final BiFunction function) { + return this.bitAnd(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #bitAndInt(ToIntBiFunction)} + */ + @Override + @Deprecated + default int bitAndInt(final ToIntFunction> function) { + return BaseSeq.super.bitAndInt(function); + } + + /** + * @see Seq#bitAndInt(ToIntFunction) + */ + default int bitAndInt(final ToIntBiFunction function) { + return this.bitAndInt(this.unwrap(function)); + } + + /** + * @see Seq#bitAndLong(ToLongFunction) + */ + default long bitAndLong(final ToLongBiFunction function) { + return this.bitAndLong(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #bitAndLong(ToLongBiFunction)} + */ + @Override + @Deprecated + default long bitAndLong(final ToLongFunction> function) { + return BaseSeq.super.bitAndLong(function); + } + + /** + * @deprecated Use {@link #bitOr(BiFunction)} + */ + @Override + @Deprecated + default Optional bitOr(final Function, ? extends U> function) { + return BaseSeq.super.bitOr(function); + } + + /** + * @see Seq#bitOr(Function) + */ + default Optional bitOr(final BiFunction function) { + return this.bitOr(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #bitOrInt(ToIntBiFunction)} + */ + @Override + @Deprecated + default int bitOrInt(final ToIntFunction> function) { + return BaseSeq.super.bitOrInt(function); + } + + /** + * @see Seq#bitOrInt(ToIntFunction) + */ + default int bitOrInt(final ToIntBiFunction function) { + return this.bitOrInt(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #bitOrLong(ToLongBiFunction)} + */ + @Override + @Deprecated + default long bitOrLong(final ToLongFunction> function) { + return BaseSeq.super.bitOrLong(function); + } + + /** + * @see Seq#bitOrLong(ToLongFunction) + */ + default long bitOrLong(final ToLongBiFunction function) { + return this.bitOrLong(this.unwrap(function)); + } + + /** + * @see Seq#cast(Class) + */ + default Seq2 cast(final Class type) { + return this.toSeq2().cast(type); + } + + @Override + default void close() { + this.toSeq2().close(); + } + + @Override + default R collect(final Supplier supplier, final BiConsumer> accumulator, + final BiConsumer combiner) { + return this.toSeq2().collect(supplier, accumulator, combiner); + } + + @Override + default R collect(final Collector, A, R> collector) { + return this.toSeq2().collect(collector); + } + + /** + * @see Seq#concat(Object) + */ + default PairSeq concat(final K otherKey, final V otherValue) { + return this.concat(new Tuple2<>(otherKey, otherValue)); + } + + /** + * @see Seq#concat(Object) + * @deprecated Use {@link #concat(Object, Object)} + */ + @Deprecated + default PairSeq concat(final Tuple2 other) { + return seq(this.toSeq2().concat(other)); + } + + /** + * @see Seq#concat(Object[]) + */ + default PairSeq concat(final Tuple2... other) { + return seq(this.toSeq2().concat(other)); + } + + /** + * @see Seq#concat(Iterable) + */ + default PairSeq concat(final Iterable> other) { + return seq(this.toSeq2().concat(other)); + } + + /** + * @see Seq#concat(Stream, Stream) + */ + default PairSeq concat(final Stream> other) { + return seq(this.toSeq2().concat(other)); + } + + /** + * @see Seq#concat(Seq) + */ + default PairSeq concat(final Seq> other) { + return seq(this.toSeq2().concat(other)); + } + + /** + * @see Seq#concat(Seq) + */ + default PairSeq concat(final Seq2> other) { + return seq(this.toSeq2().concat(other)); + } + + /** + * @see Seq#concat(Seq) + */ + default PairSeq concat(final PairSeq other) { + return seq(this.toSeq2().concat(other.toSeq2())); + } + + /** + * @see Seq#concat(Optional) + */ + default PairSeq concat(final Optional> other) { + return seq(this.toSeq2().concat(other)); + } + + /** + * @see Seq#contains(Object) + */ + default boolean contains(final K otherKey, final V otherValue) { + return this.contains(new Tuple2<>(otherKey, otherValue)); + } + + /** + * @deprecated Use {@link #contains(Object, Object)} + */ + @Override + @Deprecated + default boolean contains(final Tuple2 otherValue) { + return BaseSeq.super.contains(otherValue); + } + + /** + * @see Seq#containsAll(Seq) + */ + default boolean containsAll(final PairSeq other) { + return this.containsAll(other.toSeq2()); + } + + /** + * @see Seq#containsAny(Seq) + */ + default boolean containsAny(final PairSeq other) { + return this.containsAny(other.toSeq2()); + } + + @Override + default long count() { + return this.toSeq2().count(); + } + + /** + * @deprecated Use {@link #count(BiPredicate)} + */ + @Override + @Deprecated + default long count(final Predicate> predicate) { + return BaseSeq.super.count(predicate); + } + + /** + * @see Seq#count(Predicate) + */ + default long count(final BiPredicate predicate) { + return this.count(this.unwrap(predicate)); + } + + /** + * @deprecated Use {@link #countDistinct(BiPredicate)} + */ + @Override + @Deprecated + default long countDistinct(final Predicate> predicate) { + return BaseSeq.super.countDistinct(predicate); + } + + /** + * @see Seq#countDistinct(Predicate) + */ + default long countDistinct(final BiPredicate predicate) { + return this.countDistinct(this.unwrap(predicate)); + } + + /** + * @deprecated Use {@link #countDistinctBy(BiFunction)} + */ + @Override + @Deprecated + default long countDistinctBy(final Function, ? extends U> function) { + return BaseSeq.super.countDistinctBy(function); + } + + /** + * @see Seq#countDistinctBy(Function) + */ + default long countDistinctBy(final BiFunction function) { + return this.countDistinctBy(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #countDistinctBy(BiFunction, Predicate)} + */ + @Override + @Deprecated + default long countDistinctBy(final Function, ? extends U> function, + final Predicate predicate) { + return BaseSeq.super.countDistinctBy(function, predicate); + } + + /** + * @see Seq#countDistinctBy(Function, Predicate) + */ + default long countDistinctBy(final BiFunction function, + final Predicate predicate) { + return this.countDistinctBy(t -> t.map(function), predicate); + } + + default long countDistinctKeys() { + return this.keys().countDistinct(); + } + + default long countDistinctKeys(final Predicate predicate) { + return this.keys().countDistinct(predicate); + } + + default long countDistinctKeysBy(final Function function) { + return this.keys().countDistinctBy(function); + } + + default long countDistinctKeysBy(final Function function, + final Predicate predicate) { + return this.keys().countDistinctBy(function, predicate); + } + + default long countDistinctValues() { + return this.values().countDistinct(); + } + + default long countDistinctValues(final Predicate predicate) { + return this.values().countDistinct(predicate); + } + + default long countDistinctValuesBy(final Function function) { + return this.values().countDistinctBy(function); + } + + default long countDistinctValuesBy(final Function function, + final Predicate predicate) { + return this.values().countDistinctBy(function, predicate); + } + + default long countKeys(final Predicate predicate) { + return this.keys().count(predicate); + } + + default long countValues(final Predicate predicate) { + return this.values().count(predicate); + } + + /** + * @see Seq#crossApply(Function) + * @deprecated Use {@link #crossApply(BiFunction)} + */ + @Deprecated + default PairSeq, U> crossApply( + final Function, ? extends Iterable> function) { + return this.toSeq2().crossApply(function); + } + + /** + * @see Seq#crossApply(Function) + */ + default PairSeq, U> crossApply( + final BiFunction> function) { + return this.crossApply(this.unwrap(function)); + } + + /** + * @see Seq#crossJoin(Stream) + */ + default PairSeq, U> crossJoin(final Stream other) { + return this.toSeq2().crossJoin(other); + } + + /** + * @see Seq#crossJoin(Iterable) + */ + default PairSeq, U> crossJoin(final Iterable other) { + return this.toSeq2().crossJoin(other); + } + + /** + * @see Seq#crossJoin(Seq) + */ + default PairSeq, U> crossJoin(final Seq other) { + return this.toSeq2().crossJoin(other); + } + + /** + * @see Seq#crossJoin(Seq) + */ + default PairSeq, U> crossJoin(final Seq2 other) { + return this.toSeq2().crossJoin(other); + } + + /** + * @see Seq#crossJoin(Seq) + */ + default PairSeq, Tuple2> crossJoin(final PairSeq other) { + return this.crossJoin(other.toSeq2()); + } + + /** + * @see Seq#crossSelfJoin() + */ + default PairSeq, Tuple2> crossSelfJoin() { + return this.toSeq2().crossSelfJoin(); + } + + /** + * @see Seq#cycle() + */ + default PairSeq cycle() { + return seq(this.toSeq2().cycle()); + } + + /** + * @see Seq#cycle(long) + */ + default PairSeq cycle(final long times) { + return seq(this.toSeq2().cycle(times)); + } + + @Override + default PairSeq distinct() { + return seq(this.toSeq2().distinct()); + } + + /** + * @see Seq#distinct(Function) + * @deprecated Use {@link #distinct(BiFunction)} + */ + @Deprecated + default PairSeq distinct(final Function, ? extends U> keyExtractor) { + return seq(this.toSeq2().distinct(keyExtractor)); + } + + /** + * @see Seq#distinct(Function) + */ + default PairSeq distinct(final BiFunction keyExtractor) { + return this.distinct(this.unwrap(keyExtractor)); + } + + /** + * @see Seq#drop(long) + */ + default PairSeq drop(final long n) { + return seq(this.toSeq2().drop(n)); + } + + /** + * @deprecated Use {@link #dropWhile(BiPredicate)} + */ + @Override + @Deprecated + default PairSeq dropWhile(final Predicate> predicate) { + return seq(this.toSeq2().dropWhile(predicate)); + } + + /** + * @see Seq#dropWhile(Predicate) + */ + default PairSeq dropWhile(final BiPredicate predicate) { + return this.dropWhile(this.unwrap(predicate)); + } + + /** + * @see Seq#duplicate() + */ + default Tuple2, PairSeq> duplicate() { + return this.toSeq2().duplicate().map1(PairSeq::seq).map2(PairSeq::seq); + } + + /** + * @deprecated Use {@link #filter(BiPredicate)} + */ + @Override + @Deprecated + default PairSeq filter(final Predicate> predicate) { + return seq(this.toSeq2().filter(predicate)); + } + + /** + * @see Stream#filter(Predicate) + */ + default PairSeq filter(final BiPredicate predicate) { + return this.filter(this.unwrap(predicate)); + } + + default PairSeq filterKeys(final Predicate predicate) { + return seq(this.toSeq2().filter(t -> predicate.test(t.v1()))); + } + + default PairSeq filterKeysNot(final Predicate predicate) { + return seq(this.toSeq2().filterNot(t -> predicate.test(t.v1()))); + } + + default PairSeq filterNot(final Predicate> predicate) { + return seq(this.toSeq2().filterNot(predicate)); + } + + default PairSeq filterNot(final BiPredicate predicate) { + return seq(this.toSeq2().filterNot(this.unwrap(predicate))); + } + + default PairSeq filterValues(final Predicate predicate) { + return seq(this.toSeq2().filter(t -> predicate.test(t.v2()))); + } + + default PairSeq filterValuesNot(final Predicate predicate) { + return seq(this.toSeq2().filterNot(t -> predicate.test(t.v2()))); + } + + @Override + default Optional> findAny() { + return this.toSeq2().findAny(); + } + + @Override + default Optional> findFirst() { + return this.toSeq2().findFirst(); + } + + /** + * @deprecated Use {@link #findFirst(BiPredicate)} + */ + @Override + @Deprecated + default Optional> findFirst(final Predicate> predicate) { + return BaseSeq.super.findFirst(predicate); + } + + /** + * @see Seq#findFirst(Predicate) + */ + default Optional> findFirst(final BiPredicate predicate) { + return this.findFirst(this.unwrap(predicate)); + } + + /** + * @see Seq#findLast(Predicate) + */ + default Optional> findLast(final BiPredicate predicate) { + return this.findLast(this.unwrap(predicate)); + } + + /** + * @deprecated Use {@link #findLast(BiPredicate)} + */ + @Override + @Deprecated + default Optional> findLast(final Predicate> predicate) { + return BaseSeq.super.findLast(predicate); + } + + /** + * @deprecated Use {@link #flatMap(BiFunction)} + */ + @Override + @Deprecated + default Seq2 flatMap(final Function, ? extends Stream> mapper) { + return this.toSeq2().flatMap(mapper); + } + + /** + * @see Stream#flatMap(Function) + */ + default Seq2 flatMap(final BiFunction> mapper) { + return this.flatMap(this.unwrap(mapper)); + } + + default PairSeq flatMapKeys(final Function> function) { + return this.flatMapToPair((k, v) -> function.apply(k).map(k2 -> new Tuple2<>(k2, v))); + } + + default PairSeq flatMapKeysToPair( + final Function>> function) { + return seq(this.flatMapKeys(function).keys()); + } + + /** + * @deprecated Use {@link #flatMapToDouble(BiFunction)} + */ + @Override + @Deprecated + default DoubleStream flatMapToDouble(final Function, ? extends DoubleStream> mapper) { + return this.toSeq2().flatMapToDouble(mapper); + } + + /** + * @see Stream#flatMapToDouble(Function) + */ + default DoubleStream flatMapToDouble(final BiFunction mapper) { + return this.flatMapToDouble(t -> t.map(mapper)); + } + + /** + * @deprecated Use {@link #flatMapToInt(BiFunction)} + */ + @Override + @Deprecated + default IntStream flatMapToInt(final Function, ? extends IntStream> mapper) { + return this.toSeq2().flatMapToInt(mapper); + } + + /** + * @see Stream#flatMapToInt(Function) + */ + default IntStream flatMapToInt(final BiFunction mapper) { + return this.flatMapToInt(t -> t.map(mapper)); + } + + /** + * @deprecated Use {@link #flatMapToLong(BiFunction)} + */ + @Override + @Deprecated + default LongStream flatMapToLong(final Function, ? extends LongStream> mapper) { + return this.toSeq2().flatMapToLong(mapper); + } + + /** + * @see Stream#flatMapToLong(Function) + */ + default LongStream flatMapToLong(final BiFunction mapper) { + return this.flatMapToLong(t -> t.map(mapper)); + } + + default PairSeq flatMapToPair( + final BiFunction>> mapper) { + final Seq2> seq2 = this.flatMap(t -> t.map(mapper)); + return seq(seq2); + } + + default PairSeq flatMapValues(final Function> function) { + return this.flatMapToPair((k, v) -> function.apply(v).map(v2 -> new Tuple2<>(k, v2))); + } + + default PairSeq flatMapValuesToPair( + final Function>> function) { + return seq(this.flatMapValues(function).values()); + } + + /** + * @deprecated Use {@link #forEach(BiConsumer)} + */ + @Override + @Deprecated + default void forEach(final Consumer> action) { + this.toSeq2().forEach(action); + } + + /** + * @see Stream#forEach(Consumer) + * @see Iterable#forEach(Consumer) + */ + default void forEach(final BiConsumer action) { + this.toSeq2().forEach(this.unwrap(action)); + } + + /** + * @deprecated Use {@link #forEachOrdered(BiConsumer)} + */ + @Override + @Deprecated + default void forEachOrdered(final Consumer> action) { + this.toSeq2().forEachOrdered(action); + } + + /** + * @see Stream#forEachOrdered(Consumer) + */ + default void forEachOrdered(final BiConsumer action) { + this.forEachOrdered(this.unwrap(action)); + } + + /** + * @see Seq#groupBy(Function) + */ + default Map>> groupBy(final BiFunction classifier) { + return this.groupBy(this.unwrap(classifier)); + } + + /** + * @deprecated Use {@link #groupBy(BiFunction)} + */ + @Override + @Deprecated + default Map>> groupBy(final Function, ? extends K1> classifier) { + return BaseSeq.super.groupBy(classifier); + } + + /** + * @see Seq#groupBy(Function, Collector) + */ + default Map groupBy(final BiFunction classifier, + final Collector, A, D> downstream) { + return this.groupBy(this.unwrap(classifier), downstream); + } + + /** + * @deprecated Use {@link #groupBy(BiFunction, Collector)} + */ + @Override + @Deprecated + default Map groupBy(final Function, ? extends K1> classifier, + final Collector, A, D> downstream) { + return BaseSeq.super.groupBy(classifier, downstream); + } + + /** + * @see Seq#groupBy(Function, Supplier, Collector) + */ + default > M groupBy(final BiFunction classifier, + final Supplier mapFactory, final Collector, A, D> downstream) { + return this.groupBy(this.unwrap(classifier), mapFactory, downstream); + } + + /** + * @deprecated Use {@link #groupBy(BiFunction, Supplier, Collector)} + */ + @Override + @Deprecated + default > M groupBy(final Function, ? extends K1> classifier, + final Supplier mapFactory, final Collector, A, D> downstream) { + return BaseSeq.super.groupBy(classifier, mapFactory, downstream); + } + + default PairSeq> groupByKey() { + final PairSeq>> grouped = this.toSeq2().grouped(Tuple2::v1); + return grouped.mapValues(s -> s.map(Tuple2::v2)); + } + + /** + * @see Seq#grouped(Function) + * @deprecated Use {@link #grouped(BiFunction)} + */ + @Deprecated + default PairSeq> grouped(final Function, K1> classifier) { + return this.toSeq2().grouped(classifier).mapValues(PairSeq::seq); + } + + /** + * @see Seq#grouped(Function) + */ + default PairSeq> grouped(final BiFunction classifier) { + return this.toSeq2().grouped(t -> t.map(classifier)).mapValues(PairSeq::seq); + } + + /** + * @see Seq#grouped(Function, Collector) + * @deprecated Use {@link #grouped(BiFunction, Collector)} + */ + @Deprecated + default PairSeq grouped(final Function, ? extends K1> classifier, + final Collector, A, D> downstream) { + return this.toSeq2().grouped(classifier, downstream); + } + + /** + * @see Seq#grouped(Function, Collector) + */ + default PairSeq grouped(final BiFunction classifier, + final Collector, A, D> downstream) { + return this.toSeq2().grouped(t -> t.map(classifier), downstream); + } + + /** + * @deprecated Use {@link #indexOf(Object, Object)} + */ + @Override + @Deprecated + default OptionalLong indexOf(final Tuple2 element) { + return BaseSeq.super.indexOf(element); + } + + /** + * @see Seq#indexOf(Object) + */ + default OptionalLong indexOf(final K elementKey, final V elementValue) { + return this.indexOf(new Tuple2<>(elementKey, elementValue)); + } + + /** + * @deprecated Use {@link #indexOf(BiPredicate)} + */ + @Override + @Deprecated + default OptionalLong indexOf(final Predicate> predicate) { + return BaseSeq.super.indexOf(predicate); + } + + /** + * @see Seq#indexOf(Predicate) + */ + default OptionalLong indexOf(final BiPredicate predicate) { + return this.indexOf(this.unwrap(predicate)); + } + + /** + * @see Seq#innerJoin(Stream, BiPredicate) + */ + default PairSeq, U> innerJoin(final Stream other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().innerJoin(other, predicate); + } + + /** + * @see Seq#innerJoin(Iterable, BiPredicate) + */ + default PairSeq, U> innerJoin(final Iterable other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().innerJoin(other, predicate); + } + + /** + * @see Seq#innerJoin(Seq, BiPredicate) + */ + default PairSeq, U> innerJoin(final Seq other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().innerJoin(other, predicate); + } + + /** + * @see Seq#innerJoin(Seq, BiPredicate) + */ + default PairSeq, U> innerJoin(final Seq2 other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().innerJoin(other, predicate); + } + + /** + * @see Seq#innerJoin(Seq, BiPredicate) + */ + default PairSeq, Tuple2> innerJoin(final PairSeq other, + final BiPredicate, ? super Tuple2> predicate) { + return this.innerJoin(other.toSeq2(), predicate); + } + + /** + * @see Seq#innerSelfJoin(BiPredicate) + */ + default PairSeq, Tuple2> innerSelfJoin( + final BiPredicate, ? super Tuple2> predicate) { + return this.toSeq2().innerSelfJoin(predicate); + } + + /** + * @see Seq#intersperse(Object) + * @deprecated Use {@link #intersperse(Object, Object)} + */ + @Deprecated + default PairSeq intersperse(final Tuple2 value) { + return seq(this.toSeq2().intersperse(value)); + } + + /** + * @see Seq#intersperse(Object) + */ + default PairSeq intersperse(final K key, final V value) { + return this.intersperse(new Tuple2<>(key, value)); + } + + @Override + default boolean isParallel() { + return this.toSeq2().isParallel(); + } + + @Override + default Iterator> iterator() { + return this.toSeq2().iterator(); + } + + default Seq2 keys() { + return this.toSeq2().map(Tuple2::v1); + } + + /** + * @see Seq#leftOuterJoin(Stream, BiPredicate) + */ + default PairSeq, U> leftOuterJoin(final Stream other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().leftOuterJoin(other, predicate); + } + + /** + * @see Seq#leftOuterJoin(Iterable, BiPredicate) + */ + default PairSeq, U> leftOuterJoin(final Iterable other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().leftOuterJoin(other, predicate); + } + + /** + * @see Seq#leftOuterJoin(Seq, BiPredicate) + */ + default PairSeq, U> leftOuterJoin(final Seq other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().leftOuterJoin(other, predicate); + } + + /** + * @see Seq#leftOuterJoin(Seq, BiPredicate) + */ + default PairSeq, U> leftOuterJoin(final Seq2 other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().leftOuterJoin(other, predicate); + } + + /** + * @see Seq#leftOuterJoin(Seq, BiPredicate) + */ + default PairSeq, Tuple2> leftOuterJoin( + final PairSeq other, + final BiPredicate, ? super Tuple2> predicate) { + return this.leftOuterJoin(other.toSeq2(), predicate); + } + + /** + * @see Seq#leftOuterSelfJoin(BiPredicate) + */ + default PairSeq, Tuple2> leftOuterSelfJoin( + final BiPredicate, ? super Tuple2> predicate) { + return this.toSeq2().leftOuterSelfJoin(predicate); + } + + @Override + default PairSeq limit(final long maxSize) { + return seq(this.toSeq2().limit(maxSize)); + } + + /** + * @see Seq#limitUntil(Predicate) + * @deprecated Use {@link #limitUntil(BiPredicate)} + */ + @Deprecated + default PairSeq limitUntil(final Predicate> predicate) { + return seq(this.toSeq2().limitUntil(predicate)); + } + + /** + * @see Seq#limitUntil(Predicate) + */ + default PairSeq limitUntil(final BiPredicate predicate) { + return this.limitUntil(this.unwrap(predicate)); + } + + /** + * @see Seq#limitUntilClosed(Predicate) + * @deprecated Use {@link #limitUntilClosed(BiPredicate)} + */ + @Deprecated + default PairSeq limitUntilClosed(final Predicate> predicate) { + return seq(this.toSeq2().limitUntilClosed(predicate)); + } + + /** + * @see Seq#limitUntilClosed(Predicate) + */ + default PairSeq limitUntilClosed(final BiPredicate predicate) { + return this.limitUntilClosed(this.unwrap(predicate)); + } + + /** + * @see Seq#limitWhile(Predicate) + * @deprecated Use {@link #limitWhile(BiPredicate)} + */ + @Deprecated + default PairSeq limitWhile(final Predicate> predicate) { + return seq(this.toSeq2().limitWhile(predicate)); + } + + /** + * @see Seq#limitWhile(Predicate) + */ + default PairSeq limitWhile(final BiPredicate predicate) { + return this.limitWhile(this.unwrap(predicate)); + } + + /** + * @see Seq#limitWhileClosed(Predicate) + * @deprecated Use {@link #limitWhileClosed(BiPredicate)} + */ + @Deprecated + default PairSeq limitWhileClosed(final Predicate> predicate) { + return seq(this.toSeq2().limitWhileClosed(predicate)); + } + + /** + * @see Seq#limitWhileClosed(Predicate) + */ + default PairSeq limitWhileClosed(final BiPredicate predicate) { + return this.limitWhileClosed(this.unwrap(predicate)); + } + + /** + * @deprecated Use {@link #map(BiFunction)} + */ + @Override + @Deprecated + default Seq2 map(final Function, ? extends R> mapper) { + return this.toSeq2().map(mapper); + } + + default PairSeq map(final Function keyMapper, + final Function valueMapper) { + return this.mapKeys(keyMapper).mapValues(valueMapper); + } + + /** + * @see Stream#map(Function) + */ + default Seq2 map(final BiFunction function) { + return this.map(this.unwrap(function)); + } + + default PairSeq mapKeys(final Function function) { + final Seq2> seq = this.map(t -> t.map1(function)); + return seq(seq); + } + + /** + * @deprecated Use {@link #mapToDouble(ToDoubleBiFunction)} + */ + @Override + @Deprecated + default DoubleStream mapToDouble(final ToDoubleFunction> mapper) { + return this.toSeq2().mapToDouble(mapper); + } + + /** + * @see Stream#mapToDouble(ToDoubleFunction) + */ + default DoubleStream mapToDouble(final ToDoubleBiFunction function) { + return this.mapToDouble(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #mapToInt(ToIntBiFunction)} + */ + @Override + @Deprecated + default IntStream mapToInt(final ToIntFunction> mapper) { + return this.toSeq2().mapToInt(mapper); + } + + /** + * @see Stream#mapToInt(ToIntFunction) + */ + default IntStream mapToInt(final ToIntBiFunction function) { + return this.mapToInt(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #mapToLong(ToLongBiFunction)} + */ + @Override + @Deprecated + default LongStream mapToLong(final ToLongFunction> mapper) { + return this.toSeq2().mapToLong(mapper); + } + + /** + * @see Stream#mapToLong(ToLongFunction) + */ + default LongStream mapToLong(final ToLongBiFunction function) { + return this.mapToLong(this.unwrap(function)); + } + + default PairSeq mapToPair(final BiFunction keyMapper, + final BiFunction valueMapper) { + return this.mapToPair(this.toTuple(keyMapper, valueMapper)); + } + + default PairSeq mapToPair( + final BiFunction> function) { + return this.mapToPair(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #mapToPair(BiFunction)} + */ + @Deprecated + default PairSeq mapToPair( + final Function, ? extends Tuple2> function) { + return seq(this.map(function)); + } + + default PairSeq mapValues(final Function function) { + final Seq2> seq = this.map(t -> t.map2(function)); + return seq(seq); + } + + @Override + default Optional> max(final Comparator> comparator) { + return this.toSeq2().max(comparator); + } + + /** + * @deprecated Use {@link #max(BiFunction)} + */ + @Override + @Deprecated + default > Optional max(final Function, ? extends U> function) { + return BaseSeq.super.max(function); + } + + /** + * @see Seq#max(Function) + */ + default > Optional max(final BiFunction function) { + return this.max(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #max(BiFunction, Comparator)} + */ + @Override + @Deprecated + default Optional max(final Function, ? extends U> function, + final Comparator comparator) { + return BaseSeq.super.max(function, comparator); + } + + /** + * @see Seq#max(Function, Comparator) + */ + default Optional max(final BiFunction function, + final Comparator comparator) { + return this.max(t -> function.apply(t.v1(), t.v2()), comparator); + } + + /** + * @see Seq#maxAll() + */ + default PairSeq maxAll() { + return seq(this.toSeq2().maxAll()); + } + + /** + * @see Seq#maxAll(Comparator) + */ + default PairSeq maxAll(final Comparator> comparator) { + return seq(this.toSeq2().maxAll(comparator)); + } + + /** + * @see Seq#maxAll(Function) + * @deprecated Use {@link #maxAll(BiFunction)} + */ + @Deprecated + default > Seq2 maxAll(final Function, ? extends U> function) { + return this.toSeq2().maxAll(function); + } + + /** + * @see Seq#maxAll(Function) + */ + default > Seq2 maxAll(final BiFunction function) { + return this.maxAll(this.unwrap(function)); + } + + /** + * @see Seq#maxAll(Function, Comparator) + * @deprecated Use {@link #maxAll(BiFunction, Comparator)} + */ + @Deprecated + default Seq2 maxAll(final Function, ? extends U> function, + final Comparator comparator) { + return this.toSeq2().maxAll(function, comparator); + } + + /** + * @see Seq#maxAll(Function, Comparator) + */ + default Seq2 maxAll(final BiFunction function, + final Comparator comparator) { + return this.maxAll(t -> t.map(function), comparator); + } + + /** + * @see Seq#maxAllBy(Function) + * @deprecated Use {@link #maxAllBy(BiFunction)} + */ + @Deprecated + default > PairSeq maxAllBy( + final Function, ? extends U> function) { + return seq(this.toSeq2().maxAllBy(function)); + } + + /** + * @see Seq#maxAllBy(Function) + */ + default > PairSeq maxAllBy( + final BiFunction function) { + return this.maxAllBy(this.unwrap(function)); + } + + /** + * @see Seq#maxAllBy(Function, Comparator) + * @deprecated Use {@link #maxAllBy(BiFunction, Comparator)} + */ + @Deprecated + default PairSeq maxAllBy(final Function, ? extends U> function, + final Comparator comparator) { + return seq(this.toSeq2().maxAllBy(function, comparator)); + } + + /** + * @see Seq#maxAllBy(Function, Comparator) + */ + default PairSeq maxAllBy( + final BiFunction function, + final Comparator comparator) { + return this.maxAllBy(t -> t.map(function), comparator); + } + + /** + * @deprecated Use {@link #maxBy(BiFunction)} + */ + @Override + @Deprecated + default > Optional> maxBy( + final Function, ? extends U> function) { + return BaseSeq.super.maxBy(function); + } + + /** + * @see Seq#maxBy(Function) + */ + default > Optional> maxBy( + final BiFunction function) { + return this.maxBy(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #maxBy(BiFunction, Comparator)} + */ + @Override + @Deprecated + default Optional> maxBy(final Function, ? extends U> function, + final Comparator comparator) { + return BaseSeq.super.maxBy(function, comparator); + } + + /** + * @see Seq#maxBy(Function, Comparator) + */ + default Optional> maxBy(final BiFunction function, + final Comparator comparator) { + return this.maxBy(t -> t.map(function), comparator); + } + + /** + * @deprecated Use {@link #medianBy(BiFunction)} + */ + @Override + @Deprecated + default > Optional> medianBy( + final Function, ? extends U> function) { + return BaseSeq.super.medianBy(function); + } + + /** + * @see Seq#medianBy(Function) + */ + default > Optional> medianBy( + final BiFunction function) { + return this.medianBy(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #medianBy(BiFunction, Comparator)} + */ + @Override + @Deprecated + default Optional> medianBy(final Function, ? extends U> function, + final Comparator comparator) { + return BaseSeq.super.medianBy(function, comparator); + } + + /** + * @see Seq#medianBy(Function, Comparator) + */ + default Optional> medianBy(final BiFunction function, + final Comparator comparator) { + return this.medianBy(t -> t.map(function), comparator); + } + + @Override + default Optional> min(final Comparator> comparator) { + return this.toSeq2().min(comparator); + } + + /** + * @deprecated Use {@link #min(BiFunction)} + */ + @Override + @Deprecated + default > Optional min(final Function, ? extends U> function) { + return BaseSeq.super.min(function); + } + + /** + * @see Seq#min(Function) + */ + default > Optional min(final BiFunction function) { + return this.min(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #min(BiFunction, Comparator)} + */ + @Override + @Deprecated + default Optional min(final Function, ? extends U> function, + final Comparator comparator) { + return BaseSeq.super.min(function, comparator); + } + + /** + * @see Seq#min(Function, Comparator) + */ + default Optional min(final BiFunction function, + final Comparator comparator) { + return this.min(t -> function.apply(t.v1(), t.v2()), comparator); + } + + /** + * @see Seq#minAll() + */ + default PairSeq minAll() { + return seq(this.toSeq2().minAll()); + } + + /** + * @see Seq#minAll(Comparator) + */ + default PairSeq minAll(final Comparator> comparator) { + return seq(this.toSeq2().minAll(comparator)); + } + + /** + * @see Seq#minAll(Function) + * @deprecated Use {@link #minAll(BiFunction)} + */ + @Deprecated + default > Seq2 minAll(final Function, ? extends U> function) { + return this.toSeq2().minAll(function); + } + + /** + * @see Seq#minAll(Function) + */ + default > Seq2 minAll(final BiFunction function) { + return this.minAll(this.unwrap(function)); + } + + /** + * @see Seq#minAll(Function, Comparator) + * @deprecated Use {@link #minAll(BiFunction, Comparator)} + */ + @Deprecated + default Seq2 minAll(final Function, ? extends U> function, + final Comparator comparator) { + return this.toSeq2().minAll(function, comparator); + } + + /** + * @see Seq#minAll(Function, Comparator) + */ + default Seq2 minAll(final BiFunction function, + final Comparator comparator) { + return this.toSeq2().minAll(t -> function.apply(t.v1(), t.v2()), comparator); + } + + /** + * @see Seq#minAllBy(Function, Comparator) + * @deprecated Use {@link #minAllBy(BiFunction)} + */ + @Deprecated + default > PairSeq minAllBy( + final Function, ? extends U> function) { + return seq(this.toSeq2().minAllBy(function)); + } + + /** + * @see Seq#minAllBy(Function) + */ + default > PairSeq minAllBy( + final BiFunction function) { + return this.minAllBy(this.unwrap(function)); + } + + /** + * @see Seq#minAllBy(Function, Comparator) + * @deprecated Use {@link #minAllBy(BiFunction, Comparator)} + */ + @Deprecated + default PairSeq minAllBy(final Function, ? extends U> function, + final Comparator comparator) { + return seq(this.toSeq2().minAllBy(function, comparator)); + } + + /** + * @see Seq#minAllBy(Function, Comparator) + */ + default PairSeq minAllBy(final BiFunction function, + final Comparator comparator) { + return this.minAllBy(t -> t.map(function), comparator); + } + + /** + * @deprecated Use {@link #minBy(BiFunction)} + */ + @Override + @Deprecated + default > Optional> minBy( + final Function, ? extends U> function) { + return BaseSeq.super.minBy(function); + } + + /** + * @see Seq#minBy(Function) + */ + default > Optional> minBy( + final BiFunction function) { + return this.minBy(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #minBy(BiFunction, Comparator)} + */ + @Override + @Deprecated + default Optional> minBy(final Function, ? extends U> function, + final Comparator comparator) { + return BaseSeq.super.minBy(function, comparator); + } + + /** + * @see Seq#minBy(Function, Comparator) + */ + default Optional> minBy(final BiFunction function, + final Comparator comparator) { + return this.minBy(t -> function.apply(t.v1(), t.v2()), comparator); + } + + /** + * @see Seq#modeAll() + */ + default PairSeq modeAll() { + return seq(this.toSeq2().modeAll()); + } + + /** + * @see Seq#modeAllBy(Function) + * @deprecated Use {@link #modeAllBy(BiFunction)} + */ + @Deprecated + default PairSeq modeAllBy(final Function, ? extends U> function) { + return seq(this.toSeq2().modeAllBy(function)); + } + + /** + * @see Seq#modeAllBy(Function) + */ + default PairSeq modeAllBy(final BiFunction function) { + return this.modeAllBy(this.unwrap(function)); + } + + /** + * @see Seq#modeBy(Function) + * @deprecated Use {@link #modeBy(BiFunction)} + */ + @Override + @Deprecated + default Optional> modeBy(final Function, ? extends U> function) { + return BaseSeq.super.modeBy(function); + } + + /** + * @see Seq#modeBy(Function) + */ + default Optional> modeBy(final BiFunction function) { + return this.modeBy(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #noneMatch(BiPredicate)} + */ + @Override + @Deprecated + default boolean noneMatch(final Predicate> predicate) { + return this.toSeq2().noneMatch(predicate); + } + + /** + * @see Stream#noneMatch(Predicate) + */ + default boolean noneMatch(final BiPredicate predicate) { + return this.noneMatch(this.unwrap(predicate)); + } + + /** + * @see Seq#ofType(Class) + */ + default Seq2 ofType(final Class type) { + return this.toSeq2().ofType(type); + } + + @Override + default PairSeq onClose(final Runnable closeHandler) { + return seq(this.toSeq2().onClose(closeHandler)); + } + + /** + * @see Seq#onEmpty(Object) + * @deprecated Use {@link #onEmpty(Object, Object)} + */ + @Deprecated + default PairSeq onEmpty(final Tuple2 value) { + return seq(this.toSeq2().onEmpty(value)); + } + + /** + * @see Seq#onEmpty(Object) + */ + default PairSeq onEmpty(final K key, final V value) { + return this.onEmpty(new Tuple2<>(key, value)); + } + + /** + * @see Seq#onEmptyGet(Supplier) + */ + default PairSeq onEmptyGet(final Supplier> supplier) { + return seq(this.toSeq2().onEmptyGet(supplier)); + } + + /** + * @see Seq#onEmptyThrow(Supplier) + */ + default PairSeq onEmptyThrow(final Supplier supplier) { + return seq(this.toSeq2().onEmptyThrow(supplier)); + } + + /** + * @see Seq#outerApply(Function) + * @deprecated Use {@link #outerApply(BiFunction)} + */ + @Deprecated + default PairSeq, U> outerApply( + final Function, ? extends Iterable> function) { + return this.toSeq2().outerApply(function); + } + + /** + * @see Seq#outerApply(Function) + */ + default PairSeq, U> outerApply( + final BiFunction> function) { + return this.outerApply(this.unwrap(function)); + } + + @Override + default PairSeq parallel() { + return seq(this.toSeq2().parallel()); + } + + /** + * @see Seq#partition(Predicate) + * @deprecated Use {@link #partition(BiPredicate)} + */ + @Deprecated + default Tuple2, PairSeq> partition(final Predicate> predicate) { + return this.toSeq2().partition(predicate).map1(PairSeq::seq).map2(PairSeq::seq); + } + + /** + * @see Seq#partition(Predicate) + */ + default Tuple2, PairSeq> partition(final BiPredicate predicate) { + return this.partition(this.unwrap(predicate)); + } + + /** + * @deprecated Use {@link #peek(BiConsumer)} + */ + @Override + @Deprecated + default PairSeq peek(final Consumer> action) { + return seq(this.toSeq2().peek(action)); + } + + /** + * @see Stream#peek(Consumer) + */ + default PairSeq peek(final BiConsumer action) { + return this.peek(this.unwrap(action)); + } + + default PairSeq peekKey(final Consumer action) { + return seq(this.toSeq2().peek(t -> action.accept(t.v1()))); + } + + default PairSeq peekValue(final Consumer action) { + return seq(this.toSeq2().peek(t -> action.accept(t.v2()))); + } + + /** + * @deprecated Use {@link #percentileBy(double, BiFunction)} + */ + @Override + @Deprecated + default > Optional> percentileBy(final double percentile, + final Function, ? extends U> function) { + return BaseSeq.super.percentileBy(percentile, function); + } + + /** + * @see Seq#percentileBy(double, Function, Comparator) + */ + default > Optional> percentileBy(final double percentile, + final BiFunction function) { + return this.percentileBy(percentile, this.unwrap(function)); + } + + /** + * @deprecated Use {@link #percentileBy(double, BiFunction, Comparator)} + */ + @Override + @Deprecated + default Optional> percentileBy(final double percentile, + final Function, ? extends U> function, final Comparator comparator) { + return BaseSeq.super.percentileBy(percentile, function, comparator); + } + + /** + * @see Seq#percentileBy(double, Function) + */ + default Optional> percentileBy(final double percentile, + final BiFunction function, final Comparator comparator) { + return this.percentileBy(percentile, t -> t.map(function), comparator); + } + + /** + * @see Seq#prepend(Object) + */ + default PairSeq prepend(final K otherKey, final V otherValue) { + return this.prepend(new Tuple2<>(otherKey, otherValue)); + } + + /** + * @see Seq#prepend(Object) + * @deprecated Use {@link #prepend(Object, Object)} + */ + @Deprecated + default PairSeq prepend(final Tuple2 other) { + return seq(this.toSeq2().prepend(other)); + } + + /** + * @see Seq#prepend(Object[]) + */ + default PairSeq prepend(final Tuple2... other) { + return seq(this.toSeq2().prepend(other)); + } + + /** + * @see Seq#prepend(Iterable) + */ + default PairSeq prepend(final Iterable> other) { + return seq(this.toSeq2().prepend(other)); + } + + /** + * @see Seq#prepend(Stream) + */ + default PairSeq prepend(final Stream> other) { + return seq(this.toSeq2().prepend(other)); + } + + /** + * @see Seq#prepend(Seq) + */ + default PairSeq prepend(final Seq> other) { + return seq(this.toSeq2().prepend(other)); + } + + /** + * @see Seq#prepend(Seq) + */ + default PairSeq prepend(final Seq2> other) { + return seq(this.toSeq2().prepend(other)); + } + + /** + * @see Seq#prepend(Seq) + */ + default PairSeq prepend(final PairSeq other) { + return this.prepend(other.toSeq2()); + } + + /** + * @see Seq#prepend(Optional) + */ + default PairSeq prepend(final Optional> other) { + return seq(this.toSeq2().prepend(other)); + } + + @Override + default Tuple2 reduce(final Tuple2 identity, final BinaryOperator> accumulator) { + return this.toSeq2().reduce(identity, accumulator); + } + + @Override + default Optional> reduce(final BinaryOperator> accumulator) { + return this.toSeq2().reduce(accumulator); + } + + @Override + default U reduce(final U identity, final BiFunction, U> accumulator, + final BinaryOperator combiner) { + return this.toSeq2().reduce(identity, accumulator, combiner); + } + + default PairSeq reduceByKey(final V identity, final BinaryOperator accumulator) { + return this.groupByKey().mapValues(s -> s.reduce(identity, accumulator)); + } + + default PairSeq reduceByKey(final BinaryOperator accumulator) { + return this.groupByKey().flatMapValues(s -> s.reduce(accumulator).stream()); + } + + default PairSeq reduceByKey(final U identity, final BiFunction accumulator, + final BinaryOperator combiner) { + return this.groupByKey().mapValues(s -> s.reduce(identity, accumulator, combiner)); + } + + /** + * @see Seq#remove(Object) + * @deprecated Use {@link #remove(Object, Object)} + */ + @Deprecated + default PairSeq remove(final Tuple2 other) { + return seq(this.toSeq2().remove(other)); + } + + /** + * @see Seq#remove(Object) + */ + default PairSeq remove(final K otherKey, final V otherValue) { + return this.remove(new Tuple2<>(otherKey, otherValue)); + } + + /** + * @see Seq#removeAll(Seq) + */ + default PairSeq removeAll(final PairSeq other) { + return this.removeAll(other.toSeq2()); + } + + /** + * @see Seq#removeAll(Object[]) + */ + default PairSeq removeAll(final Tuple2... other) { + return seq(this.toSeq2().removeAll(other)); + } + + /** + * @see Seq#removeAll(Stream) + */ + default PairSeq removeAll(final Stream> other) { + return seq(this.toSeq2().removeAll(other)); + } + + /** + * @see Seq#removeAll(Iterable) + */ + default PairSeq removeAll(final Iterable> other) { + return seq(this.toSeq2().removeAll(other)); + } + + /** + * @see Seq#removeAll(Seq) + */ + default PairSeq removeAll(final Seq> other) { + return seq(this.toSeq2().removeAll(other)); + } + + /** + * @see Seq#removeAll(Seq) + */ + default PairSeq removeAll(final Seq2> other) { + return seq(this.toSeq2().removeAll(other)); + } + + /** + * @see Seq#retainAll(Object[]) + */ + default PairSeq retainAll(final Tuple2... other) { + return seq(this.toSeq2().retainAll(other)); + } + + /** + * @see Seq#retainAll(Stream) + */ + default PairSeq retainAll(final Stream> other) { + return seq(this.toSeq2().retainAll(other)); + } + + /** + * @see Seq#retainAll(Iterable) + */ + default PairSeq retainAll(final Iterable> other) { + return seq(this.toSeq2().retainAll(other)); + } + + /** + * @see Seq#retainAll(Seq) + */ + default PairSeq retainAll(final Seq> other) { + return seq(this.toSeq2().retainAll(other)); + } + + /** + * @see Seq#retainAll(Seq) + */ + default PairSeq retainAll(final Seq2> other) { + return seq(this.toSeq2().retainAll(other)); + } + + /** + * @see Seq#retainAll(Seq) + */ + default PairSeq retainAll(final PairSeq other) { + return this.retainAll(other.toSeq2()); + } + + /** + * @see Seq#reverse() + */ + default PairSeq reverse() { + return seq(this.toSeq2().reverse()); + } + + /** + * @see Seq#rightOuterJoin(Stream, BiPredicate) + */ + default PairSeq, U> rightOuterJoin(final Stream other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().rightOuterJoin(other, predicate); + } + + /** + * @see Seq#rightOuterJoin(Iterable, BiPredicate) + */ + default PairSeq, U> rightOuterJoin(final Iterable other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().rightOuterJoin(other, predicate); + } + + /** + * @see Seq#rightOuterJoin(Seq, BiPredicate) + */ + default PairSeq, U> rightOuterJoin(final Seq other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().rightOuterJoin(other, predicate); + } + + /** + * @see Seq#rightOuterJoin(Seq, BiPredicate) + */ + default PairSeq, U> rightOuterJoin(final Seq2 other, + final BiPredicate, ? super U> predicate) { + return this.toSeq2().rightOuterJoin(other, predicate); + } + + /** + * @see Seq#rightOuterJoin(Seq, BiPredicate) + */ + default PairSeq, Tuple2> rightOuterJoin( + final PairSeq other, + final BiPredicate, ? super Tuple2> predicate) { + return this.rightOuterJoin(other.toSeq2(), predicate); + } + + /** + * @see Seq#rightOuterSelfJoin(BiPredicate) + */ + default PairSeq, Tuple2> rightOuterSelfJoin( + final BiPredicate, ? super Tuple2> predicate) { + return this.toSeq2().rightOuterSelfJoin(predicate); + } + + /** + * @see Seq#scanLeft(Object, BiFunction) + */ + default Seq2 scanLeft(final U seed, + final BiFunction, ? extends U> function) { + return this.toSeq2().scanLeft(seed, function); + } + + /** + * @see Seq#scanRight(Object, BiFunction) + */ + default Seq2 scanRight(final U seed, + final BiFunction, ? super U, ? extends U> function) { + return this.toSeq2().scanRight(seed, function); + } + + @Override + default PairSeq sequential() { + return seq(this.toSeq2().sequential()); + } + + /** + * @see Seq#shuffle() + */ + default PairSeq shuffle() { + return seq(this.toSeq2().shuffle()); + } + + /** + * @see Seq#shuffle(Random) + */ + default PairSeq shuffle(final Random random) { + return seq(this.toSeq2().shuffle(random)); + } + + @Override + default PairSeq skip(final long n) { + return seq(this.toSeq2().skip(n)); + } + + /** + * @see Seq#skipUntil(Predicate) + * @deprecated Use {@link #skipUntil(BiPredicate)} + */ + @Deprecated + default PairSeq skipUntil(final Predicate> predicate) { + return seq(this.toSeq2().skipUntil(predicate)); + } + + /** + * @see Seq#skipUntil(Predicate) + */ + default PairSeq skipUntil(final BiPredicate predicate) { + return this.skipUntil(this.unwrap(predicate)); + } + + /** + * @see Seq#skipUntilClosed(Predicate) + * @deprecated Use {@link #skipUntilClosed(BiPredicate)} + */ + @Deprecated + default PairSeq skipUntilClosed(final Predicate> predicate) { + return seq(this.toSeq2().skipUntilClosed(predicate)); + } + + /** + * @see Seq#skipWhileClosed(Predicate) + */ + default PairSeq skipUntilClosed(final BiPredicate predicate) { + return this.skipUntilClosed(this.unwrap(predicate)); + } + + /** + * @see Seq#skipWhile(Predicate) + * @deprecated Use {@link #skipWhile(BiPredicate)} + */ + @Deprecated + default PairSeq skipWhile(final Predicate> predicate) { + return seq(this.toSeq2().skipWhile(predicate)); + } + + /** + * @see Seq#skipWhile(Predicate) + */ + default PairSeq skipWhile(final BiPredicate predicate) { + return this.skipWhile(this.unwrap(predicate)); + } + + /** + * @see Seq#skipWhileClosed(Predicate) + * @deprecated Use {@link #skipWhileClosed(BiPredicate)} + */ + @Deprecated + default PairSeq skipWhileClosed(final Predicate> predicate) { + return seq(this.toSeq2().skipWhileClosed(predicate)); + } + + /** + * @see Seq#skipWhileClosed(Predicate) + */ + default PairSeq skipWhileClosed(final BiPredicate predicate) { + return this.skipWhileClosed(this.unwrap(predicate)); + } + + /** + * @see Seq#slice(long, long) + */ + default PairSeq slice(final long from, final long to) { + return seq(this.toSeq2().slice(from, to)); + } + + /** + * @see Seq#sliding(long) + */ + default Seq2> sliding(final long size) { + return this.toSeq2().sliding(size).map(PairSeq::seq); + } + + @Override + default PairSeq sorted() { + return seq(this.toSeq2().sorted()); + } + + @Override + default PairSeq sorted(final Comparator> comparator) { + return seq(this.toSeq2().sorted(comparator)); + } + + /** + * @see Seq#sorted(Function) + * @deprecated Use {@link #sorted(BiFunction)} + */ + @Deprecated + default > PairSeq sorted( + final Function, ? extends U> function) { + return seq(this.toSeq2().sorted(function)); + } + + /** + * @see Seq#sorted(Function) + */ + default > PairSeq sorted( + final BiFunction function) { + return this.sorted(this.unwrap(function)); + } + + /** + * @see Seq#sorted(Function, Comparator) + * @deprecated Use {@link #sorted(BiFunction, Comparator)} + */ + @Deprecated + default PairSeq sorted(final Function, ? extends U> function, + final Comparator comparator) { + return seq(this.toSeq2().sorted(function, comparator)); + } + + /** + * @see Seq#sorted(Function, Comparator) + */ + default PairSeq sorted(final BiFunction function, + final Comparator comparator) { + return this.sorted(t -> t.map(function), comparator); + } + + /** + * @see Seq#splitAt(long) + */ + default Tuple2, PairSeq> splitAt(final long position) { + return this.toSeq2().splitAt(position).map1(PairSeq::seq).map2(PairSeq::seq); + } + + /** + * @see Seq#splitAtHead() + */ + default Tuple2>, PairSeq> splitAtHead() { + return this.toSeq2().splitAtHead().map2(PairSeq::seq); + } + + @Override + default Spliterator> spliterator() { + return this.toSeq2().spliterator(); + } + + /** + * @deprecated Use {@link #sum(BiFunction)} + */ + @Override + @Deprecated + default Optional sum(final Function, ? extends U> function) { + return BaseSeq.super.sum(function); + } + + /** + * @see Seq#sum(Function) + */ + default Optional sum(final BiFunction function) { + return this.sum(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #sumDouble(ToDoubleBiFunction)} + */ + @Override + @Deprecated + default double sumDouble(final ToDoubleFunction> function) { + return BaseSeq.super.sumDouble(function); + } + + /** + * @see Seq#sumDouble(ToDoubleFunction) + */ + default double sumDouble(final ToDoubleBiFunction function) { + return this.sumDouble(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #sumInt(ToIntBiFunction)} + */ + @Override + @Deprecated + default int sumInt(final ToIntFunction> function) { + return BaseSeq.super.sumInt(function); + } + + /** + * @see Seq#sumInt(ToIntFunction) + */ + default int sumInt(final ToIntBiFunction function) { + return this.sumInt(this.unwrap(function)); + } + + /** + * @deprecated Use {@link #sumLong(ToLongBiFunction)} + */ + @Override + @Deprecated + default long sumLong(final ToLongFunction> function) { + return BaseSeq.super.sumLong(function); + } + + /** + * @see Seq#sumLong(ToLongFunction) + */ + default long sumLong(final ToLongBiFunction function) { + return this.sumLong(this.unwrap(function)); + } + + default PairSeq swapped() { + return this.mapToPair(Tuple2::swap); + } + + /** + * @see Seq#take(long) + */ + default PairSeq take(final long maxSize) { + return seq(this.toSeq2().take(maxSize)); + } + + /** + * @deprecated Use {@link #takeWhile(BiPredicate)} + */ + @Override + @Deprecated + default Stream> takeWhile(final Predicate> predicate) { + return this.toSeq2().takeWhile(predicate); + } + + /** + * @see Seq#takeWhile(Predicate) + */ + default Stream> takeWhile(final BiPredicate predicate) { + return this.takeWhile(this.unwrap(predicate)); + } + + @Override + default Object[] toArray() { + return this.toSeq2().toArray(); + } + + @Override + default A[] toArray(final IntFunction generator) { + return this.toSeq2().toArray(generator); + } + + default Map toMap() { + return this.toSeq2().toMap(Tuple2::v1, Tuple2::v2); + } + + /** + * @deprecated Use {@link #toMap(BiFunction, BiFunction)} + */ + @Override + @Deprecated + default Map toMap(final Function, ? extends K2> keyMapper, + final Function, ? extends V2> valueMapper) { + return BaseSeq.super.toMap(keyMapper, valueMapper); + } + + /** + * @see Seq#toMap(Function, Function) + */ + default Map toMap(final BiFunction keyMapper, + final BiFunction valueMapper) { + return this.toMap(t -> t.map(keyMapper), t -> t.map(valueMapper)); + } + + /** + * @deprecated Use {@link #toMap(BiFunction)} + */ + @Override + @Deprecated + default Map> toMap(final Function, ? extends K2> keyMapper) { + return BaseSeq.super.toMap(keyMapper); + } + + /** + * @see Seq#toMap(Function) + */ + default Map> toMap(final BiFunction keyMapper) { + return this.toMap(t -> t.map(keyMapper)); + } + + /** + * @deprecated Only for internal use. If methods of {@link Seq2} are missing, implement them. + */ + @Deprecated + Seq2> toSeq2(); + + /** + * @see Seq#transform(Function) + */ + default U transform(final Function, ? extends U> transformer) { + return this.toSeq2().transform(s -> transformer.apply(seq(s))); + } + + @Override + default PairSeq unordered() { + return seq(this.toSeq2().unordered()); + } + + default Seq2 values() { + return this.toSeq2().map(Tuple2::v2); + } + + /** + * @see Seq#window() + */ + default Seq2>> window() { + return this.toSeq2().window(); + } + + /** + * @see Seq#window(long, long) + */ + default Seq2>> window(final long lower, final long upper) { + return this.toSeq2().window(lower, upper); + } + + /** + * @see Seq#window(Comparator) + */ + default Seq2>> window(final Comparator> orderBy) { + return this.toSeq2().window(orderBy); + } + + /** + * @see Seq#window(Comparator, long, long) + */ + default Seq2>> window(final Comparator> orderBy, final long lower, + final long upper) { + return this.toSeq2().window(orderBy, lower, upper); + } + + /** + * @see Seq#window(Function) + * @deprecated Use {@link #window(BiFunction)} + */ + @Deprecated + default Seq2>> window(final Function, ? extends U> partitionBy) { + return this.toSeq2().window(partitionBy); + } + + /** + * @see Seq#window(Function) + */ + default Seq2>> window(final BiFunction partitionBy) { + return this.window(this.unwrap(partitionBy)); + } + + /** + * @see Seq#window(Function, long, long) + * @deprecated Use {@link #window(BiFunction, long, long)} + */ + @Deprecated + default Seq2>> window(final Function, ? extends U> partitionBy, + final long lower, + final long upper) { + return this.toSeq2().window(partitionBy, lower, upper); + } + + /** + * @see Seq#window(Function, long, long) + */ + default Seq2>> window(final BiFunction partitionBy, + final long lower, + final long upper) { + return this.window(this.unwrap(partitionBy), lower, upper); + } + + /** + * @see Seq#window(Function, Comparator) + * @deprecated Use {@link #window(BiFunction, Comparator)} + */ + @Deprecated + default Seq2>> window(final Function, ? extends U> partitionBy, + final Comparator> orderBy) { + return this.toSeq2().window(partitionBy, orderBy); + } + + /** + * @see Seq#window(Function, Comparator) + */ + default Seq2>> window(final BiFunction partitionBy, + final Comparator> orderBy) { + return this.window(this.unwrap(partitionBy), orderBy); + } + + /** + * @see Seq#window(Function, Comparator, long, long) + * @deprecated Use {@link #window(BiFunction, Comparator, long, long)} + */ + @Deprecated + default Seq2>> window(final Function, ? extends U> partitionBy, + final Comparator> orderBy, final long lower, final long upper) { + return this.toSeq2().window(partitionBy, orderBy, lower, upper); + } + + /** + * @see Seq#window(Function, Comparator, long, long) + */ + default Seq2>> window(final BiFunction partitionBy, + final Comparator> orderBy, final long lower, final long upper) { + return this.window(this.unwrap(partitionBy), orderBy, lower, upper); + } + + private Consumer> unwrap(final BiConsumer action) { + return t -> action.accept(t.v1(), t.v2()); + } + + private BiFunction> toTuple( + final BiFunction keyMapper, + final BiFunction valueMapper) { + return (k, v) -> new Tuple2<>(keyMapper.apply(k, v), valueMapper.apply(k, v)); + } + + private Predicate> unwrap(final BiPredicate predicate) { + return t -> predicate.test(t.v1(), t.v2()); + } + + private Function, ? extends U> unwrap( + final BiFunction function) { + return t -> t.map(function); + } + + private ToIntFunction> unwrap(final ToIntBiFunction function) { + return t -> function.applyAsInt(t.v1(), t.v2()); + } + + private ToLongFunction> unwrap(final ToLongBiFunction function) { + return t -> function.applyAsLong(t.v1(), t.v2()); + } + + private ToDoubleFunction> unwrap(final ToDoubleBiFunction function) { + return t -> function.applyAsDouble(t.v1(), t.v2()); + } +} diff --git a/src/main/java/com/bakdata/util/seq2/PairSeqImpl.java b/src/main/java/com/bakdata/util/seq2/PairSeqImpl.java new file mode 100644 index 0000000..a44405e --- /dev/null +++ b/src/main/java/com/bakdata/util/seq2/PairSeqImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c), 2019 bakdata GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bakdata.util.seq2; + +import lombok.RequiredArgsConstructor; +import org.jooq.lambda.Seq; +import org.jooq.lambda.tuple.Tuple2; + +@RequiredArgsConstructor +class PairSeqImpl implements PairSeq { + + private final Seq2> wrapped; + + @Override + public Seq> toSeq() { + return toSeq2().toSeq(); + } + + @Override + public Seq2> toSeq2() { + return this.wrapped; + } +} diff --git a/src/main/java/com/bakdata/util/seq2/Seq2.java b/src/main/java/com/bakdata/util/seq2/Seq2.java new file mode 100644 index 0000000..d92b3f6 --- /dev/null +++ b/src/main/java/com/bakdata/util/seq2/Seq2.java @@ -0,0 +1,1309 @@ +/* + * Copyright (c), 2019 bakdata GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bakdata.util.seq2; + +import java.util.Comparator; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.Spliterator; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.BinaryOperator; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntFunction; +import java.util.function.ToLongFunction; +import java.util.stream.Collector; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.Stream; +import org.jooq.lambda.Seq; +import org.jooq.lambda.Window; +import org.jooq.lambda.tuple.Tuple2; + +@SuppressWarnings("deprecation") +public interface Seq2 extends Stream, Iterable, BaseSeq { + /** + * @see Seq#empty() + */ + static Seq2 empty() { + final Seq seq = Seq.empty(); + return seq(seq); + } + + /** + * @see Seq#generate(Supplier) + */ + static Seq2 generate(final Supplier s) { + final Seq seq = Seq.generate(s); + return seq(seq); + } + + /** + * @see Seq#generate(Object) + */ + static Seq2 generate(final T value) { + final Seq seq = Seq.generate(value); + return seq(seq); + } + + /** + * @see Seq#generate() + */ + static Seq2 generate() { + final Seq seq = Seq.generate(); + return seq(seq); + } + + /** + * @see Seq#of(Object[]) + */ + static Seq2 of(final T... values) { + final Seq seq = Seq.of(values); + return seq(seq); + } + + /** + * @see Seq#of(Object) + */ + static Seq2 of(final T value) { + final Seq seq = Seq.of(value); + return seq(seq); + } + + /** + * @see Seq#seq(Stream) + */ + static Seq2 seq(final Stream stream) { + final Seq seq = Seq.seq(stream); + return seq(seq); + } + + /** + * @see Seq#seq(Supplier) + */ + static Seq2 seq(final Supplier s) { + final Seq seq = Seq.seq(s); + return seq(seq); + } + + /** + * @see Seq#seq(Iterator) + */ + static Seq2 seq(final Iterator iterator) { + final Seq seq = Seq.seq(iterator); + return seq(seq); + } + + /** + * @see Seq#seq(Enumeration) + */ + static Seq2 seq(final Enumeration enumeration) { + final Seq seq = Seq.seq(enumeration); + return seq(seq); + } + + /** + * @see Seq#seq(Spliterator) + */ + static Seq2 seq(final Spliterator spliterator) { + final Seq seq = Seq.seq(spliterator); + return seq(seq); + } + + /** + * @see Seq#seq(Object[], int, int) + */ + static Seq2 seq(final T[] values, final int startIndex, final int endIndex) { + final Seq seq = Seq.seq(values, startIndex, endIndex); + return seq(seq); + } + + /** + * @see Seq#seq(Iterable) + */ + static Seq2 seq(final Iterable iterable) { + final Seq seq = Seq.seq(iterable); + return seq(seq); + } + + /** + * Wrap a {@code Stream} into a {@code Seq}. + */ + static Seq2 seq(final Seq2 seq2) { + return seq(seq2.toSeq()); + } + + /** + * Wrap a {@code Stream} into a {@code Seq}. + */ + static Seq2 seq(final Seq seq) { + return new Seq2Impl<>(seq); + } + + /** + * @see Seq#seq(Map) + */ + static Seq2> seq(final Map map) { + final Seq> seq = Seq.seq(map); + return seq(seq); + } + + @Override + default boolean allMatch(final Predicate predicate) { + return this.toSeq().allMatch(predicate); + } + + @Override + default boolean anyMatch(final Predicate predicate) { + return this.toSeq().anyMatch(predicate); + } + + /** + * @see Seq#append(Stream) + */ + default Seq2 append(final Stream other) { + return seq(this.toSeq().append(other)); + } + + /** + * @see Seq#append(Iterable) + */ + default Seq2 append(final Iterable other) { + return seq(this.toSeq().append(other)); + } + + /** + * @see Seq#append(Seq) + */ + default Seq2 append(final Seq2 other) { + return this.append(other.toSeq()); + } + + /** + * @see Seq#append(Seq) + */ + default Seq2 append(final Seq other) { + return seq(this.toSeq().append(other)); + } + + /** + * @see Seq#append(Object) + */ + default Seq2 append(final T other) { + return seq(this.toSeq().append(other)); + } + + /** + * @see Seq#append(Object[]) + */ + default Seq2 append(final T... other) { + return seq(this.toSeq().append(other)); + } + + /** + * @see Seq#append(Optional) + */ + default Seq2 append(final Optional other) { + return seq(this.toSeq().append(other)); + } + + /** + * @see Seq#cast(Class) + */ + default Seq2 cast(final Class type) { + return seq(this.toSeq().cast(type)); + } + + @Override + default void close() { + this.toSeq().close(); + } + + @Override + default R collect(final Supplier supplier, final BiConsumer accumulator, + final BiConsumer combiner) { + return this.toSeq().collect(supplier, accumulator, combiner); + } + + @Override + default R collect(final Collector collector) { + return this.toSeq().collect(collector); + } + + /** + * @see Seq#concat(Object) + */ + default Seq2 concat(final T other) { + return seq(this.toSeq().concat(other)); + } + + /** + * @see Seq#concat(Object[]) + */ + default Seq2 concat(final T... other) { + return seq(this.toSeq().concat(other)); + } + + /** + * @see Seq#concat(Iterable) + */ + default Seq2 concat(final Iterable other) { + return seq(this.toSeq().concat(other)); + } + + /** + * @see Seq#concat(Stream) + */ + default Seq2 concat(final Stream other) { + return seq(this.toSeq().concat(other)); + } + + /** + * @see Seq#concat(Seq) + */ + default Seq2 concat(final Seq other) { + return seq(this.toSeq().concat(other)); + } + + /** + * @see Seq#concat(Seq) + */ + default Seq2 concat(final Seq2 other) { + return this.concat(other.toSeq()); + } + + /** + * @see Seq#concat(Optional) + */ + default Seq2 concat(final Optional other) { + return seq(this.toSeq().concat(other)); + } + + @Override + default long count() { + return this.toSeq().count(); + } + + /** + * @see Seq#crossApply(Function) + */ + default PairSeq crossApply(final Function> function) { + return PairSeq.seq(this.toSeq().crossApply(function)); + } + + /** + * @see Seq#crossJoin(Iterable) + */ + default PairSeq crossJoin(final Iterable other) { + return PairSeq.seq(this.toSeq().crossJoin(other)); + } + + /** + * @see Seq#crossJoin(Stream) + */ + default PairSeq crossJoin(final Stream other) { + return PairSeq.seq(this.toSeq().crossJoin(other)); + } + + /** + * @see Seq#crossJoin(Seq) + */ + default PairSeq crossJoin(final Seq other) { + return PairSeq.seq(this.toSeq().crossJoin(other)); + } + + /** + * @see Seq#crossJoin(Seq) + */ + default PairSeq crossJoin(final Seq2 other) { + return this.crossJoin(other.toSeq()); + } + + /** + * @see Seq#crossSelfJoin() + */ + default PairSeq crossSelfJoin() { + return PairSeq.seq(this.toSeq().crossSelfJoin()); + } + + /** + * @see Seq#cycle() + */ + default Seq2 cycle() { + return seq(this.toSeq().cycle()); + } + + /** + * @see Seq#cycle(long) + */ + default Seq2 cycle(final long times) { + return seq(this.toSeq().cycle(times)); + } + + /** + * @see Seq#distinct(Function) + */ + default Seq2 distinct(final Function keyExtractor) { + return seq(this.toSeq().distinct(keyExtractor)); + } + + @Override + default Seq2 distinct() { + return seq(this.toSeq().distinct()); + } + + /** + * @see Seq#drop(long) + */ + default Seq2 drop(final long n) { + return seq(this.toSeq().drop(n)); + } + + @Override + default Seq2 dropWhile(final Predicate predicate) { + return seq(this.toSeq().dropWhile(predicate)); + } + + /** + * @see Seq#duplicate() + */ + default Tuple2, Seq2> duplicate() { + return this.toSeq().duplicate().map1(Seq2::seq).map2(Seq2::seq); + } + + @Override + default Seq2 filter(final Predicate predicate) { + return seq(this.toSeq().filter(predicate)); + } + + /** + * Same as {@link Seq2#filter(Predicate)} but with negated predicate. + * + * @see Seq#map(Function) + */ + default Seq2 filterNot(final Predicate predicate) { + return seq(this.filter(predicate.negate())); + } + + @Override + default Optional findAny() { + return this.toSeq().findAny(); + } + + @Override + default Optional findFirst() { + return this.toSeq().findFirst(); + } + + @Override + default Seq2 flatMap(final Function> mapper) { + return seq(this.toSeq().flatMap(mapper)); + } + + @Override + default DoubleStream flatMapToDouble(final Function mapper) { + return this.toSeq().flatMapToDouble(mapper); + } + + @Override + default IntStream flatMapToInt(final Function mapper) { + return this.toSeq().flatMapToInt(mapper); + } + + /** + * Flat map this stream. Instead of returning a stream, the passed function can return an {@code Iterable}. + * + * @see Seq#flatMap(Function) + */ + default Seq2 flatMapToIterable(final Function> mapper) { + return seq(this.toSeq().flatMap(t -> seq(mapper.apply(t)))); + } + + @Override + default LongStream flatMapToLong(final Function mapper) { + return this.toSeq().flatMapToLong(mapper); + } + + /** + * Flat map a {@code Seq2} to a {@code PairSeq} + */ + default PairSeq flatMapToPair( + final Function>> mapper) { + final Seq2> seq = this.flatMap(mapper); + return PairSeq.seq(seq); + } + + @Override + default void forEach(final Consumer action) { + this.toSeq().forEach(action); + } + + @Override + default void forEachOrdered(final Consumer action) { + this.toSeq().forEachOrdered(action); + } + + /** + * @see Seq#grouped(Function) + */ + default PairSeq> grouped(final Function classifier) { + final Seq>> seq = this.toSeq().grouped(classifier); + final PairSeq> pairSeq = PairSeq.seq(seq); + return pairSeq.mapValues(Seq2::seq); + } + + /** + * @see Seq#grouped(Function, Collector) + */ + default PairSeq grouped(final Function classifier, + final Collector downstream) { + return PairSeq.seq(this.toSeq().grouped(classifier, downstream)); + } + + /** + * @see Seq#innerJoin(Stream, BiPredicate) + */ + default PairSeq innerJoin(final Stream other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().innerJoin(other, predicate)); + } + + /** + * @see Seq#innerJoin(Iterable, BiPredicate) + */ + default PairSeq innerJoin(final Iterable other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().innerJoin(other, predicate)); + } + + /** + * @see Seq#innerJoin(Seq, BiPredicate) + */ + default PairSeq innerJoin(final Seq other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().innerJoin(other, predicate)); + } + + /** + * @see Seq#innerJoin(Seq, BiPredicate) + */ + default PairSeq innerJoin(final Seq2 other, + final BiPredicate predicate) { + return this.innerJoin(other.toSeq(), predicate); + } + + /** + * @see Seq#innerSelfJoin(BiPredicate) + */ + default PairSeq innerSelfJoin(final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().innerSelfJoin(predicate)); + } + + /** + * @see Seq#intersperse(Object) + */ + default Seq2 intersperse(final T value) { + return seq(this.toSeq().intersperse(value)); + } + + @Override + default boolean isParallel() { + return this.toSeq().isParallel(); + } + + @Override + default Iterator iterator() { + return this.toSeq().iterator(); + } + + /** + * @see Seq#leftOuterJoin(Stream, BiPredicate) + */ + default PairSeq leftOuterJoin(final Stream other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().leftOuterJoin(other, predicate)); + } + + /** + * @see Seq#leftOuterJoin(Iterable, BiPredicate) + */ + default PairSeq leftOuterJoin(final Iterable other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().leftOuterJoin(other, predicate)); + } + + /** + * @see Seq#leftOuterJoin(Seq, BiPredicate) + */ + default PairSeq leftOuterJoin(final Seq other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().leftOuterJoin(other, predicate)); + } + + /** + * @see Seq#leftOuterJoin(Seq, BiPredicate) + */ + default PairSeq leftOuterJoin(final Seq2 other, + final BiPredicate predicate) { + return this.leftOuterJoin(other.toSeq(), predicate); + } + + /** + * @see Seq#leftOuterSelfJoin(BiPredicate) + */ + default PairSeq leftOuterSelfJoin(final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().leftOuterSelfJoin(predicate)); + } + + @Override + default Seq2 limit(final long maxSize) { + return seq(this.toSeq().limit(maxSize)); + } + + /** + * @see Seq#limitUntil(Predicate) + */ + default Seq2 limitUntil(final Predicate predicate) { + return seq(this.toSeq().limitUntil(predicate)); + } + + /** + * @see Seq#limitUntilClosed(Predicate) + */ + default Seq2 limitUntilClosed(final Predicate predicate) { + return seq(this.toSeq().limitUntilClosed(predicate)); + } + + /** + * @see Seq#limitWhile(Predicate) + */ + default Seq2 limitWhile(final Predicate predicate) { + return seq(this.toSeq().limitWhile(predicate)); + } + + /** + * @see Seq#limitWhileClosed(Predicate) + */ + default Seq2 limitWhileClosed(final Predicate predicate) { + return seq(this.toSeq().limitWhileClosed(predicate)); + } + + @Override + default Seq2 map(final Function function) { + return seq(this.toSeq().map(function)); + } + + @Override + default DoubleStream mapToDouble(final ToDoubleFunction mapper) { + return this.toSeq().mapToDouble(mapper); + } + + @Override + default IntStream mapToInt(final ToIntFunction function) { + return this.toSeq().mapToInt(function); + } + + @Override + default LongStream mapToLong(final ToLongFunction mapper) { + return this.toSeq().mapToLong(mapper); + } + + /** + * Map a {@code Seq2} to a {@code PairSeq} + * + * @see Seq#map(Function) + */ + default PairSeq mapToPair(final Function> mapper) { + final Seq> seq = this.toSeq().map(mapper); + return PairSeq.seq(seq); + } + + /** + * Map a {@code Seq2} to a {@code PairSeq} + * + * @param keyMapper function to extract key from input + * @param valueMapper function to extract value from input + * @see Seq#map(Function) + */ + default PairSeq mapToPair(final Function keyMapper, + final Function valueMapper) { + return this.mapToPair(this.toTuple(keyMapper, valueMapper)); + } + + @Override + default Optional max(final Comparator comparator) { + return this.toSeq().max(comparator); + } + + /** + * @see Seq#maxAll() + */ + default Seq2 maxAll() { + return seq(this.toSeq().maxAll()); + } + + /** + * @see Seq#maxAll(Comparator) + */ + default Seq2 maxAll(final Comparator comparator) { + return seq(this.toSeq().maxAll(comparator)); + } + + /** + * @see Seq#maxAll(Function) + */ + default > Seq2 maxAll(final Function function) { + return seq(this.toSeq().maxAll(function)); + } + + /** + * @see Seq#maxAll(Function, Comparator) + */ + default Seq2 maxAll(final Function function, + final Comparator comparator) { + return seq(this.toSeq().maxAll(function, comparator)); + } + + /** + * @see Seq#maxAllBy(Function) + */ + default > Seq2 maxAllBy(final Function function) { + return seq(this.toSeq().maxAllBy(function)); + } + + /** + * @see Seq#maxAllBy(Function, Comparator) + */ + default Seq2 maxAllBy(final Function function, + final Comparator comparator) { + return seq(this.toSeq().maxAllBy(function, comparator)); + } + + @Override + default Optional min(final Comparator comparator) { + return this.toSeq().min(comparator); + } + + /** + * @see Seq#minAll() + */ + default Seq2 minAll() { + return seq(this.toSeq().minAll()); + } + + /** + * @see Seq#minAll(Comparator) + */ + default Seq2 minAll(final Comparator comparator) { + return seq(this.toSeq().minAll(comparator)); + } + + /** + * @see Seq#minAll(Function) + */ + default > Seq2 minAll(final Function function) { + return seq(this.toSeq().minAll(function)); + } + + /** + * @see Seq#minAll(Function, Comparator) + */ + default Seq2 minAll(final Function function, + final Comparator comparator) { + return seq(this.toSeq().minAll(function, comparator)); + } + + /** + * @see Seq#minAllBy(Function) + */ + default > Seq2 minAllBy(final Function function) { + return seq(this.toSeq().minAllBy(function)); + } + + /** + * @see Seq#minAllBy(Function, Comparator) + */ + default Seq2 minAllBy(final Function function, + final Comparator comparator) { + return seq(this.toSeq().minAllBy(function, comparator)); + } + + /** + * @see Seq#modeAll() + */ + default Seq2 modeAll() { + return seq(this.toSeq().modeAll()); + } + + /** + * @see Seq#modeAllBy(Function) + */ + default Seq2 modeAllBy(final Function function) { + return seq(this.toSeq().modeAllBy(function)); + } + + @Override + default boolean noneMatch(final Predicate predicate) { + return this.toSeq().noneMatch(predicate); + } + + /** + * @see Seq#ofType(Class) + */ + default Seq2 ofType(final Class type) { + return seq(this.toSeq().ofType(type)); + } + + @Override + default Seq2 onClose(final Runnable closeHandler) { + return seq(this.toSeq().onClose(closeHandler)); + } + + /** + * @see Seq#onEmpty(Object) + */ + default Seq2 onEmpty(final T value) { + return seq(this.toSeq().onEmpty(value)); + } + + /** + * @see Seq#onEmptyGet(Supplier) + */ + default Seq2 onEmptyGet(final Supplier supplier) { + return seq(this.toSeq().onEmptyGet(supplier)); + } + + /** + * @see Seq#onEmptyThrow(Supplier) + */ + default Seq2 onEmptyThrow(final Supplier supplier) { + return seq(this.toSeq().onEmptyThrow(supplier)); + } + + /** + * @see Seq#outerApply(Function) + */ + default PairSeq outerApply(final Function> function) { + return PairSeq.seq(this.toSeq().outerApply(function)); + } + + @Override + default Seq2 parallel() { + return seq(this.toSeq().parallel()); + } + + /** + * @see Seq#partition(Predicate) + */ + default Tuple2, Seq2> partition(final Predicate predicate) { + return this.toSeq().partition(predicate).map1(Seq2::seq).map2(Seq2::seq); + } + + @Override + default Seq2 peek(final Consumer action) { + return seq(this.toSeq().peek(action)); + } + + /** + * @see Seq#prepend(Object) + */ + default Seq2 prepend(final T other) { + return seq(this.toSeq().prepend(other)); + } + + /** + * @see Seq#prepend(Object[]) + */ + default Seq2 prepend(final T... other) { + return seq(this.toSeq().prepend(other)); + } + + /** + * @see Seq#prepend(Iterable) + */ + default Seq2 prepend(final Iterable other) { + return seq(this.toSeq().prepend(other)); + } + + /** + * @see Seq#prepend(Stream) + */ + default Seq2 prepend(final Stream other) { + return seq(this.toSeq().prepend(other)); + } + + /** + * @see Seq#prepend(Seq) + */ + default Seq2 prepend(final Seq other) { + return seq(this.toSeq().prepend(other)); + } + + /** + * @see Seq#prepend(Seq) + */ + default Seq2 prepend(final Seq2 other) { + return this.prepend(other.toSeq()); + } + + /** + * @see Seq#prepend(Optional) + */ + default Seq2 prepend(final Optional other) { + return seq(this.toSeq().prepend(other)); + } + + @Override + default T reduce(final T identity, final BinaryOperator accumulator) { + return this.toSeq().reduce(identity, accumulator); + } + + @Override + default Optional reduce(final BinaryOperator accumulator) { + return this.toSeq().reduce(accumulator); + } + + @Override + default U reduce(final U identity, final BiFunction accumulator, + final BinaryOperator combiner) { + return this.toSeq().reduce(identity, accumulator, combiner); + } + + /** + * @see Seq#remove(Object) + */ + default Seq2 remove(final T other) { + return seq(this.toSeq().remove(other)); + } + + /** + * @see Seq#removeAll(Object[]) + */ + default Seq2 removeAll(final T... other) { + return seq(this.toSeq().removeAll(other)); + } + + /** + * @see Seq#removeAll(Stream) + */ + default Seq2 removeAll(final Stream other) { + return seq(this.toSeq().removeAll(other)); + } + + /** + * @see Seq#removeAll(Iterable) + */ + default Seq2 removeAll(final Iterable other) { + return seq(this.toSeq().removeAll(other)); + } + + /** + * @see Seq#removeAll(Seq) + */ + default Seq2 removeAll(final Seq other) { + return seq(this.toSeq().removeAll(other)); + } + + /** + * @see Seq#removeAll(Seq) + */ + default Seq2 removeAll(final Seq2 other) { + return this.removeAll(other.toSeq()); + } + + /** + * @see Seq#retainAll(Object[]) + */ + default Seq2 retainAll(final T... other) { + return seq(this.toSeq().retainAll(other)); + } + + /** + * @see Seq#retainAll(Stream) + */ + default Seq2 retainAll(final Stream other) { + return seq(this.toSeq().retainAll(other)); + } + + /** + * @see Seq#retainAll(Iterable) + */ + default Seq2 retainAll(final Iterable other) { + return seq(this.toSeq().retainAll(other)); + } + + /** + * @see Seq#retainAll(Seq) + */ + default Seq2 retainAll(final Seq other) { + return seq(this.toSeq().retainAll(other)); + } + + /** + * @see Seq#retainAll(Seq) + */ + default Seq2 retainAll(final Seq2 other) { + return this.retainAll(other.toSeq()); + } + + /** + * @see Seq#reverse() + */ + default Seq2 reverse() { + return seq(this.toSeq().reverse()); + } + + /** + * @see Seq#rightOuterJoin(Stream, BiPredicate) + */ + default PairSeq rightOuterJoin(final Stream other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().rightOuterJoin(other, predicate)); + } + + /** + * @see Seq#rightOuterJoin(Iterable, BiPredicate) + */ + default PairSeq rightOuterJoin(final Iterable other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().rightOuterJoin(other, predicate)); + } + + /** + * @see Seq#rightOuterJoin(Seq, BiPredicate) + */ + default PairSeq rightOuterJoin(final Seq other, + final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().rightOuterJoin(other, predicate)); + } + + /** + * @see Seq#rightOuterJoin(Seq, BiPredicate) + */ + default PairSeq rightOuterJoin(final Seq2 other, + final BiPredicate predicate) { + return this.rightOuterJoin(other.toSeq(), predicate); + } + + /** + * @see Seq#rightOuterSelfJoin(BiPredicate) + */ + default PairSeq rightOuterSelfJoin(final BiPredicate predicate) { + return PairSeq.seq(this.toSeq().rightOuterSelfJoin(predicate)); + } + + /** + * @see Seq#scanLeft(Object, BiFunction) + */ + default Seq2 scanLeft(final U seed, final BiFunction function) { + return seq(this.toSeq().scanLeft(seed, function)); + } + + /** + * @see Seq#scanRight(Object, BiFunction) + */ + default Seq2 scanRight(final U seed, final BiFunction function) { + return seq(this.toSeq().scanRight(seed, function)); + } + + @Override + default Seq2 sequential() { + return seq(this.toSeq().sequential()); + } + + /** + * @see Seq#shuffle() + */ + default Seq2 shuffle() { + return seq(this.toSeq().shuffle()); + } + + /** + * @see Seq#shuffle(Random) + */ + default Seq2 shuffle(final Random random) { + return seq(this.toSeq().shuffle(random)); + } + + @Override + default Seq2 skip(final long n) { + return seq(this.toSeq().skip(n)); + } + + /** + * @see Seq#skipUntil(Predicate) + */ + default Seq2 skipUntil(final Predicate predicate) { + return seq(this.toSeq().skipUntil(predicate)); + } + + /** + * @see Seq#skipUntilClosed(Predicate) + */ + default Seq2 skipUntilClosed(final Predicate predicate) { + return seq(this.toSeq().skipUntilClosed(predicate)); + } + + /** + * @see Seq#skipWhile(Predicate) + */ + default Seq2 skipWhile(final Predicate predicate) { + return seq(this.toSeq().skipWhile(predicate)); + } + + /** + * @see Seq#skipWhileClosed(Predicate) + */ + default Seq2 skipWhileClosed(final Predicate predicate) { + return seq(this.toSeq().skipWhileClosed(predicate)); + } + + /** + * @see Seq#slice(long, long) + */ + default Seq2 slice(final long from, final long to) { + return seq(this.toSeq().slice(from, to)); + } + + /** + * @see Seq#sliding(long) + */ + default Seq2> sliding(final long size) { + return seq(this.toSeq().sliding(size)).map(Seq2::seq); + } + + @Override + default Seq2 sorted() { + return seq(this.toSeq().sorted()); + } + + @Override + default Seq2 sorted(final Comparator comparator) { + return seq(this.toSeq().sorted(comparator)); + } + + /** + * @see Seq#sorted(Function) + */ + default > Seq2 sorted(final Function function) { + return seq(this.toSeq().sorted(function)); + } + + /** + * @see Seq#sorted(Function, Comparator) + */ + default Seq2 sorted(final Function function, + final Comparator comparator) { + return seq(this.toSeq().sorted(function, comparator)); + } + + /** + * @see Seq#splitAt(long) + */ + default Tuple2, Seq2> splitAt(final long position) { + return this.toSeq().splitAt(position).map1(Seq2::seq).map2(Seq2::seq); + } + + /** + * @see Seq#splitAtHead() + */ + default Tuple2, Seq2> splitAtHead() { + return this.toSeq().splitAtHead().map2(Seq2::seq); + } + + @Override + default Spliterator spliterator() { + return this.toSeq().spliterator(); + } + + /** + * @see Seq#take(long) + */ + default Seq2 take(final long maxSize) { + return seq(this.toSeq().take(maxSize)); + } + + @Override + default Stream takeWhile(final Predicate predicate) { + return this.toSeq().takeWhile(predicate); + } + + @Override + default Object[] toArray() { + return this.toSeq().toArray(); + } + + @Override + default A[] toArray(final IntFunction generator) { + return this.toSeq().toArray(generator); + } + + /** + * @see Seq#transform(Function) + */ + default U transform(final Function, ? extends U> transformer) { + return this.toSeq().transform(transformer); + } + + @Override + default Seq2 unordered() { + return seq(this.toSeq().unordered()); + } + + /** + * @see Seq#window() + */ + default Seq2> window() { + return seq(this.toSeq().window()); + } + + /** + * @see Seq#window(long, long) + */ + default Seq2> window(final long lower, final long upper) { + return seq(this.toSeq().window(lower, upper)); + } + + /** + * @see Seq#window(Comparator) + */ + default Seq2> window(final Comparator orderBy) { + return seq(this.toSeq().window(orderBy)); + } + + /** + * @see Seq#window(Comparator, long, long) + */ + default Seq2> window(final Comparator orderBy, final long lower, final long upper) { + return seq(this.toSeq().window(orderBy, lower, upper)); + } + + /** + * @see Seq#window(Function) + */ + default Seq2> window(final Function partitionBy) { + return seq(this.toSeq().window(partitionBy)); + } + + /** + * @see Seq#window(Function, long, long) + */ + default Seq2> window(final Function partitionBy, final long lower, + final long upper) { + return seq(this.toSeq().window(partitionBy, lower, upper)); + } + + /** + * @see Seq#window(Function, Comparator) + */ + default Seq2> window(final Function partitionBy, + final Comparator orderBy) { + return seq(this.toSeq().window(partitionBy, orderBy)); + } + + /** + * @see Seq#window(Function, Comparator, long, long) + */ + default Seq2> window(final Function partitionBy, + final Comparator orderBy, + final long lower, final long upper) { + return seq(this.toSeq().window(partitionBy, orderBy, lower, upper)); + } + + /** + * @see Seq#zip(Stream, BiFunction) + */ + default Seq2 zip(final Stream other, + final BiFunction zipper) { + return seq(this.toSeq().zip(other, zipper)); + } + + /** + * @see Seq#zip(Iterable, BiFunction) + */ + default Seq2 zip(final Iterable other, + final BiFunction zipper) { + return seq(this.toSeq().zip(other, zipper)); + } + + /** + * @see Seq#zip(Seq, BiFunction) + */ + default Seq2 zip(final Seq other, + final BiFunction zipper) { + return seq(this.toSeq().zip(other, zipper)); + } + + /** + * @see Seq#zip(Seq, BiFunction) + */ + default Seq2 zip(final Seq2 other, + final BiFunction zipper) { + return this.zip(other.toSeq(), zipper); + } + + /** + * @see Seq#zip(Stream) + */ + default PairSeq zip(final Stream other) { + return PairSeq.seq(this.toSeq().zip(other)); + } + + /** + * @see Seq#zip(Iterable) + */ + default PairSeq zip(final Iterable other) { + return PairSeq.seq(this.toSeq().zip(other)); + } + + /** + * @see Seq#zip(Seq) + */ + default PairSeq zip(final Seq other) { + return PairSeq.seq(this.toSeq().zip(other)); + } + + /** + * @see Seq#zip(Seq) + */ + default PairSeq zip(final Seq2 other) { + return this.zip(other.toSeq()); + } + + default PairSeq zipWithIndex() { + return PairSeq.seq(this.toSeq().zipWithIndex()); + } + + /** + * @see Seq#zipWithIndex() + */ + default Seq2 zipWithIndex(final BiFunction zipper) { + return seq(this.toSeq().zipWithIndex(zipper)); + } + + private Function> toTuple(final Function keyMapper, + final Function valueMapper) { + return t -> new Tuple2<>(keyMapper.apply(t), valueMapper.apply(t)); + } +} diff --git a/src/main/java/com/bakdata/util/seq2/Seq2Impl.java b/src/main/java/com/bakdata/util/seq2/Seq2Impl.java new file mode 100644 index 0000000..a7e3893 --- /dev/null +++ b/src/main/java/com/bakdata/util/seq2/Seq2Impl.java @@ -0,0 +1,27 @@ +/* + * Copyright (c), 2019 bakdata GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bakdata.util.seq2; + +import lombok.RequiredArgsConstructor; +import org.jooq.lambda.Seq; + +@RequiredArgsConstructor +class Seq2Impl implements Seq2 { + private final Seq wrapped; + + @Override + public Seq toSeq() { + return this.wrapped; + } +} diff --git a/src/test/java/com/bakdata/util/seq2/PairSeqTest.java b/src/test/java/com/bakdata/util/seq2/PairSeqTest.java new file mode 100644 index 0000000..e80c69d --- /dev/null +++ b/src/test/java/com/bakdata/util/seq2/PairSeqTest.java @@ -0,0 +1,246 @@ +/* + * Copyright (c), 2019 bakdata GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bakdata.util.seq2; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import java.util.Map; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.Stream; +import org.jooq.lambda.Seq; +import org.jooq.lambda.tuple.Tuple2; +import org.junit.jupiter.api.Test; + +class PairSeqTest { + + @Test + void shouldConstructFromMap() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b"))) + .hasSize(2) + .containsExactlyInAnyOrder(new Tuple2<>(1, "a"), new Tuple2<>(2, "b")); + } + + @Test + void shouldCollectToMap() { + assertThat(PairSeq.seq(Map.of(1, "a", 2, "b")).toMap()) + .hasSize(2) + .containsEntry(1, "a") + .containsEntry(2, "b"); + } + + @Test + void shouldMap() { + assertThat((Stream) PairSeq.seq(Map.of(1, "a", 2, "b")).map((k, v) -> k + v)) + .hasSize(2) + .containsExactlyInAnyOrder("1a", "2b"); + } + + @Test + void shouldMapToLong() { + assertThat(PairSeq.seq(Map.of(1, "a", 2, "b")).mapToLong((k, v) -> k)) + .hasSize(2) + .containsExactlyInAnyOrder(1L, 2L); + } + + @Test + void shouldMapToInt() { + assertThat(PairSeq.seq(Map.of(1, "a", 2, "b")).mapToInt((k, v) -> k)) + .hasSize(2) + .containsExactlyInAnyOrder(1, 2); + } + + @Test + void shouldMapToDouble() { + assertThat(PairSeq.seq(Map.of(1, "a", 2, "b")).mapToDouble((k, v) -> k)) + .hasSize(2) + .containsExactlyInAnyOrder(1.0, 2.0); + } + + @Test + void shouldFlatMap() { + assertThat((Stream) PairSeq.seq(Map.of(1, "ab", 2, "bc")) + .flatMap((k, v) -> v.chars().mapToObj(i -> k + String.valueOf((char) i)))) + .hasSize(4) + .containsExactlyInAnyOrder("1a", "1b", "2b", "2c"); + } + + @Test + void shouldFlatMapToLong() { + assertThat(PairSeq.seq(Map.of(1, "ab", 2, "bc")) + .flatMapToLong((k, v) -> LongStream.range(0, k))) + .hasSize(3) + .containsExactlyInAnyOrder(0L, 0L, 1L); + } + + @Test + void shouldFlatMapToInt() { + assertThat(PairSeq.seq(Map.of(1, "ab", 2, "bc")) + .flatMapToInt((k, v) -> IntStream.range(0, k))) + .hasSize(3) + .containsExactlyInAnyOrder(0, 0, 1); + } + + @Test + void shouldFlatMapToDouble() { + assertThat(PairSeq.seq(Map.of(1, "ab", 2, "bc")) + .flatMapToDouble((k, v) -> DoubleStream.of(k))) + .hasSize(2) + .containsExactlyInAnyOrder(1.0, 2.0); + } + + @Test + void shouldFlatMapValues() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "ab", 2, "bc")) + .flatMapValues(v -> v.chars().mapToObj(i -> (char) i))) + .hasSize(4) + .containsExactlyInAnyOrder(new Tuple2<>(1, 'a'), new Tuple2<>(1, 'b'), new Tuple2<>(2, 'b'), + new Tuple2<>(2, 'c')); + } + + @Test + void shouldFlatMapKeysToPair() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")) + .flatMapKeysToPair(k -> PairSeq.seq(Map.of(k, k, k + 1, k + 1)))) + .hasSize(4) + .containsExactlyInAnyOrder(new Tuple2<>(1, 1), new Tuple2<>(2, 2), + new Tuple2<>(2, 2), new Tuple2<>(3, 3)); + } + + @Test + void shouldFlatMapValuesToPair() { + assertThat((Stream>) PairSeq.seq(Map.of(1, Map.of(3, "a"), 2, Map.of(4, "b", 5, "c"))) + .flatMapValuesToPair(PairSeq::seq)) + .hasSize(3) + .containsExactlyInAnyOrder(new Tuple2<>(3, "a"), new Tuple2<>(4, "b"), new Tuple2<>(5, "c")); + } + + @Test + void shouldFlatMapKeys() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")) + .flatMapKeys(k -> IntStream.range(0, k).boxed())) + .hasSize(3) + .containsExactlyInAnyOrder(new Tuple2<>(0, "a"), new Tuple2<>(0, "b"), new Tuple2<>(1, "b")); + } + + @Test + void shouldMapValues() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")).mapValues(v -> v + v)) + .hasSize(2) + .containsExactlyInAnyOrder(new Tuple2<>(1, "aa"), new Tuple2<>(2, "bb")); + } + + @Test + void shouldMapKeys() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")).mapKeys(v -> v + 1)) + .hasSize(2) + .containsExactlyInAnyOrder(new Tuple2<>(2, "a"), new Tuple2<>(3, "b")); + } + + @Test + void shouldReturnValues() { + assertThat((Stream) PairSeq.seq(Map.of(1, "a", 2, "b")).values()) + .hasSize(2) + .containsExactlyInAnyOrder("a", "b"); + } + + @Test + void shouldReturnKeys() { + assertThat((Stream) PairSeq.seq(Map.of(1, "a", 2, "b")).keys()) + .hasSize(2) + .containsExactlyInAnyOrder(1, 2); + } + + @Test + void shouldGroupByKey() { + assertThat((Stream>>) PairSeq + .seq(Seq.of(new Tuple2<>(1, "a"), new Tuple2<>(1, "b"), new Tuple2<>(2, "c"))) + .groupByKey() + .mapValues(Seq2::toList)) + .hasSize(2) + .anySatisfy(t -> { + assertThat(t.v1()).isEqualTo(1); + assertThat(t.v2()) + .hasSize(2) + .containsExactlyInAnyOrder("a", "b"); + }) + .anySatisfy(t -> { + assertThat(t.v1()).isEqualTo(2); + assertThat(t.v2()) + .hasSize(1) + .containsExactlyInAnyOrder("c"); + }); + } + + @Test + void shouldFilter() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")) + .filter((k, v) -> k > 1)) + .hasSize(1) + .containsExactlyInAnyOrder(new Tuple2<>(2, "b")); + } + + @Test + void shouldFilterNot() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")) + .filterNot((k, v) -> k > 1)) + .hasSize(1) + .containsExactlyInAnyOrder(new Tuple2<>(1, "a")); + } + + @Test + void shouldFilterKeys() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")) + .filterKeys(k -> k > 1)) + .hasSize(1) + .containsExactlyInAnyOrder(new Tuple2<>(2, "b")); + } + + @Test + void shouldFilterKeysNot() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")) + .filterKeysNot(k -> k > 1)) + .hasSize(1) + .containsExactlyInAnyOrder(new Tuple2<>(1, "a")); + } + + @Test + void shouldFilterValues() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")) + .filterValues("a"::equals)) + .hasSize(1) + .containsExactlyInAnyOrder(new Tuple2<>(1, "a")); + } + + @Test + void shouldFilterValuesNot() { + assertThat((Stream>) PairSeq.seq(Map.of(1, "a", 2, "b")) + .filterValuesNot("a"::equals)) + .hasSize(1) + .containsExactlyInAnyOrder(new Tuple2<>(2, "b")); + } + + @Test + void shouldGroupBy() { + final Map>> actual = PairSeq.seq(Map.of(1, "a", 2, "a")) + .groupBy(Tuple2::v2); + assertThat(actual) + .hasSize(1) + .hasEntrySatisfying("a", value -> assertThat(value) + .containsExactlyInAnyOrder(new Tuple2<>(1, "a"), new Tuple2<>(2, "a"))); + } + +} \ No newline at end of file diff --git a/src/test/java/com/bakdata/util/seq2/Seq2Test.java b/src/test/java/com/bakdata/util/seq2/Seq2Test.java new file mode 100644 index 0000000..018f08b --- /dev/null +++ b/src/test/java/com/bakdata/util/seq2/Seq2Test.java @@ -0,0 +1,31 @@ +/* + * Copyright (c), 2019 bakdata GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bakdata.util.seq2; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; + +class Seq2Test { + + @Test + void shouldFlatMapToIterable() { + assertThat((Stream) Seq2.of(1, 2).flatMapToIterable(List::of)) + .hasSize(2) + .containsExactlyInAnyOrder(1, 2); + } + +} \ No newline at end of file