├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .travis.yml ├── pom.xml ├── mvnw.cmd ├── LICENSE.txt ├── mvnw ├── src ├── test │ └── java │ │ └── snippets │ │ └── SnippetsTests.java └── main │ └── java │ └── snippets │ └── Snippets.java └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .settings/ 2 | .idea/ 3 | *.iml 4 | .classpath 5 | .project 6 | build/ 7 | target/ 8 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shekhargulati/30-seconds-of-java/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | install: ./mvnw install -DskipTests=true -Dmaven.javadoc.skip=true -B -V 3 | script: ./mvnw test -B 4 | jdk: 5 | - oraclejdk8 6 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.shekhargulati 8 | little-java-functions 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 1.8 13 | 1.8 14 | 4.12 15 | 3.8.0 16 | 17 | 18 | 19 | 20 | junit 21 | junit 22 | ${junit.version} 23 | test 24 | 25 | 26 | org.assertj 27 | assertj-core 28 | ${assertj.version} 29 | test 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-surefire-plugin 38 | 2.20 39 | 40 | 41 | **/Test*.java 42 | **/*Test.java 43 | **/*Tests.java 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /src/test/java/snippets/SnippetsTests.java: -------------------------------------------------------------------------------- 1 | package snippets; 2 | 3 | import java.util.AbstractMap.SimpleEntry; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.OptionalInt; 10 | import java.util.stream.IntStream; 11 | 12 | import org.junit.Test; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | 16 | public class SnippetsTests { 17 | 18 | @Test 19 | public void gcd_of_array_containing_1_to_5_is_1() throws Exception { 20 | OptionalInt gcd = Snippets.gcd(new int[]{1, 2, 3, 4, 5}); 21 | assertThat(gcd).isNotEmpty(); 22 | assertThat(gcd).hasValue(1); 23 | } 24 | 25 | @Test 26 | public void gcd_of_array_containing_4_8_and_12_is_4() throws Exception { 27 | OptionalInt gcd = Snippets.gcd(new int[]{4, 8, 12}); 28 | assertThat(gcd).isNotEmpty(); 29 | assertThat(gcd).hasValue(4); 30 | } 31 | 32 | @Test 33 | public void lcm_of_array_containing_1_to_5_is_60() throws Exception { 34 | OptionalInt lcm = Snippets.lcm(new int[]{1, 2, 3, 4, 5}); 35 | assertThat(lcm).isNotEmpty(); 36 | assertThat(lcm).hasValue(60); 37 | } 38 | 39 | @Test 40 | public void lcm_of_array_containing_4_8_and_12_is_24() throws Exception { 41 | OptionalInt lcm = Snippets.lcm(new int[]{4, 8, 12}); 42 | assertThat(lcm).isNotEmpty(); 43 | assertThat(lcm).hasValue(24); 44 | } 45 | 46 | @Test 47 | public void max_of_array_containing_10_1_and_5_is_10() throws Exception { 48 | OptionalInt max = Snippets.arrayMax(new int[]{10, 1, 5}); 49 | assertThat(max).hasValue(10); 50 | } 51 | 52 | @Test 53 | public void min_of_array_containing_10_1_and_5_is_10() throws Exception { 54 | OptionalInt min = Snippets.arrayMin(new int[]{10, 1, 5}); 55 | assertThat(min).hasValue(1); 56 | } 57 | 58 | @Test 59 | public void chunk_breaks_input_array__with_odd_length() throws Exception { 60 | int[][] chunks = Snippets.chunk(new int[]{1, 2, 3, 4, 5}, 2); 61 | assertThat(chunks) 62 | .containsExactly( 63 | new int[]{1, 2}, 64 | new int[]{3, 4}, 65 | new int[]{5} 66 | ); 67 | } 68 | 69 | @Test 70 | public void chunk_breaks_input_array__with_event_length() throws Exception { 71 | int[][] chunks = Snippets.chunk(new int[]{1, 2, 3, 4, 5, 6}, 2); 72 | assertThat(chunks) 73 | .containsExactly( 74 | new int[]{1, 2}, 75 | new int[]{3, 4}, 76 | new int[]{5, 6} 77 | ); 78 | } 79 | 80 | @Test 81 | public void countOccurrences_counts_occurrences_of_a_value() throws Exception { 82 | long count = Snippets.countOccurrences(new int[]{1, 1, 2, 1, 2, 3}, 1); 83 | assertThat(count).isEqualTo(3); 84 | } 85 | 86 | @Test 87 | public void deepFlatten_flatten_a_deeply_nested_array() throws Exception { 88 | int[] flatten = Snippets.deepFlatten( 89 | new Object[]{1, new Object[]{2}, new Object[]{3, 4, 5}} 90 | ); 91 | 92 | assertThat(flatten).isEqualTo(new int[]{1, 2, 3, 4, 5}); 93 | } 94 | 95 | @Test 96 | public void difference_between_array_with_1_2_3_and_array_with_1_2_4_is_3() throws Exception { 97 | int[] difference = Snippets.difference(new int[]{1, 2, 3}, new int[]{1, 2, 4}); 98 | assertThat(difference).isEqualTo(new int[]{3}); 99 | } 100 | 101 | @Test 102 | public void difference_between_array_with_1_2_3_and_array_with_1_2_3_is_empty_array() throws Exception { 103 | int[] difference = Snippets.difference(new int[]{1, 2, 3}, new int[]{1, 2, 3}); 104 | assertThat(difference).isEmpty(); 105 | } 106 | 107 | @Test 108 | public void differenceWith_return_all_squares_that_do_not_exist_in_second() throws Exception { 109 | int[] difference = Snippets.differenceWith( 110 | new int[]{1, 4, 9, 16, 25}, 111 | new int[]{1, 2, 3, 6, 7}, 112 | (o1, o2) -> o1 - (o2 * o2) 113 | ); 114 | 115 | assertThat(difference).isEqualTo(new int[]{16, 25}); 116 | } 117 | 118 | @Test 119 | public void differenceWith_returns_empty_array_when_two_arrays_are_equal_as_per_comparison_operation() throws Exception { 120 | int[] difference = Snippets.differenceWith( 121 | new int[]{1, 2, 3}, 122 | new int[]{1, 2, 3}, 123 | (o1, o2) -> o1 - o2 124 | ); 125 | 126 | assertThat(difference).isEmpty(); 127 | } 128 | 129 | @Test 130 | public void differenceWith_returns_first_array_when_elements_in_second_array_are_not_comparable_as_per_comparison_operation() throws Exception { 131 | int[] difference = Snippets.differenceWith( 132 | new int[]{1, 2, 3}, 133 | new int[]{10, 11, 12}, 134 | (o1, o2) -> o1 - o2 135 | ); 136 | 137 | assertThat(difference).isEqualTo(new int[]{1, 2, 3}); 138 | } 139 | 140 | @Test 141 | public void distinct_remove_all_duplicate_values_from_an_array() throws Exception { 142 | int[] distinct = Snippets.distinctValuesOfArray(new int[]{1, 2, 2, 3, 4, 4, 5}); 143 | assertThat(distinct).isEqualTo(new int[]{1, 2, 3, 4, 5}); 144 | } 145 | 146 | @Test 147 | public void drop_elements_less_than_3() throws Exception { 148 | int[] elements = Snippets.dropElements(new int[]{1, 2, 3, 4}, i -> i >= 3); 149 | assertThat(elements).isEqualTo(new int[]{3, 4}); 150 | } 151 | 152 | @Test 153 | public void drop_elements_returns_empty_array_when_no_element_match_the_condition() throws Exception { 154 | int[] elements = Snippets.dropElements(new int[]{1, 2, 3, 4}, i -> i < 1); 155 | assertThat(elements).isEmpty(); 156 | } 157 | 158 | @Test 159 | public void drop_elements__return_all_elements_when_all_elements_match_the_condition() throws Exception { 160 | int[] elements = Snippets.dropElements(new int[]{1, 2, 3, 4}, i -> i <= 4); 161 | assertThat(elements).isEqualTo(new int[]{1, 2, 3, 4}); 162 | } 163 | 164 | @Test 165 | public void dropRight_remove_n_elements_from_right() throws Exception { 166 | int[] elements = Snippets.dropRight(new int[]{1, 2, 3}, 1); 167 | assertThat(elements).isEqualTo(new int[]{1, 2}); 168 | 169 | elements = Snippets.dropRight(new int[]{1, 2, 3}, 2); 170 | assertThat(elements).isEqualTo(new int[]{1}); 171 | 172 | elements = Snippets.dropRight(new int[]{1, 2, 3}, 3); 173 | assertThat(elements).isEmpty(); 174 | 175 | elements = Snippets.dropRight(new int[]{1, 2, 3}, 42); 176 | assertThat(elements).isEmpty(); 177 | } 178 | 179 | @Test 180 | public void everyNth_return_every_2nd_element() throws Exception { 181 | int[] elements = Snippets.everyNth(new int[]{1, 2, 3, 4, 5, 6}, 2); 182 | assertThat(elements).isEqualTo(new int[]{2, 4, 6}); 183 | } 184 | 185 | @Test 186 | public void filterNonUnique_return_unique_elements() throws Exception { 187 | int[] elements = Snippets.filterNonUnique(new int[]{1, 2, 2, 3, 4, 4, 5}); 188 | assertThat(elements).isEqualTo(new int[]{1, 3, 5}); 189 | } 190 | 191 | @Test 192 | public void filterNonUnique_return_same_array_when_all_unique() throws Exception { 193 | int[] elements = Snippets.filterNonUnique(new int[]{1, 2, 3, 4, 5}); 194 | assertThat(elements).isEqualTo(new int[]{1, 2, 3, 4, 5}); 195 | } 196 | 197 | @Test 198 | public void filterNonUnique_return_empty_array_when_all_duplicated() throws Exception { 199 | int[] elements = Snippets.filterNonUnique(new int[]{1, 1, 2, 2, 3, 3, 4, 4, 5, 5}); 200 | assertThat(elements).isEmpty(); 201 | } 202 | 203 | @Test 204 | public void flatten_flat_one_level_array() throws Exception { 205 | int[] flatten = Snippets.flatten(new Object[]{1, new int[]{2}, 3, 4}); 206 | assertThat(flatten).isEqualTo(new int[]{1, 2, 3, 4}); 207 | } 208 | 209 | @Test 210 | public void flattenDepth_flatten_to_specified_depth() throws Exception { 211 | Object[] input = { 212 | 1, 213 | new Object[]{2}, 214 | new Object[]{ 215 | new Object[]{ 216 | new Object[]{ 217 | 3 218 | }, 219 | 4 220 | }, 5 221 | } 222 | }; 223 | 224 | Object[] flatten = Snippets.flattenDepth(input, 2); 225 | assertThat(flatten).isEqualTo(new Object[]{1, 2, new Object[]{3}, 4, 5}); 226 | } 227 | 228 | @Test 229 | public void group_elements_by_length() throws Exception { 230 | Map> groups = Snippets.groupBy(new String[]{"one", "two", "three"}, String::length); 231 | assertThat(groups) 232 | .containsExactly( 233 | new SimpleEntry<>(3, Arrays.asList("one", "two")), 234 | new SimpleEntry<>(5, Collections.singletonList("three")) 235 | ); 236 | } 237 | 238 | @Test 239 | public void initial_return_array_except_last_element() throws Exception { 240 | Integer[] initial = Snippets.initial(new Integer[]{1, 2, 3}); 241 | assertThat(initial).isEqualTo(new Integer[]{1, 2}); 242 | } 243 | 244 | @Test 245 | public void initializeArrayWithRange_from_1_to_5() throws Exception { 246 | int[] numbers = Snippets.initializeArrayWithRange(5, 1); 247 | assertThat(numbers).isEqualTo(new int[]{1, 2, 3, 4, 5}); 248 | } 249 | 250 | @Test 251 | public void initializeArrayWithValues() throws Exception { 252 | int[] elements = Snippets.initializeArrayWithValues(5, 2); 253 | assertThat(elements).isEqualTo(new int[]{2, 2, 2, 2, 2}); 254 | } 255 | 256 | @Test 257 | public void intersection_between_two_arrays() throws Exception { 258 | int[] elements = Snippets.intersection(new int[]{1, 2, 3}, new int[]{4, 3, 2}); 259 | assertThat(elements).isEqualTo(new int[]{2, 3}); 260 | } 261 | 262 | @Test 263 | public void isSorted_return_1_when_array_sorted_is_ascending_order() throws Exception { 264 | int sorted = Snippets.isSorted(new Integer[]{0, 1, 2, 3}); 265 | assertThat(sorted).isEqualTo(1); 266 | 267 | sorted = Snippets.isSorted(new Integer[]{0, 1, 2, 2}); 268 | assertThat(sorted).isEqualTo(1); 269 | } 270 | 271 | @Test 272 | public void isSorted_return_minus_1_when_array_sorted_in_descending_order() throws Exception { 273 | int sorted = Snippets.isSorted(new Integer[]{3, 2, 1, 0}); 274 | assertThat(sorted).isEqualTo(-1); 275 | 276 | sorted = Snippets.isSorted(new Integer[]{3, 3, 2, 1, 0}); 277 | assertThat(sorted).isEqualTo(-1); 278 | } 279 | 280 | @Test 281 | public void isSorted_returns_0_when_array_is_not_sorted() throws Exception { 282 | int sorted = Snippets.isSorted(new Integer[]{3, 4, 1, 0}); 283 | assertThat(sorted).isEqualTo(0); 284 | } 285 | 286 | @Test 287 | public void join_should_create_string_from_an_array_with_different_sep_and_end() throws Exception { 288 | String joined = Snippets.join(new String[]{"pen", "pineapple", "apple", "pen"}, ",", "&"); 289 | assertThat(joined).isEqualTo("pen,pineapple,apple&pen"); 290 | } 291 | 292 | @Test 293 | public void join_should_create_string_from_an_array_with_sep_only() throws Exception { 294 | String joined = Snippets.join(new String[]{"pen", "pineapple", "apple", "pen"}, ","); 295 | assertThat(joined).isEqualTo("pen,pineapple,apple,pen"); 296 | } 297 | 298 | @Test 299 | public void join_should_create_string_from_an_array_with_default_sep() throws Exception { 300 | String joined = Snippets.join(new String[]{"pen", "pineapple", "apple", "pen"}); 301 | assertThat(joined).isEqualTo("pen,pineapple,apple,pen"); 302 | } 303 | 304 | @Test 305 | public void join_should_create_empty_string_with_empty_array() throws Exception { 306 | String joined = Snippets.join(new String[]{}); 307 | assertThat(joined).isEqualTo(""); 308 | } 309 | 310 | @Test 311 | public void nthElement_return_nth_element_from_start_when_n_is_greater_than_0() throws Exception { 312 | String nthElement = Snippets.nthElement(new String[]{"a", "b", "c"}, 1); 313 | assertThat(nthElement).isEqualTo("b"); 314 | } 315 | 316 | 317 | @Test 318 | public void nthElement_return_nth_element_from_end_when_n_is_less_than_0() throws Exception { 319 | String nthElement = Snippets.nthElement(new String[]{"a", "b", "c"}, -3); 320 | assertThat(nthElement).isEqualTo("a"); 321 | } 322 | 323 | @Test 324 | public void pick_should_pick_key_pairs_corresponding_to_keys() throws Exception { 325 | Map obj = new HashMap<>(); 326 | obj.put("a", 1); 327 | obj.put("b", 2); 328 | obj.put("c", 3); 329 | 330 | Map picked = Snippets.pick(obj, new String[]{"a", "c"}); 331 | assertThat(picked).containsExactly(new SimpleEntry<>("a", 1), new SimpleEntry<>("c", 3)); 332 | } 333 | 334 | @Test 335 | public void reducedFilter_Test() throws Exception { 336 | Map item1 = new HashMap<>(); 337 | item1.put("id", 1); 338 | item1.put("name", "john"); 339 | item1.put("age", 24); 340 | 341 | Map item2 = new HashMap<>(); 342 | item2.put("id", 2); 343 | item2.put("name", "mike"); 344 | item2.put("age", 50); 345 | 346 | Map[] filtered = Snippets.reducedFilter((Map[]) new Map[]{item1, item2}, new String[]{"id", "name"}, item -> (Integer) item.get("age") > 24); 347 | assertThat(filtered).hasSize(1); 348 | assertThat(filtered[0]) 349 | .containsOnly( 350 | new SimpleEntry("id", 2), 351 | new SimpleEntry("name", "mike")); 352 | } 353 | 354 | @Test 355 | public void sample_should_return_random_element() throws Exception { 356 | Integer sample = Snippets.sample(new Integer[]{3, 7, 9, 11}); 357 | assertThat(sample).isIn(Arrays.asList(3, 7, 9, 11)); 358 | } 359 | 360 | @Test 361 | public void sampleSize_should_return_sample_of_size_array_length_when_sample_size_is_greater_than_array_size() throws Exception { 362 | Integer[] sample = Snippets.sampleSize(new Integer[]{1, 2, 3}, 4); 363 | assertThat(sample).hasSize(3); 364 | } 365 | 366 | @Test 367 | public void similarity_test() throws Exception { 368 | Integer[] arr = Snippets.similarity(new Integer[]{1, 2, 3}, new Integer[]{1, 2, 4}); 369 | assertThat(arr).isEqualTo(new Integer[]{1, 2}); 370 | } 371 | 372 | @Test 373 | public void empty_array() throws Exception { 374 | String[] empty = Snippets.emptyArray(String.class); 375 | assertThat(empty).isEmpty(); 376 | } 377 | 378 | @Test 379 | public void sortedIndex_descending() throws Exception { 380 | int index = Snippets.sortedIndex(new Integer[]{5, 3, 2, 1}, 4); 381 | assertThat(index).isEqualTo(1); 382 | } 383 | 384 | @Test 385 | public void sortedIndex_ascending() throws Exception { 386 | int index = Snippets.sortedIndex(new Integer[]{30, 50}, 40); 387 | assertThat(index).isEqualTo(1); 388 | } 389 | 390 | @Test 391 | public void sortedIndex_ascending_at_end() throws Exception { 392 | int index = Snippets.sortedIndex(new Integer[]{30, 50}, 60); 393 | assertThat(index).isEqualTo(2); 394 | } 395 | 396 | @Test 397 | public void symmetricDifference_test() throws Exception { 398 | Integer[] diff = Snippets.symmetricDifference( 399 | new Integer[]{1, 2, 3}, 400 | new Integer[]{1, 2, 4} 401 | ); 402 | assertThat(diff).isEqualTo(new Integer[]{3, 4}); 403 | } 404 | 405 | @Test 406 | public void union_test() throws Exception { 407 | Integer[] union = Snippets.union( 408 | new Integer[]{1, 2, 3}, 409 | new Integer[]{1, 2, 4} 410 | ); 411 | 412 | assertThat(union).isEqualTo(new Integer[]{1, 2, 3, 4}); 413 | } 414 | 415 | @Test 416 | public void without_test() throws Exception { 417 | Integer[] without = Snippets.without( 418 | new Integer[]{2, 1, 2, 3}, 419 | 1, 2 420 | 421 | ); 422 | 423 | assertThat(without).isEqualTo(new Integer[]{3}); 424 | } 425 | 426 | @Test 427 | public void zip_test() throws Exception { 428 | List zipped = Snippets.zip( 429 | new String[]{"a", "b"}, 430 | new Integer[]{1, 2}, 431 | new Boolean[]{true, false} 432 | ); 433 | 434 | assertThat(zipped).hasSize(2); 435 | assertThat(zipped.get(0)).isEqualTo(new Object[]{"a", 1, true}); 436 | assertThat(zipped.get(1)).isEqualTo(new Object[]{"b", 2, false}); 437 | } 438 | 439 | @Test 440 | public void zip_test_2() throws Exception { 441 | List zipped = Snippets.zip( 442 | new String[]{"a"}, 443 | new Integer[]{1, 2}, 444 | new Boolean[]{true, false} 445 | ); 446 | 447 | assertThat(zipped).hasSize(2); 448 | assertThat(zipped.get(0)).isEqualTo(new Object[]{"a", 1, true}); 449 | assertThat(zipped.get(1)).isEqualTo(new Object[]{null, 2, false}); 450 | } 451 | 452 | @Test 453 | public void zipObject_test_1() throws Exception { 454 | Map map = Snippets.zipObject( 455 | new String[]{"a", "b", "c"}, 456 | new Integer[]{1, 2} 457 | ); 458 | 459 | assertThat(map).containsOnly( 460 | new SimpleEntry<>("a", 1), 461 | new SimpleEntry<>("b", 2), 462 | new SimpleEntry<>("c", null) 463 | ); 464 | } 465 | 466 | @Test 467 | public void zipObject_test_2() throws Exception { 468 | Map map = Snippets.zipObject( 469 | new String[]{"a", "b"}, 470 | new Integer[]{1, 2, 3} 471 | ); 472 | 473 | assertThat(map).containsOnly( 474 | new SimpleEntry<>("a", 1), 475 | new SimpleEntry<>("b", 2) 476 | ); 477 | } 478 | 479 | @Test 480 | public void average_of_1_to_10_is_5_dot_5() throws Exception { 481 | double average = Snippets.average(IntStream.rangeClosed(1, 10).toArray()); 482 | assertThat(average).isEqualTo(5.5); 483 | } 484 | 485 | @Test 486 | public void capitalize_test() throws Exception { 487 | assertThat(Snippets.capitalize("fooBar", false)).isEqualTo("FooBar"); 488 | assertThat(Snippets.capitalize("fooBar", true)).isEqualTo("Foobar"); 489 | } 490 | 491 | @Test 492 | public void capitalizeEveryWord_test() throws Exception { 493 | assertThat(Snippets.capitalizeEveryWord("hello world!")).isEqualTo("Hello World!"); 494 | } 495 | 496 | @Test 497 | public void anagrams_test() throws Exception { 498 | List anagrams = Snippets.anagrams("abc"); 499 | assertThat(anagrams) 500 | .containsOnly("abc", "acb", "bac", "bca", "cab", "cba"); 501 | } 502 | 503 | @Test 504 | public void byteSize_of_smiley_is_4() throws Exception { 505 | int length = Snippets.byteSize("\uD83D\uDE00"); 506 | assertThat(length).isEqualTo(4); 507 | } 508 | 509 | @Test 510 | public void byteSize_of_hello_world_is_11() throws Exception { 511 | assertThat(Snippets.byteSize("Hello World")).isEqualTo(11); 512 | } 513 | 514 | @Test 515 | public void countVowels_test() throws Exception { 516 | assertThat(Snippets.countVowels("foobar")).isEqualTo(3); 517 | } 518 | 519 | @Test 520 | public void escapeRegex_test() throws Exception { 521 | assertThat(Snippets.escapeRegExp("(test)")).isEqualTo("\\Q(test)\\E"); 522 | } 523 | 524 | @Test 525 | public void fromCamelCase_test() throws Exception { 526 | assertThat(Snippets.fromCamelCase("someJavaProperty", "_")) 527 | .isEqualTo("some_java_property"); 528 | assertThat(Snippets.fromCamelCase("someDatabaseFieldName", " ")) 529 | .isEqualTo("some database field name"); 530 | assertThat(Snippets.fromCamelCase("someLabelThatNeedsToBeCamelized", "-")) 531 | .isEqualTo("some-label-that-needs-to-be-camelized"); 532 | } 533 | 534 | @Test 535 | public void isAbsoluteUrl_test() throws Exception { 536 | assertThat(Snippets.isAbsoluteUrl("https://google.com")).isTrue(); 537 | assertThat(Snippets.isAbsoluteUrl("ftp://www.myserver.net")).isTrue(); 538 | assertThat(Snippets.isAbsoluteUrl("/foo/bar")).isFalse(); 539 | } 540 | 541 | @Test 542 | public void isLowerCase_test() throws Exception { 543 | assertThat(Snippets.isLowerCase("abc")).isTrue(); 544 | assertThat(Snippets.isLowerCase("a3@$")).isTrue(); 545 | assertThat(Snippets.isLowerCase("Ab4")).isFalse(); 546 | } 547 | 548 | @Test 549 | public void mask_test() throws Exception { 550 | assertThat(Snippets.mask("1234567890", 4, "*")).isEqualTo("******7890"); 551 | assertThat(Snippets.mask("1234567890", 3, "*")).isEqualTo("*******890"); 552 | assertThat(Snippets.mask("1234567890", -4, "*")).isEqualTo("1234******"); 553 | } 554 | 555 | @Test 556 | public void palindrome_test() throws Exception { 557 | assertThat(Snippets.isPalindrome("taco cat")).isTrue(); 558 | assertThat(Snippets.isPalindrome("abc")).isFalse(); 559 | } 560 | 561 | @Test 562 | public void reverseString_test() throws Exception { 563 | assertThat(Snippets.reverseString("foobar")).isEqualTo("raboof"); 564 | } 565 | 566 | @Test 567 | public void sortCharactersInString_test() throws Exception { 568 | assertThat(Snippets.sortCharactersInString("cabbage")).isEqualTo("aabbceg"); 569 | } 570 | 571 | @Test 572 | public void splitLines_test() throws Exception { 573 | assertThat(Snippets.splitLines("This\nis a\nmultiline\nstring.\n")) 574 | .isEqualTo(new String[]{ 575 | "This", 576 | "is a", 577 | "multiline", 578 | "string." 579 | }); 580 | } 581 | 582 | @Test 583 | public void toCamelCase_test() throws Exception { 584 | assertThat(Snippets.toCamelCase("some_database_field_name")).isEqualTo("someDatabaseFieldName"); 585 | assertThat(Snippets.toCamelCase("Some label that needs to be camelized")).isEqualTo("someLabelThatNeedsToBeCamelized"); 586 | assertThat(Snippets.toCamelCase("some-java-property")).isEqualTo("someJavaProperty"); 587 | assertThat(Snippets.toCamelCase("some-mixed_string with spaces_underscores-and-hyphens")).isEqualTo("someMixedStringWithSpacesUnderscoresAndHyphens"); 588 | } 589 | 590 | @Test 591 | public void toKebabCase_test() throws Exception { 592 | assertThat(Snippets.toKebabCase("camelCase")).isEqualTo("camel-case"); 593 | assertThat(Snippets.toKebabCase("some text")).isEqualTo("some-text"); 594 | assertThat(Snippets.toKebabCase("some-mixed_string With spaces_underscores-and-hyphens")).isEqualTo("some-mixed-string-with-spaces-underscores-and-hyphens"); 595 | assertThat(Snippets.toKebabCase("AllThe-small Things")).isEqualTo("all-the-small-things"); 596 | assertThat(Snippets.toKebabCase("IAmListeningToFMWhileLoadingDifferentURLOnMyBrowserAndAlsoEditingXMLAndHTML")).isEqualTo("i-am-listening-to-fm-while-loading-different-url-on-my-browser-and-also-editing-xml-and-html"); 597 | } 598 | 599 | @Test 600 | public void toSnakeCase_test() throws Exception { 601 | assertThat(Snippets.toSnakeCase("camelCase")).isEqualTo("camel_case"); 602 | assertThat(Snippets.toSnakeCase("some text")).isEqualTo("some_text"); 603 | assertThat(Snippets.toSnakeCase("some-mixed_string With spaces_underscores-and-hyphens")).isEqualTo("some_mixed_string_with_spaces_underscores_and_hyphens"); 604 | assertThat(Snippets.toSnakeCase("AllThe-small Things")).isEqualTo("all_the_small_things"); 605 | assertThat(Snippets.toSnakeCase("IAmListeningToFMWhileLoadingDifferentURLOnMyBrowserAndAlsoEditingXMLAndHTML")).isEqualTo("i_am_listening_to_fm_while_loading_different_url_on_my_browser_and_also_editing_xml_and_html"); 606 | } 607 | 608 | @Test 609 | public void truncateString_test() throws Exception { 610 | assertThat(Snippets.truncateString("boomerang", 7)).isEqualTo("boom..."); 611 | } 612 | 613 | @Test 614 | public void words_test() throws Exception { 615 | assertThat(Snippets.words("I love java!!")).isEqualTo(new String[]{"I", "love", "java"}); 616 | assertThat(Snippets.words("Kotlin, Java & LemonTea")).isEqualTo(new String[]{"Kotlin", "Java", "LemonTea"}); 617 | } 618 | 619 | @Test 620 | public void randomInts_test() throws Exception { 621 | assertThat(Snippets.randomInts(5, 100, 200)).hasSize(5); 622 | } 623 | 624 | @Test 625 | public void concat_test() throws Exception { 626 | String[] first = {"a", "b"}; 627 | String[] second = {"c", "d"}; 628 | assertThat(Snippets.concat(first, second)) 629 | .isEqualTo(new String[]{"a", "b", "c", "d"}); 630 | } 631 | 632 | @Test 633 | public void getCurrentWorkingDirectoryPath_test() throws Exception { 634 | assertThat(Snippets.getCurrentWorkingDirectoryPath()).isNotBlank(); 635 | } 636 | 637 | @Test 638 | public void isNumeric_test() throws Exception { 639 | assertThat(Snippets.isNumeric("123")).isTrue(); 640 | assertThat(Snippets.isNumeric("abc")).isFalse(); 641 | assertThat(Snippets.isNumeric("")).isFalse(); 642 | } 643 | 644 | @Test 645 | public void findNextPositivePowerOfTwo_test() throws Exception { 646 | assertThat(Snippets.findNextPositivePowerOfTwo(-1)).isEqualTo(1); 647 | assertThat(Snippets.findNextPositivePowerOfTwo(3)).isEqualTo(4); 648 | assertThat(Snippets.findNextPositivePowerOfTwo(31)).isEqualTo(32); 649 | assertThat(Snippets.findNextPositivePowerOfTwo(32)).isEqualTo(32); 650 | } 651 | 652 | @Test 653 | public void isEven_test() throws Exception { 654 | assertThat(Snippets.isEven(1)).isFalse(); 655 | assertThat(Snippets.isEven(2)).isTrue(); 656 | assertThat(Snippets.isEven(3)).isFalse(); 657 | assertThat(Snippets.isEven(4)).isTrue(); 658 | assertThat(Snippets.isEven(-1)).isFalse(); 659 | } 660 | 661 | @Test 662 | public void stringToIntegers_test() throws Exception { 663 | int[] intArray = Snippets.stringToIntegers("1 2 3 4 5"); 664 | assertThat(intArray).isEqualTo(new int[]{1, 2, 3, 4, 5}); 665 | } 666 | 667 | private static class Class1 implements I2, I1, I5 { 668 | // empty 669 | } 670 | 671 | private static class Class2 extends Class1 implements I2, I3 { 672 | // empty 673 | } 674 | 675 | private interface I1 { 676 | // empty 677 | } 678 | 679 | private interface I2 { 680 | // empty 681 | } 682 | 683 | private interface I3 extends I4, I5 { 684 | // empty 685 | } 686 | 687 | private interface I4 { 688 | // empty 689 | } 690 | 691 | private interface I5 extends I6 { 692 | // empty 693 | } 694 | 695 | private interface I6 { 696 | // empty 697 | } 698 | 699 | @Test 700 | public void getAllInterfaces_shouldFindAllInterfacesImplementedByAClass() { 701 | final List> list = Snippets.getAllInterfaces(Class2.class); 702 | assertThat(list).hasSize(6); 703 | assertThat(list).containsExactly(I2.class, I3.class, I4.class, I5.class, I6.class, I1.class); 704 | } 705 | 706 | enum Priority { 707 | High, Medium, Low 708 | } 709 | 710 | @Test 711 | public void getEnumMap_convert_enum_to_map() throws Exception { 712 | Map map = Snippets.getEnumMap(Priority.class); 713 | assertThat(map).hasSize(3); 714 | assertThat(map) 715 | .containsOnly( 716 | new SimpleEntry<>("High", Priority.High), 717 | new SimpleEntry<>("Medium", Priority.Medium), 718 | new SimpleEntry<>("Low", Priority.Low) 719 | ); 720 | } 721 | } 722 | -------------------------------------------------------------------------------- /src/main/java/snippets/Snippets.java: -------------------------------------------------------------------------------- 1 | package snippets; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.PrintWriter; 8 | import java.io.StringWriter; 9 | import java.lang.management.ManagementFactory; 10 | import java.lang.management.RuntimeMXBean; 11 | import java.lang.reflect.Array; 12 | import java.nio.charset.StandardCharsets; 13 | import java.nio.file.FileSystems; 14 | import java.nio.file.Files; 15 | import java.nio.file.Path; 16 | import java.util.AbstractMap.SimpleEntry; 17 | import java.util.ArrayList; 18 | import java.util.Arrays; 19 | import java.util.Collections; 20 | import java.util.HashMap; 21 | import java.util.HashSet; 22 | import java.util.List; 23 | import java.util.Map; 24 | import java.util.Objects; 25 | import java.util.OptionalInt; 26 | import java.util.Set; 27 | import java.util.concurrent.ThreadLocalRandom; 28 | import java.util.function.Function; 29 | import java.util.function.IntBinaryOperator; 30 | import java.util.function.IntFunction; 31 | import java.util.function.IntPredicate; 32 | import java.util.function.Predicate; 33 | import java.util.regex.Matcher; 34 | import java.util.regex.Pattern; 35 | import java.util.stream.Collectors; 36 | import java.util.stream.IntStream; 37 | import java.util.stream.Stream; 38 | 39 | public abstract class Snippets { 40 | 41 | /** 42 | * Calculates the greatest common denominator (gcd) of an array of numbers 43 | * 44 | * @param numbers Array of numbers 45 | * @return gcd of array of numbers 46 | */ 47 | public static OptionalInt gcd(int[] numbers) { 48 | return Arrays.stream(numbers) 49 | .reduce((a, b) -> gcd(a, b)); 50 | } 51 | 52 | /** 53 | * Calculates the lowest common multiple (lcm) of an array of numbers. 54 | * 55 | * @param numbers Array of numbers 56 | * @return lcm of array of numbers 57 | */ 58 | public static OptionalInt lcm(int[] numbers) { 59 | IntBinaryOperator lcm = (x, y) -> (x * y) / gcd(x, y); 60 | return Arrays.stream(numbers) 61 | .reduce((a, b) -> lcm.applyAsInt(a, b)); 62 | } 63 | 64 | private static int gcd(int a, int b) { 65 | if (b == 0) { 66 | return a; 67 | } 68 | return gcd(b, a % b); 69 | } 70 | 71 | /** 72 | * Returns the maximum value in an array. 73 | * 74 | * @param numbers Array of numbers 75 | * @return maximum value in an array 76 | */ 77 | public static OptionalInt arrayMax(int[] numbers) { 78 | return Arrays.stream(numbers).max(); 79 | } 80 | 81 | /** 82 | * Returns the minimum value in an array. 83 | * 84 | * @param numbers Array of numbers 85 | * @return minimum value in an array 86 | */ 87 | public static OptionalInt arrayMin(int[] numbers) { 88 | return Arrays.stream(numbers).min(); 89 | } 90 | 91 | /** 92 | * Chunks an array into smaller arrays of a specified size. 93 | * 94 | * @param numbers Input array of numbers 95 | * @param size The chunk size 96 | * @return Smaller chunks 97 | */ 98 | public static int[][] chunk(int[] numbers, int size) { 99 | return IntStream.iterate(0, i -> i + size) 100 | .limit((long) Math.ceil((double) numbers.length / size)) 101 | .mapToObj(cur -> Arrays.copyOfRange(numbers, cur, cur + size > numbers.length ? numbers.length : cur + size)) 102 | .toArray(int[][]::new); 103 | } 104 | 105 | /** 106 | * Counts the occurrences of a value in an array. 107 | * 108 | * @param numbers Array of numbers 109 | * @param value the value for which we have to count occurrences 110 | * @return count of total number of occurrences of the value 111 | */ 112 | public static long countOccurrences(int[] numbers, int value) { 113 | return Arrays.stream(numbers) 114 | .filter(number -> number == value) 115 | .count(); 116 | } 117 | 118 | /** 119 | * Deep flattens an array. 120 | * 121 | * @param input A nested array containing integers 122 | * @return flattened array 123 | */ 124 | public static int[] deepFlatten(Object[] input) { 125 | return Arrays.stream(input) 126 | .flatMapToInt(o -> { 127 | if (o instanceof Object[]) { 128 | return Arrays.stream(deepFlatten((Object[]) o)); 129 | } 130 | return IntStream.of((Integer) o); 131 | }).toArray(); 132 | } 133 | 134 | /** 135 | * Returns the difference between two arrays. 136 | * 137 | * @param first the first array 138 | * @param second the second array 139 | * @return Elements in first that are not in second 140 | */ 141 | public static int[] difference(int[] first, int[] second) { 142 | Set set = Arrays.stream(second).boxed().collect(Collectors.toSet()); 143 | return Arrays.stream(first) 144 | .filter(v -> !set.contains(v)) 145 | .toArray(); 146 | } 147 | 148 | /** 149 | * Filters out all values from an array for which the comparator function does not return true. 150 | * 151 | * @param first the first array 152 | * @param second the second array 153 | * @param comparator the comparator function 154 | * @return the resulting array 155 | */ 156 | public static int[] differenceWith(int[] first, int[] second, IntBinaryOperator comparator) { 157 | return Arrays.stream(first) 158 | .filter(a -> 159 | Arrays.stream(second) 160 | .noneMatch(b -> comparator.applyAsInt(a, b) == 0) 161 | ).toArray(); 162 | } 163 | 164 | /** 165 | * Returns all the distinct values of an array. 166 | * 167 | * @param elements ints 168 | * @return distinct values 169 | */ 170 | public static int[] distinctValuesOfArray(int[] elements) { 171 | return Arrays.stream(elements).distinct().toArray(); 172 | } 173 | 174 | /** 175 | * Removes elements in an array until the passed function returns true. Returns the remaining elements in the array. 176 | * 177 | * @param elements 178 | * @param condition 179 | * @return 180 | */ 181 | public static int[] dropElements(int[] elements, IntPredicate condition) { 182 | while (elements.length > 0 && !condition.test(elements[0])) { 183 | elements = Arrays.copyOfRange(elements, 1, elements.length); 184 | } 185 | return elements; 186 | } 187 | 188 | /** 189 | * Returns a new array with n elements removed from the right 190 | * 191 | * @param elements 192 | * @param n number of elements to remove 193 | * @return array after removing n elements 194 | */ 195 | public static int[] dropRight(int[] elements, int n) { 196 | if (n < 0) { 197 | throw new IllegalArgumentException("n is less than 0"); 198 | } 199 | return n < elements.length 200 | ? Arrays.copyOfRange(elements, 0, elements.length - n) 201 | : new int[0]; 202 | } 203 | 204 | /** 205 | * Returns every nth element in an array. 206 | * 207 | * @param elements 208 | * @param nth 209 | * @return 210 | */ 211 | public static int[] everyNth(int[] elements, int nth) { 212 | return IntStream.range(0, elements.length) 213 | .filter(i -> i % nth == nth - 1) 214 | .map(i -> elements[i]) 215 | .toArray(); 216 | } 217 | 218 | /** 219 | * Filters out the non-unique values in an array. 220 | *

221 | * Use Array.stream().filter() for an array containing only the unique values. 222 | * 223 | * @param elements input array 224 | * @return unique values in the array 225 | */ 226 | public static int[] filterNonUnique(int[] elements) { 227 | return Arrays.stream(elements) 228 | .filter(el -> indexOf(elements, el) == lastIndexOf(elements, el)) 229 | .toArray(); 230 | } 231 | 232 | /** 233 | * Find index of element in the array. Return -1 in case element does not exist. 234 | *

235 | * Uses IntStream.range().filter() to find index of the element in the array. 236 | * 237 | * @param elements input array 238 | * @param el element to find 239 | * @return index of the element 240 | */ 241 | public static int indexOf(int[] elements, int el) { 242 | return IntStream.range(0, elements.length) 243 | .filter(idx -> elements[idx] == el) 244 | .findFirst() 245 | .orElse(-1); 246 | } 247 | 248 | /** 249 | * Find last index of element in the array. Return -1 in case element does not exist. 250 | *

251 | * Uses IntStream.iterate().limit().filter() to find index of the element in the array. 252 | * 253 | * @param elements input array 254 | * @param el element to find 255 | * @return index of the element 256 | */ 257 | public static int lastIndexOf(int[] elements, int el) { 258 | return IntStream.iterate(elements.length - 1, i -> i - 1) 259 | .limit(elements.length) 260 | .filter(idx -> elements[idx] == el) 261 | .findFirst() 262 | .orElse(-1); 263 | } 264 | 265 | /** 266 | * Flattens an array. 267 | * 268 | * @param elements input array 269 | * @return flattened array 270 | */ 271 | public static int[] flatten(Object[] elements) { 272 | return Arrays.stream(elements) 273 | .flatMapToInt(el -> el instanceof int[] 274 | ? Arrays.stream((int[]) el) 275 | : IntStream.of((int) el) 276 | ).toArray(); 277 | } 278 | 279 | /** 280 | * Flattens an array up to the specified depth. 281 | * 282 | * @param elements input array 283 | * @param depth depth to which to flatten array 284 | * @return flattened array 285 | */ 286 | public static Object[] flattenDepth(Object[] elements, int depth) { 287 | if (depth == 0) { 288 | return elements; 289 | } 290 | return Arrays.stream(elements) 291 | .flatMap(el -> el instanceof Object[] 292 | ? Arrays.stream(flattenDepth((Object[]) el, depth - 1)) 293 | : Arrays.stream(new Object[]{el}) 294 | ).toArray(); 295 | 296 | 297 | } 298 | 299 | /** 300 | * Groups the elements of an array based on the given function. 301 | * 302 | * @param elements input array 303 | * @param func function 304 | * @param type parameter 305 | * @return grouped elements in a Map 306 | */ 307 | public static Map> groupBy(T[] elements, Function func) { 308 | return Arrays.stream(elements).collect(Collectors.groupingBy(func)); 309 | } 310 | 311 | /** 312 | * Returns all the elements of an array except the last one. 313 | * Use Arrays.copyOfRange() to return all except the last one 314 | * 315 | * @param elements 316 | * @param 317 | * @return 318 | */ 319 | public static T[] initial(T[] elements) { 320 | return Arrays.copyOfRange(elements, 0, elements.length - 1); 321 | } 322 | 323 | /** 324 | * Initializes an array containing the numbers in the specified range where start and end are inclusive. 325 | * 326 | * @param end 327 | * @param start 328 | * @return 329 | */ 330 | public static int[] initializeArrayWithRange(int end, int start) { 331 | return IntStream.rangeClosed(start, end).toArray(); 332 | } 333 | 334 | public static int[] initializeArrayWithValues(int n, int value) { 335 | return IntStream.generate(() -> value).limit(n).toArray(); 336 | } 337 | 338 | public static int[] intersection(int[] first, int[] second) { 339 | Set set = Arrays.stream(second).boxed().collect(Collectors.toSet()); 340 | return Arrays.stream(first) 341 | .filter(set::contains) 342 | .toArray(); 343 | } 344 | 345 | public static > int isSorted(T[] arr) { 346 | final int direction = arr[0].compareTo(arr[1]) < 0 ? 1 : -1; 347 | for (int i = 0; i < arr.length; i++) { 348 | T val = arr[i]; 349 | if (i == arr.length - 1) return direction; 350 | else if ((val.compareTo(arr[i + 1]) * direction > 0)) return 0; 351 | } 352 | return direction; 353 | } 354 | 355 | public static String join(T[] arr, String separator, String end) { 356 | return IntStream.range(0, arr.length) 357 | .mapToObj(i -> new SimpleEntry<>(i, arr[i])) 358 | .reduce("", (acc, val) -> val.getKey() == arr.length - 2 359 | ? acc + val.getValue() + end 360 | : val.getKey() == arr.length - 1 ? acc + val.getValue() : acc + val.getValue() + separator, (fst, snd) -> fst); 361 | } 362 | 363 | public static String join(T[] arr, String separator) { 364 | return join(arr, separator, separator); 365 | } 366 | 367 | public static String join(T[] arr) { 368 | return join(arr, ","); 369 | } 370 | 371 | public static T nthElement(T[] arr, int n) { 372 | if (n > 0) { 373 | return Arrays.copyOfRange(arr, n, arr.length)[0]; 374 | } 375 | return Arrays.copyOfRange(arr, arr.length + n, arr.length)[0]; 376 | } 377 | 378 | public static Map pick(Map obj, T[] arr) { 379 | return Arrays.stream(arr) 380 | .filter(obj::containsKey) 381 | .collect(Collectors.toMap(k -> k, obj::get)); 382 | } 383 | 384 | public static Map[] reducedFilter(Map[] data, String[] keys, Predicate> fn) { 385 | return Arrays.stream(data) 386 | .filter(fn) 387 | .map(el -> Arrays.stream(keys).filter(el::containsKey) 388 | .collect(Collectors.toMap(Function.identity(), el::get))) 389 | .toArray((IntFunction[]>) Map[]::new); 390 | } 391 | 392 | public static T sample(T[] arr) { 393 | return arr[(int) Math.floor(Math.random() * arr.length)]; 394 | } 395 | 396 | public static T[] sampleSize(T[] input, int n) { 397 | T[] arr = Arrays.copyOf(input, input.length); 398 | int length = arr.length; 399 | int m = length; 400 | while (m > 0) { 401 | int i = (int) Math.floor(Math.random() * m--); 402 | T tmp = arr[i]; 403 | arr[i] = arr[m]; 404 | arr[m] = tmp; 405 | } 406 | return Arrays.copyOfRange(arr, 0, n > length ? length : n); 407 | } 408 | 409 | public static T[] shuffle(T[] input) { 410 | T[] arr = Arrays.copyOf(input, input.length); 411 | int length = arr.length; 412 | int m = length; 413 | while (m > 0) { 414 | int i = (int) Math.floor(Math.random() * m--); 415 | T tmp = arr[i]; 416 | arr[i] = arr[m]; 417 | arr[m] = tmp; 418 | } 419 | return arr; 420 | } 421 | 422 | public static T[] similarity(T[] first, T[] second) { 423 | return Arrays.stream(first) 424 | .filter(a -> Arrays.stream(second).anyMatch(b -> Objects.equals(a, b))) 425 | // Make a new array of first's runtime type, but empty content: 426 | .toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass())); 427 | } 428 | 429 | public static T[] emptyArray(Class clz) { 430 | return (T[]) Array.newInstance(clz, 0); 431 | } 432 | 433 | 434 | public static > int sortedIndex(T[] arr, T el) { 435 | boolean isDescending = arr[0].compareTo(arr[arr.length - 1]) > 0; 436 | return IntStream.range(0, arr.length) 437 | .filter(i -> isDescending ? el.compareTo(arr[i]) >= 0 : el.compareTo(arr[i]) <= 0) 438 | .findFirst() 439 | .orElse(arr.length); 440 | } 441 | 442 | public static T[] symmetricDifference(T[] first, T[] second) { 443 | Set sA = new HashSet<>(Arrays.asList(first)); 444 | Set sB = new HashSet<>(Arrays.asList(second)); 445 | 446 | return Stream.concat( 447 | Arrays.stream(first).filter(a -> !sB.contains(a)), 448 | Arrays.stream(second).filter(b -> !sA.contains(b)) 449 | ).toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass())); 450 | } 451 | 452 | public static T[] tail(T[] arr) { 453 | return arr.length > 1 454 | ? Arrays.copyOfRange(arr, 1, arr.length) 455 | : arr; 456 | } 457 | 458 | public static T[] take(T[] arr, int n) { 459 | return Arrays.copyOfRange(arr, 0, n); 460 | } 461 | 462 | public static T[] takeRight(T[] arr, int n) { 463 | return Arrays.copyOfRange(arr, arr.length - n, arr.length); 464 | } 465 | 466 | public static T[] union(T[] first, T[] second) { 467 | Set set = new HashSet<>(Arrays.asList(first)); 468 | set.addAll(Arrays.asList(second)); 469 | return set.toArray((T[]) Arrays.copyOf(new Object[0], 0, first.getClass())); 470 | } 471 | 472 | public static T[] without(T[] arr, T... elements) { 473 | List excludeElements = Arrays.asList(elements); 474 | return Arrays.stream(arr) 475 | .filter(el -> !excludeElements.contains(el)) 476 | .toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, arr.getClass())); 477 | } 478 | 479 | public static List zip(Object[]... arrays) { 480 | OptionalInt max = Arrays.stream(arrays).mapToInt(arr -> arr.length).max(); 481 | return IntStream.range(0, max.getAsInt()) 482 | .mapToObj(i -> Arrays.stream(arrays) 483 | .map(arr -> i < arr.length ? arr[i] : null) 484 | .toArray()) 485 | .collect(Collectors.toList()); 486 | } 487 | 488 | public static Map zipObject(String[] props, Object[] values) { 489 | return IntStream.range(0, props.length) 490 | .mapToObj(i -> new SimpleEntry<>(props[i], i < values.length ? values[i] : null)) 491 | .collect( 492 | HashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), HashMap::putAll); 493 | } 494 | 495 | public static double average(int[] arr) { 496 | return IntStream.of(arr) 497 | .average() 498 | .orElseThrow(() -> new IllegalArgumentException("Array is empty")); 499 | } 500 | 501 | public static List anagrams(String input) { 502 | if (input.length() <= 2) { 503 | return input.length() == 2 504 | ? Arrays.asList(input, input.substring(1) + input.substring(0, 1)) 505 | : Collections.singletonList(input); 506 | } 507 | return IntStream.range(0, input.length()) 508 | .mapToObj(i -> new SimpleEntry<>(i, input.substring(i, i + 1))) 509 | .flatMap(entry -> 510 | anagrams(input.substring(0, entry.getKey()) + input.substring(entry.getKey() + 1)) 511 | .stream() 512 | .map(s -> entry.getValue() + s)) 513 | .collect(Collectors.toList()); 514 | } 515 | 516 | public static int byteSize(String input) { 517 | // Read the link below to learn more 518 | // https://stackoverflow.com/questions/16270994/difference-between-string-length-and-string-getbytes-length 519 | return input.getBytes().length; 520 | } 521 | 522 | public static String capitalize(String input, boolean lowerRest) { 523 | return input.substring(0, 1).toUpperCase() + 524 | (lowerRest 525 | ? input.substring(1, input.length()).toLowerCase() 526 | : input.substring(1, input.length())); 527 | } 528 | 529 | public static String capitalizeEveryWord(final String input) { 530 | return Pattern.compile("\\b(?=\\w)").splitAsStream(input) 531 | .map(w -> capitalize(w, false)) 532 | .collect(Collectors.joining()); 533 | } 534 | 535 | public static int countVowels(String input) { 536 | return input.replaceAll("[^aeiouAEIOU]", "").length(); 537 | } 538 | 539 | public static String escapeRegExp(String input) { 540 | return Pattern.quote(input); 541 | } 542 | 543 | public static String fromCamelCase(String input, String separator) { 544 | return input 545 | .replaceAll("([a-z\\d])([A-Z])", "$1" + separator + "$2") 546 | .toLowerCase(); 547 | } 548 | 549 | public static boolean isAbsoluteUrl(String url) { 550 | return Pattern.compile("^[a-z][a-z0-9+.-]*:").matcher(url).find(); 551 | } 552 | 553 | public static boolean isLowerCase(String input) { 554 | return Objects.equals(input, input.toLowerCase()); 555 | } 556 | 557 | public static boolean isUpperCase(String input) { 558 | return Objects.equals(input, input.toUpperCase()); 559 | } 560 | 561 | public static String mask(String input, int num, String mask) { 562 | int length = input.length(); 563 | return num > 0 564 | ? 565 | input.substring(0, length - num).replaceAll(".", mask) 566 | + input.substring(length - num) 567 | : 568 | input.substring(0, Math.negateExact(num)) 569 | + input.substring(Math.negateExact(num), length).replaceAll(".", mask); 570 | } 571 | 572 | public static boolean isPalindrome(String input) { 573 | String s = input.toLowerCase().replaceAll("[\\W_]", ""); 574 | return Objects.equals( 575 | s, 576 | new StringBuilder(s).reverse().toString() 577 | ); 578 | } 579 | 580 | public static String reverseString(String input) { 581 | return new StringBuilder(input).reverse().toString(); 582 | } 583 | 584 | public static String sortCharactersInString(String input) { 585 | return Arrays.stream(input.split("")).sorted().collect(Collectors.joining()); 586 | } 587 | 588 | public static String[] splitLines(String input) { 589 | return input.split("\\r?\\n"); 590 | } 591 | 592 | public static String toCamelCase(String input) { 593 | Matcher matcher = Pattern.compile("[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+").matcher(input); 594 | List matchedParts = new ArrayList<>(); 595 | while (matcher.find()) { 596 | matchedParts.add(matcher.group(0)); 597 | } 598 | String s = matchedParts.stream() 599 | .map(x -> x.substring(0, 1).toUpperCase() + x.substring(1).toLowerCase()) 600 | .collect(Collectors.joining()); 601 | return s.substring(0, 1).toLowerCase() + s.substring(1); 602 | } 603 | 604 | public static String toKebabCase(String input) { 605 | Matcher matcher = Pattern.compile("[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+").matcher(input); 606 | List matchedParts = new ArrayList<>(); 607 | while (matcher.find()) { 608 | matchedParts.add(matcher.group(0)); 609 | } 610 | return matchedParts.stream() 611 | .map(String::toLowerCase) 612 | .collect(Collectors.joining("-")); 613 | } 614 | 615 | public static List match(String input, String regex) { 616 | Matcher matcher = Pattern.compile(regex).matcher(input); 617 | List matchedParts = new ArrayList<>(); 618 | while (matcher.find()) { 619 | matchedParts.add(matcher.group(0)); 620 | } 621 | return matchedParts; 622 | } 623 | 624 | public static String toSnakeCase(String input) { 625 | Matcher matcher = Pattern.compile("[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+").matcher(input); 626 | List matchedParts = new ArrayList<>(); 627 | while (matcher.find()) { 628 | matchedParts.add(matcher.group(0)); 629 | } 630 | return matchedParts.stream() 631 | .map(String::toLowerCase) 632 | .collect(Collectors.joining("_")); 633 | } 634 | 635 | public static String truncateString(String input, int num) { 636 | return input.length() > num 637 | ? input.substring(0, num > 3 ? num - 3 : num) + "..." 638 | : input; 639 | } 640 | 641 | public static String[] words(String input) { 642 | return Arrays.stream(input.split("[^a-zA-Z-]+")) 643 | .filter(s -> !s.isEmpty()) 644 | .toArray(String[]::new); 645 | } 646 | 647 | //Read the link below for more information 648 | // https://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string 649 | public static String convertInputStreamToString(final InputStream in) throws IOException { 650 | ByteArrayOutputStream result = new ByteArrayOutputStream(); 651 | byte[] buffer = new byte[1024]; 652 | int length; 653 | while ((length = in.read(buffer)) != -1) { 654 | result.write(buffer, 0, length); 655 | } 656 | return result.toString(StandardCharsets.UTF_8.name()); 657 | } 658 | 659 | public static int[] randomInts(int total, int start, int end) { 660 | return ThreadLocalRandom.current().ints(total, start, end).toArray(); 661 | } 662 | 663 | public String readFileAsString(Path path) throws IOException { 664 | return new String(Files.readAllBytes(path)); 665 | } 666 | 667 | public static String stackTraceAsString(final Throwable throwable) { 668 | final StringWriter sw = new StringWriter(); 669 | throwable.printStackTrace(new PrintWriter(sw)); 670 | return sw.toString(); 671 | } 672 | 673 | public static T[] concat(T[] first, T[] second) { 674 | return Stream.concat( 675 | Stream.of(first), 676 | Stream.of(second) 677 | ).toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass())); 678 | } 679 | 680 | public static String getCurrentWorkingDirectoryPath() { 681 | return FileSystems.getDefault().getPath("").toAbsolutePath().toString(); 682 | } 683 | 684 | public static boolean isNumeric(final String input) { 685 | if (input == null || input.isEmpty()) { 686 | return false; 687 | } 688 | return IntStream.range(0, input.length()) 689 | .allMatch(i -> Character.isDigit(input.charAt(i))); 690 | } 691 | 692 | public static int findNextPositivePowerOfTwo(int value) { 693 | return 1 << (32 - Integer.numberOfLeadingZeros(value - 1)); 694 | } 695 | 696 | public static boolean isEven(final int value) { 697 | return (value & 0b1) == 0; 698 | } 699 | 700 | public static boolean isPowerOfTwo(final int value) { 701 | return value > 0 && ((value & (~value + 1)) == value); 702 | } 703 | 704 | public static int generateRandomInt() { 705 | return ThreadLocalRandom.current().nextInt(); 706 | } 707 | 708 | public static String tmpDirName() { 709 | String tmpDirName = System.getProperty("java.io.tmpdir"); 710 | if (!tmpDirName.endsWith(File.separator)) { 711 | tmpDirName += File.separator; 712 | } 713 | 714 | return tmpDirName; 715 | } 716 | 717 | public static String osName() { 718 | return System.getProperty("os.name").toLowerCase(); 719 | } 720 | 721 | public static boolean isDebuggerAttached() { 722 | final RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); 723 | return runtimeMXBean.getInputArguments() 724 | .stream() 725 | .anyMatch(arg -> arg.contains("-agentlib:jdwp")); 726 | 727 | } 728 | 729 | /** 730 | * Input a line of numbers separated by space as integers 731 | * and return ArrayList of Integers. 732 | * eg. the String "1 2 3 4 5 6 7 8 9" is returned as an ArrayList of Integers. 733 | * 734 | * @param numbers range of numbers separated by space as a string 735 | * @return ArrayList of Integers 736 | */ 737 | 738 | public static int[] stringToIntegers(String numbers) { 739 | return Arrays.stream(numbers.split(" ")).mapToInt(Integer::parseInt).toArray(); 740 | } 741 | 742 | /* Class Utilities */ 743 | 744 | public static List> getAllInterfaces(final Class cls) { 745 | return Stream.concat( 746 | Arrays.stream(cls.getInterfaces()).flatMap(intf -> 747 | Stream.concat(Stream.of(intf), getAllInterfaces(intf).stream())), 748 | cls.getSuperclass() == null ? Stream.empty() : getAllInterfaces(cls.getSuperclass()).stream() 749 | ).distinct().collect(Collectors.toList()); 750 | } 751 | 752 | public static boolean isInnerClass(final Class cls) { 753 | return cls != null && cls.getEnclosingClass() != null; 754 | } 755 | 756 | public static > Map getEnumMap(final Class enumClass) { 757 | return Arrays.stream(enumClass.getEnumConstants()) 758 | .collect(Collectors.toMap(Enum::name, Function.identity())); 759 | } 760 | } 761 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 30 Seconds Of Java [![Build Status](https://travis-ci.org/shekhargulati/little-java-functions.svg?branch=master)](https://travis-ci.org/shekhargulati/little-java-functions) 2 | 3 | > Curated collection of useful little Java 8 functions that you can understand quickly. 4 | 5 | ## Table of Contents 6 | 7 | ### Array 8 | 9 |

10 | View contents 11 | 12 | * [`chunk`](#chunk) 13 | * [`countOccurrences`](#countoccurrences) 14 | * [`deepFlatten`](#deepflatten) 15 | * [`difference`](#difference) 16 | * [`differenceWith`](#differencewith) 17 | * [`distinctValuesOfArray`](#distinctvaluesofarray) 18 | * [`dropElements`](#dropelements) 19 | * [`dropRight`](#dropright) 20 | * [`everyNth`](#everynth) 21 | * [`filterNonUnique`](#filternonunique) 22 | * [`flatten`](#flatten) 23 | * [`flattenDepth`](#flattendepth) 24 | * [`groupBy`](#groupby) 25 | * [`head`](#head) 26 | * [`initial`](#initial) 27 | * [`initializeArrayWithRange`](#initializearraywithrange) 28 | * [`initializeArrayWithValues`](#initializearraywithvalues) 29 | * [`intersection`](#intersection) 30 | * [`isSorted`](#issorted) 31 | * [`join`](#join) 32 | * [`nthElement`](#nthelement) 33 | * [`pick`](#pick) 34 | * [`reducedFilter`](#reducedfilter) 35 | * [`remove`](#remove) 36 | * [`sample`](#sample) 37 | * [`sampleSize`](#samplesize) 38 | * [`shuffle`](#shuffle) 39 | * [`similarity`](#similarity) 40 | * [`sortedIndex`](#sortedindex) 41 | * [`symmetricDifference`](#symmetricdifference) 42 | * [`tail`](#tail) 43 | * [`take`](#take) 44 | * [`takeRight`](#takeright) 45 | * [`union`](#union) 46 | * [`without`](#without) 47 | * [`zip`](#zip) 48 | * [`zipObject`](#zipobject) 49 | 50 |
51 | 52 | ### Math 53 | 54 |
55 | View contents 56 | 57 | * [`average`](#average) 58 | * [`gcd`](#gcd) 59 | * [`lcm`](#lcm) 60 | * [`findNextPositivePowerOfTwo`](#findnextpositivepoweroftwo) 61 | * [`isEven`](#iseven) 62 | * [`isPowerOfTwo`](#ispoweroftwo) 63 | * [`generateRandomInt`](#generaterandomint) 64 | 65 |
66 | 67 | ### String 68 | 69 |
70 | View contents 71 | 72 | * [`anagrams`](#anagrams) 73 | * [`byteSize`](#bytesize) 74 | * [`capitalize`](#capitalize) 75 | * [`capitalizeEveryWord`](#capitalizeeveryword) 76 | * [`countVowels`](#countvowels) 77 | * [`escapeRegExp`](#escaperegexp) 78 | * [`fromCamelCase`](#fromcamelcase) 79 | * [`isAbsoluteURL`](#isabsoluteurl) 80 | * [`isLowerCase`](#islowercase) 81 | * [`isUpperCase`](#isuppercase) 82 | * [`isPalindrome`](#ispalindrome) 83 | * [`isNumeric`](#isnumeric) 84 | * [`mask`](#mask) 85 | * [`reverseString`](#reversestring) 86 | * [`sortCharactersInString`](#sortcharactersinstring) 87 | * [`splitLines`](#splitlines) 88 | * [`toCamelCase`](#tocamelcase) 89 | * [`toKebabCase`](#tokebabcase) 90 | * [`match`](#match) 91 | * [`toSnakeCase`](#tosnakecase) 92 | * [`truncateString`](#truncatestring) 93 | * [`words`](#words) 94 | * [`stringToIntegers`](#stringtointegers) 95 | 96 | 97 |
98 | 99 | ### IO 100 | 101 |
102 | View contents 103 | 104 | * [`convertInputStreamToString`](#convertinputstreamtostring) 105 | * [`readFileAsString`](#readfileasstring) 106 | * [`getCurrentWorkingDirectoryPath`](#getcurrentworkingdirectorypath) 107 | * [`tmpDirName`](#tmpdirname) 108 | 109 |
110 | 111 | ### Exception 112 | 113 |
114 | View contents 115 | 116 | * [`stackTraceAsString`](#stacktraceasstring) 117 | 118 |
119 | 120 | ### System 121 | 122 |
123 | View contents 124 | 125 | - [`osName`](#osname) 126 | - [`isDebuggerEnabled`](#isdebuggerenabled) 127 | 128 |
129 | 130 | ### Class 131 | 132 |
133 | View contents 134 | 135 | - [`getAllInterfaces`](#getallinterfaces) 136 | - [`IsInnerClass`](#isinnerclass) 137 | 138 |
139 | 140 | ### Enum 141 | 142 |
143 | View contents 144 | 145 | - [`getEnumMap`](#getenummap) 146 | 147 |
148 | 149 | ## Array 150 | 151 | ### chunk 152 | 153 | Chunks an array into smaller arrays of specified size. 154 | 155 | ```java 156 | public static int[][] chunk(int[] numbers, int size) { 157 | return IntStream.iterate(0, i -> i + size) 158 | .limit((long) Math.ceil((double) numbers.length / size)) 159 | .mapToObj(cur -> Arrays.copyOfRange(numbers, cur, cur + size > numbers.length ? numbers.length : cur + size)) 160 | .toArray(int[][]::new); 161 | } 162 | ``` 163 | 164 | ### concat 165 | 166 | ```java 167 | public static T[] concat(T[] first, T[] second) { 168 | return Stream.concat( 169 | Stream.of(first), 170 | Stream.of(second) 171 | ).toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass())); 172 | } 173 | ``` 174 | 175 | ### countOccurrences 176 | 177 | Counts the occurrences of a value in an array. 178 | 179 | Use Arrays.stream().filter().count() to count total number of values that equals the specified value. 180 | 181 | ```java 182 | public static long countOccurrences(int[] numbers, int value) { 183 | return Arrays.stream(numbers) 184 | .filter(number -> number == value) 185 | .count(); 186 | } 187 | ``` 188 | 189 | ### deepFlatten 190 | 191 | Deep flattens an array. 192 | 193 | Use recursion. Use Arrays.stream().flatMapToInt() 194 | 195 | ```java 196 | public static int[] deepFlatten(Object[] input) { 197 | return Arrays.stream(input) 198 | .flatMapToInt(o -> { 199 | if (o instanceof Object[]) { 200 | return Arrays.stream(deepFlatten((Object[]) o)); 201 | } 202 | return IntStream.of((Integer) o); 203 | }).toArray(); 204 | } 205 | ``` 206 | 207 | ### difference 208 | 209 | Returns the difference between two arrays. 210 | 211 | Create a Set from b, then use Arrays.stream().filter() on a to only keep values not contained in b. 212 | 213 | ```java 214 | public static int[] difference(int[] first, int[] second) { 215 | Set set = Arrays.stream(second).boxed().collect(Collectors.toSet()); 216 | return Arrays.stream(first) 217 | .filter(v -> !set.contains(v)) 218 | .toArray(); 219 | } 220 | ``` 221 | 222 | ### differenceWith 223 | 224 | Filters out all values from an array for which the comparator function does not return true. 225 | 226 | The comparator for int is implemented using IntBinaryOperator function. 227 | 228 | Uses Arrays.stream().filter and Arrays.stream().noneMatch() to find the appropriate values. 229 | 230 | ```java 231 | public static int[] differenceWith(int[] first, int[] second, IntBinaryOperator comparator) { 232 | return Arrays.stream(first) 233 | .filter(a -> 234 | Arrays.stream(second) 235 | .noneMatch(b -> comparator.applyAsInt(a, b) == 0) 236 | ).toArray(); 237 | } 238 | ``` 239 | 240 | ### distinctValuesOfArray 241 | 242 | Returns all the distinct values of an array. 243 | 244 | Uses Arrays.stream().distinct() to discard all duplicated values. 245 | 246 | ```java 247 | public static int[] distinctValuesOfArray(int[] elements) { 248 | return Arrays.stream(elements).distinct().toArray(); 249 | } 250 | ``` 251 | 252 | ### dropElements 253 | 254 | Removes elements in an array until the passed function returns true. Returns the remaining elements in the array. 255 | 256 | Loop through the array, using Arrays.copyOfRange() to drop the first element of the array until the returned value from the function is true. Returns the remaining elements. 257 | 258 | ```java 259 | public static int[] dropElements(int[] elements, IntPredicate condition) { 260 | while (elements.length > 0 && !condition.test(elements[0])) { 261 | elements = Arrays.copyOfRange(elements, 1, elements.length); 262 | } 263 | return elements; 264 | } 265 | ``` 266 | 267 | ### dropRight 268 | 269 | Returns a new array with n elements removed from the right. 270 | 271 | Check if n is shorter than the given array and use Array.copyOfRange() to slice it accordingly or return an empty array. 272 | 273 | ```java 274 | public static int[] dropRight(int[] elements, int n) { 275 | if (n < 0) { 276 | throw new IllegalArgumentException("n is less than 0"); 277 | } 278 | return n < elements.length 279 | ? Arrays.copyOfRange(elements, 0, elements.length - n) 280 | : new int[0]; 281 | } 282 | ``` 283 | 284 | ### everyNth 285 | 286 | Returns every nth element in an array. 287 | 288 | Use IntStream.range().filter() to create a new array that contains every nth element of a given array. 289 | 290 | ```java 291 | public static int[] everyNth(int[] elements, int nth) { 292 | return IntStream.range(0, elements.length) 293 | .filter(i -> i % nth == nth - 1) 294 | .map(i -> elements[i]) 295 | .toArray(); 296 | } 297 | ``` 298 | 299 | ### indexOf 300 | 301 | Find index of element in the array. Return -1 in case element does not exist. 302 | 303 | Uses IntStream.range().filter() to find index of the element in the array. 304 | 305 | ```java 306 | public static int indexOf(int[] elements, int el) { 307 | return IntStream.range(0, elements.length) 308 | .filter(idx -> elements[idx] == el) 309 | .findFirst() 310 | .orElse(-1); 311 | } 312 | ``` 313 | 314 | ### lastIndexOf 315 | 316 | Find last index of element in the array. Return -1 in case element does not exist. 317 | 318 | Uses IntStream.iterate().limit().filter() to find index of the element in the array. 319 | 320 | 321 | ```java 322 | public static int lastIndexOf(int[] elements, int el) { 323 | return IntStream.iterate(elements.length - 1, i -> i - 1) 324 | .limit(elements.length) 325 | .filter(idx -> elements[idx] == el) 326 | .findFirst() 327 | .orElse(-1); 328 | } 329 | ``` 330 | 331 | ### filterNonUnique 332 | 333 | Filters out the non-unique values in an array. 334 | 335 | Use Arrays.stream().filter() for an array containing only the unique values. 336 | 337 | ```java 338 | public static int[] filterNonUnique(int[] elements) { 339 | return Arrays.stream(elements) 340 | .filter(el -> indexOf(elements, el) == lastIndexOf(elements, el)) 341 | .toArray(); 342 | } 343 | ``` 344 | 345 | ### flatten 346 | 347 | Flattens an array. 348 | 349 | Use Arrays.stream().flatMapToInt().toArray() to create a new array. 350 | 351 | 352 | ```java 353 | public static int[] flatten(Object[] elements) { 354 | return Arrays.stream(elements) 355 | .flatMapToInt(el -> el instanceof int[] 356 | ? Arrays.stream((int[]) el) 357 | : IntStream.of((int) el) 358 | ).toArray(); 359 | } 360 | ``` 361 | 362 | ### flattenDepth 363 | 364 | Flattens an array up to the specified depth. 365 | 366 | ```java 367 | public static Object[] flattenDepth(Object[] elements, int depth) { 368 | if (depth == 0) { 369 | return elements; 370 | } 371 | return Arrays.stream(elements) 372 | .flatMap(el -> el instanceof Object[] 373 | ? Arrays.stream(flattenDepth((Object[]) el, depth - 1)) 374 | : Arrays.stream(new Object[]{el}) 375 | ).toArray(); 376 | 377 | 378 | } 379 | ``` 380 | 381 | ### groupBy 382 | 383 | Groups the elements of an array based on the given function. 384 | 385 | Uses Arrays.stream().collect(Collectors.groupingBy()) to group based on the grouping function. 386 | 387 | ```java 388 | public static Map> groupBy(T[] elements, Function func) { 389 | return Arrays.stream(elements).collect(Collectors.groupingBy(func)); 390 | } 391 | ``` 392 | 393 | ### initial 394 | 395 | Returns all the elements of an array except the last one. 396 | Use Arrays.copyOfRange() to return all except the last one 397 | 398 | ```java 399 | public static T[] initial(T[] elements) { 400 | return Arrays.copyOfRange(elements, 0, elements.length - 1); 401 | } 402 | ``` 403 | 404 | ### initializeArrayWithRange 405 | 406 | Initializes an array containing the numbers in the specified range where start and end are inclusive. 407 | 408 | 409 | ```java 410 | public static int[] initializeArrayWithRange(int end, int start) { 411 | return IntStream.rangeClosed(start, end).toArray(); 412 | } 413 | ``` 414 | 415 | ### initializeArrayWithValues 416 | 417 | Initializes and fills an array with the specified values. 418 | 419 | ```java 420 | public static int[] initializeArrayWithValues(int n, int value) { 421 | return IntStream.generate(() -> value).limit(n).toArray(); 422 | } 423 | ``` 424 | 425 | ### intersection 426 | 427 | Returns a list of elements that exist in both arrays. 428 | 429 | Create a Set from second, then use Arrays.stream().filter() on a to only keep values contained in b. 430 | 431 | ```java 432 | public static int[] intersection(int[] first, int[] second) { 433 | Set set = Arrays.stream(second).boxed().collect(Collectors.toSet()); 434 | return Arrays.stream(first) 435 | .filter(set::contains) 436 | .toArray(); 437 | } 438 | ``` 439 | 440 | ### isSorted 441 | 442 | Returns `1` if the array is sorted in ascending order, `-1` if it is sorted in descending order or `0` if it is not sorted. 443 | 444 | Calculate the ordering `direction` for the first two elements.Use for loop to iterate over array items and compare them in pairs. Return `0` if the `direction` changes or the `direction` if the last element is reached. 445 | 446 | ```java 447 | public static > int isSorted(T[] arr) { 448 | final int direction = arr[0].compareTo(arr[1]) < 0 ? 1 : -1; 449 | for (int i = 0; i < arr.length; i++) { 450 | T val = arr[i]; 451 | if (i == arr.length - 1) return direction; 452 | else if ((val.compareTo(arr[i + 1]) * direction > 0)) return 0; 453 | } 454 | return direction; 455 | } 456 | ``` 457 | 458 | ### join 459 | 460 | Joins all elements of an array into a string and returns this string. Uses a separator and an end separator. 461 | 462 | Use IntStream.range to zip index with the array item. Then, use `Stream.reduce` to combine elements into a string. 463 | 464 | ```java 465 | public static String join(T[] arr, String separator, String end) { 466 | return IntStream.range(0, arr.length) 467 | .mapToObj(i -> new SimpleEntry<>(i, arr[i])) 468 | .reduce("", (acc, val) -> val.getKey() == arr.length - 2 469 | ? acc + val.getValue() + end 470 | : val.getKey() == arr.length - 1 ? acc + val.getValue() : acc + val.getValue() + separator, (fst, snd) -> fst); 471 | } 472 | ``` 473 | 474 | ### nthElement 475 | 476 | Returns the nth element of an array. 477 | 478 | Use `Arrays.copyOfRange()` to get an array containing the nth element at the first place. 479 | 480 | ```Java 481 | public static T nthElement(T[] arr, int n) { 482 | if (n > 0) { 483 | return Arrays.copyOfRange(arr, n, arr.length)[0]; 484 | } 485 | return Arrays.copyOfRange(arr, arr.length + n, arr.length)[0]; 486 | } 487 | ``` 488 | 489 | ### pick 490 | 491 | Picks the key-value pairs corresponding to the given keys from an object. 492 | 493 | Use `Arrays.stream` to filter all the keys that are present in the `arr`. Then, convert all the keys present into a Map using `Collectors.toMap`. 494 | 495 | ```java 496 | public static Map pick(Map obj, T[] arr) { 497 | return Arrays.stream(arr) 498 | .filter(obj::containsKey) 499 | .collect(Collectors.toMap(k -> k, obj::get)); 500 | } 501 | ``` 502 | 503 | ### reducedFilter 504 | 505 | Filter an array of objects based on a condition while also filtering out unspecified keys. 506 | 507 | Use `Arrays.stream().filter()` to filter the array based on the predicate `fn` so that it returns the objects for which the condition is true. For each filtered Map object, create a new Map with keys present in the `keys`. Finally, collect all the Map object into an array. 508 | 509 | ```java 510 | public static Map[] reducedFilter(Map[] data, String[] keys, Predicate> fn) { 511 | return Arrays.stream(data) 512 | .filter(fn) 513 | .map(el -> Arrays.stream(keys).filter(el::containsKey) 514 | .collect(Collectors.toMap(Function.identity(), el::get))) 515 | .toArray((IntFunction[]>) Map[]::new); 516 | } 517 | ``` 518 | 519 | ### sample 520 | 521 | Returns a random element from an array. 522 | 523 | Use `Math.random()` to generate a random number, multiply it by `length` and round it of to the nearest whole number using `Math.floor()`. This method also works with strings. 524 | 525 | ```java 526 | public static T sample(T[] arr) { 527 | return arr[(int) Math.floor(Math.random() * arr.length)]; 528 | } 529 | ``` 530 | 531 | ### sampleSize 532 | 533 | Gets `n` random elements at unique keys from `array` up to the size of `array`. 534 | 535 | Shuffle the array using the [Fisher-Yates algorithm](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle). Use `Array.copyOfRange()` to get the first `n` elements. 536 | 537 | ```java 538 | public static T[] sampleSize(T[] input, int n) { 539 | T[] arr = Arrays.copyOf(input, input.length); 540 | int length = arr.length; 541 | int m = length; 542 | while (m > 0) { 543 | int i = (int) Math.floor(Math.random() * m--); 544 | T tmp = arr[i]; 545 | arr[i] = arr[m]; 546 | arr[m] = tmp; 547 | } 548 | return Arrays.copyOfRange(arr, 0, n > length ? length : n); 549 | } 550 | ``` 551 | 552 | ### shuffle 553 | 554 | Randomizes the order of the values of an array, returning a new array. 555 | 556 | Uses the [Fisher-Yates algorithm](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) to reorder the elements of the array. 557 | 558 | ```java 559 | public static T[] shuffle(T[] input) { 560 | T[] arr = Arrays.copyOf(input, input.length); 561 | int length = arr.length; 562 | int m = length; 563 | while (m > 0) { 564 | int i = (int) Math.floor(Math.random() * m--); 565 | T tmp = arr[i]; 566 | arr[i] = arr[m]; 567 | arr[m] = tmp; 568 | } 569 | return arr; 570 | } 571 | ``` 572 | 573 | ### similarity 574 | 575 | Returns an array of elements that appear in both arrays. 576 | 577 | Use `Arrays.stream().filter()` to remove values that are not part of `second`, determined using `Arrays.stream().anyMatch()`. 578 | 579 | ```java 580 | public static T[] similarity(T[] first, T[] second) { 581 | return Arrays.stream(first) 582 | .filter(a -> Arrays.stream(second).anyMatch(b -> Objects.equals(a, b))) 583 | // Make a new array of first's runtime type, but empty content: 584 | .toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass())); 585 | } 586 | ``` 587 | 588 | ### sortedIndex 589 | 590 | Returns the lowest index at which value should be inserted into array in order to maintain its sort order. 591 | 592 | Check if the array is sorted in descending order (loosely). Use `IntStream.range().filter()` to find the appropriate index where the element should be inserted. 593 | 594 | ```java 595 | public static > int sortedIndex(T[] arr, T el) { 596 | boolean isDescending = arr[0].compareTo(arr[arr.length - 1]) > 0; 597 | return IntStream.range(0, arr.length) 598 | .filter(i -> isDescending ? el.compareTo(arr[i]) >= 0 : el.compareTo(arr[i]) <= 0) 599 | .findFirst() 600 | .orElse(arr.length); 601 | } 602 | ``` 603 | 604 | ### symmetricDifference 605 | 606 | Returns the symmetric difference between two arrays. 607 | 608 | Create a `Set` from each array, then use `Arrays.stream().filter()` on each of them to only keep values not contained in the other. Finally, concatenate both arrays and create a new array and return it. 609 | 610 | ```java 611 | public static T[] symmetricDifference(T[] first, T[] second) { 612 | Set sA = new HashSet<>(Arrays.asList(first)); 613 | Set sB = new HashSet<>(Arrays.asList(second)); 614 | 615 | return Stream.concat( 616 | Arrays.stream(first).filter(a -> !sB.contains(a)), 617 | Arrays.stream(second).filter(b -> !sA.contains(b)) 618 | ).toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, first.getClass())); 619 | } 620 | ``` 621 | 622 | ### tail 623 | 624 | Returns all elements in an array except for the first one. 625 | 626 | Return `Arrays.copyOfRange(1)` if the array's `length` is more than `1`, otherwise, return the whole array. 627 | 628 | ```java 629 | public static T[] tail(T[] arr) { 630 | return arr.length > 1 631 | ? Arrays.copyOfRange(arr, 1, arr.length) 632 | : arr; 633 | } 634 | ``` 635 | 636 | ### take 637 | 638 | Returns an array with n elements removed from the beginning. 639 | 640 | ```java 641 | public static T[] take(T[] arr, int n) { 642 | return Arrays.copyOfRange(arr, 0, n); 643 | } 644 | ``` 645 | 646 | ### takeRight 647 | 648 | Returns an array with n elements removed from the end. 649 | 650 | Use `Arrays.copyOfRange()` to create a slice of the array with `n` elements taken from the end. 651 | 652 | ```java 653 | public static T[] takeRight(T[] arr, int n) { 654 | return Arrays.copyOfRange(arr, arr.length - n, arr.length); 655 | } 656 | ``` 657 | 658 | ### union 659 | 660 | Returns every element that exists in any of the two arrays once. 661 | 662 | Create a `Set` with all values of `a` and `b` and convert to an array. 663 | 664 | ```Java 665 | public static T[] union(T[] first, T[] second) { 666 | Set set = new HashSet<>(Arrays.asList(first)); 667 | set.addAll(Arrays.asList(second)); 668 | return set.toArray((T[]) Arrays.copyOf(new Object[0], 0, first.getClass())); 669 | } 670 | ``` 671 | 672 | ### without 673 | 674 | Filters out the elements of an array, that have one of the specified values. 675 | 676 | Use `Arrays.strean().filter()` to create an array excluding(using `!Arrays.asList(elements).contains()`) all given values. 677 | 678 | ```java 679 | public static T[] without(T[] arr, T... elements) { 680 | List excludeElements = Arrays.asList(elements); 681 | return Arrays.stream(arr) 682 | .filter(el -> !excludeElements.contains(el)) 683 | .toArray(i -> (T[]) Arrays.copyOf(new Object[0], i, arr.getClass())); 684 | } 685 | ``` 686 | 687 | ### zip 688 | 689 | Creates an array of elements, grouped based on the position in the original arrays. 690 | 691 | ```java 692 | public static List zip(Object[]... arrays) { 693 | OptionalInt max = Arrays.stream(arrays).mapToInt(arr -> arr.length).max(); 694 | return IntStream.range(0, max.getAsInt()) 695 | .mapToObj(i -> Arrays.stream(arrays) 696 | .map(arr -> i < arr.length ? arr[i] : null) 697 | .toArray()) 698 | .collect(Collectors.toList()); 699 | } 700 | ``` 701 | 702 | ### zipObject 703 | 704 | Given an array of valid property identifiers and an array of values, return an object associating the properties to the values. 705 | 706 | ```java 707 | public static Map zipObject(String[] props, Object[] values) { 708 | return IntStream.range(0, props.length) 709 | .mapToObj(i -> new SimpleEntry<>(props[i], i < values.length ? values[i] : null)) 710 | .collect( 711 | HashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), HashMap::putAll); 712 | } 713 | ``` 714 | 715 | ## Maths 716 | 717 | ### average 718 | 719 | Returns the average of an of two or more numbers. 720 | 721 | ```java 722 | public static double average(int[] arr) { 723 | return IntStream.of(arr) 724 | .average() 725 | .orElseThrow(() -> new IllegalArgumentException("Array is empty")); 726 | } 727 | ``` 728 | 729 | ### gcd 730 | 731 | Calculates the greatest common denominator (gcd) of an array of numbers. 732 | 733 | Use Arrays.stream().reduce() and the gcd formula (uses recursion) to calculate the greatest common denominator of an array of numbers. 734 | 735 | ```java 736 | public static OptionalInt gcd(int[] numbers) { 737 | return Arrays.stream(numbers) 738 | .reduce((a, b) -> gcd(a, b)); 739 | } 740 | 741 | private static int gcd(int a, int b) { 742 | if (b == 0) { 743 | return a; 744 | } 745 | return gcd(b, a % b); 746 | } 747 | ``` 748 | 749 | ### lcm 750 | 751 | Calculates the lowest common multiple (lcm) of an array of numbers. 752 | 753 | Use Arrays.stream().reduce() and the lcm formula (uses recursion) to calculate the lowest common multiple of an array of numbers. 754 | 755 | ```java 756 | public static OptionalInt lcm(int[] numbers) { 757 | IntBinaryOperator lcm = (x, y) -> (x * y) / gcd(x, y); 758 | return Arrays.stream(numbers) 759 | .reduce((a, b) -> lcm.applyAsInt(a, b)); 760 | } 761 | 762 | private static int gcd(int a, int b) { 763 | if (b == 0) { 764 | return a; 765 | } 766 | return gcd(b, a % b); 767 | } 768 | ``` 769 | 770 | ### findNextPositivePowerOfTwo 771 | 772 | Finds the next power of two greater than or equal to the value. 773 | 774 | This method uses left ship operator to shift 1 by the value on the right side. The right side is calculated using the `Integer.numberOfLeadingZeros` method. 775 | 776 | The `Integer.numberOfLeadingZeros` give the number of zeros leading the value. For example, calling `Integer.numberOfLeadingZeros(3)` would give value as 30. This is because 3 is represented in binary as `11`. As integer has 32 bits, so there are 30 bits with 0. The right side of the left shift operator becomes `32-30 = 2`. Left shifting 1 by 2 i.e. `001 << 2` would be `100`. `100` in decimal is equal to `4`. 777 | 778 | ```java 779 | public static int findNextPositivePowerOfTwo(int value) { 780 | return 1 << (32 - Integer.numberOfLeadingZeros(value - 1)); 781 | } 782 | ``` 783 | 784 | ### isEven 785 | 786 | Check if the number is even. 787 | 788 | This method uses bitwise & operator. The `0b1` is the binary representation of 1. Since, Java 7 you can write binary literals by prefixing them with either `0b` or `0B`. The & operator will return 0 when number is even. For example, `IsEven(4)` would result in `100` `&` `001`. The result of `&` will be `000`. 789 | 790 | ```java 791 | public static boolean isEven(final int value) { 792 | return (value & 0b1) == 0; 793 | } 794 | ``` 795 | 796 | ### isPowerOfTwo 797 | 798 | Checks if a value is positive power of two. 799 | 800 | To understand how it works let's assume we made a call `IsPowerOfTwo(4)`. 801 | 802 | As value is greater than 0, so right side of the `&&` operator will be evaluated. 803 | 804 | The result of `(~value + 1)` is equal to value itself. `~100 + 001` => `011 + 001` => `100`. This is equal to value. 805 | 806 | The result of `(value & value)` is value. `100` & `100` => `100`. 807 | 808 | This will value the expression to true as value is equal to value. 809 | 810 | ```Java 811 | public static boolean isPowerOfTwo(final int value) { 812 | return value > 0 && ((value & (~value + 1)) == value); 813 | } 814 | ``` 815 | 816 | ### generateRandomInt 817 | 818 | Generate a random integer between `Integer.MIN_VALUE` and `Integer.MAX_VALUE`. 819 | 820 | ```java 821 | public static int generateRandomInt() { 822 | return ThreadLocalRandom.current().nextInt(); 823 | } 824 | ``` 825 | 826 | ## String 827 | 828 | ### anagrams 829 | 830 | Generates all anagrams of a string (contains duplicates). 831 | 832 | ```java 833 | public static List anagrams(String input) { 834 | if (input.length() <= 2) { 835 | return input.length() == 2 836 | ? Arrays.asList(input, input.substring(1) + input.substring(0, 1)) 837 | : Collections.singletonList(input); 838 | } 839 | return IntStream.range(0, input.length()) 840 | .mapToObj(i -> new SimpleEntry<>(i, input.substring(i, i + 1))) 841 | .flatMap(entry -> 842 | anagrams(input.substring(0, entry.getKey()) + input.substring(entry.getKey() + 1)) 843 | .stream() 844 | .map(s -> entry.getValue() + s)) 845 | .collect(Collectors.toList()); 846 | } 847 | ``` 848 | 849 | ### byteSize 850 | 851 | Returns the length of a string in bytes. 852 | 853 | ```java 854 | public static int byteSize(String input) { 855 | return input.getBytes().length; 856 | } 857 | ``` 858 | 859 | ### capitalize 860 | 861 | Capitalizes the first letter of a string. 862 | 863 | ```Java 864 | public static String capitalize(String input, boolean lowerRest) { 865 | return input.substring(0, 1).toUpperCase() + 866 | (lowerRest 867 | ? input.substring(1, input.length()).toLowerCase() 868 | : input.substring(1, input.length())); 869 | } 870 | ``` 871 | 872 | ### capitalizeEveryWord 873 | 874 | Capitalizes the first letter of every word in a string. 875 | 876 | ```java 877 | public static String capitalizeEveryWord(final String input) { 878 | return Pattern.compile("\\b(?=\\w)").splitAsStream(input) 879 | .map(w -> capitalize(w, false)) 880 | .collect(Collectors.joining()); 881 | } 882 | ``` 883 | 884 | ### countVowels 885 | 886 | Retuns `number` of vowels in provided string. 887 | 888 | ```java 889 | public static int countVowels(String input) { 890 | return input.replaceAll("[^aeiouAEIOU]", "").length(); 891 | } 892 | ``` 893 | 894 | ### escapeRegExp 895 | 896 | Escapes a string to use in a regular expression. 897 | 898 | ```java 899 | public static String escapeRegExp(String input) { 900 | return Pattern.quote(input); 901 | } 902 | ``` 903 | 904 | ### fromCamelCase 905 | 906 | Converts a string from camelcase. 907 | 908 | ```java 909 | public static String fromCamelCase(String input, String separator) { 910 | return input 911 | .replaceAll("([a-z\\d])([A-Z])", "$1" + separator + "$2") 912 | .toLowerCase(); 913 | } 914 | ``` 915 | 916 | ### isAbsoluteUrl 917 | 918 | Returns `true` if the given string is an absolute URL, `false` otherwise. 919 | 920 | ```java 921 | public static boolean isAbsoluteUrl(String url) { 922 | return Pattern.compile("^[a-z][a-z0-9+.-]*:").matcher(url).find(); 923 | } 924 | ``` 925 | 926 | ### isLowerCase 927 | 928 | Checks if a string is lower case. 929 | 930 | ```java 931 | public static boolean isLowerCase(String input) { 932 | return Objects.equals(input, input.toLowerCase()); 933 | } 934 | ``` 935 | 936 | ### isUpperCase 937 | 938 | Checks if a string is upper case. 939 | 940 | ```java 941 | public static boolean isUpperCase(String input) { 942 | return Objects.equals(input, input.toUpperCase()); 943 | } 944 | ``` 945 | 946 | ### isPalindrome 947 | 948 | Checks if a string is palindrome. 949 | 950 | ```java 951 | public static boolean isPalindrome(String input) { 952 | String s = input.toLowerCase().replaceAll("[\\W_]", ""); 953 | return Objects.equals( 954 | s, 955 | new StringBuilder(s).reverse().toString() 956 | ); 957 | } 958 | ``` 959 | 960 | ### isNumeric 961 | 962 | Checks if a string is numeric. 963 | 964 | ```java 965 | public static boolean isNumeric(final String input) { 966 | return IntStream.range(0, input.length()) 967 | .allMatch(i -> Character.isDigit(input.charAt(i))); 968 | } 969 | ``` 970 | 971 | ### mask 972 | 973 | Replaces all but the last `num` of characters with the specified mask character. 974 | 975 | ```Java 976 | public static String mask(String input, int num, String mask) { 977 | int length = input.length(); 978 | return num > 0 979 | ? 980 | input.substring(0, length - num).replaceAll(".", mask) 981 | + input.substring(length - num) 982 | : 983 | input.substring(0, Math.negateExact(num)) 984 | + input.substring(Math.negateExact(num), length).replaceAll(".", mask); 985 | } 986 | ``` 987 | 988 | ### reverseString 989 | 990 | Reverses a string. 991 | 992 | ```java 993 | public static String reverseString(String input) { 994 | return new StringBuilder(input).reverse().toString(); 995 | } 996 | ``` 997 | 998 | ### sortCharactersInString 999 | 1000 | Alphabetically sorts the characters in a string. 1001 | 1002 | ```java 1003 | public static String sortCharactersInString(String input) { 1004 | return Arrays.stream(input.split("")).sorted().collect(Collectors.joining()); 1005 | } 1006 | ``` 1007 | 1008 | ### splitLines 1009 | 1010 | Splits a multiline string into an array of lines. 1011 | 1012 | ```java 1013 | public static String[] splitLines(String input) { 1014 | return input.split("\\r?\\n"); 1015 | } 1016 | ``` 1017 | 1018 | ### toCamelCase 1019 | 1020 | Converts a string to camelcase. 1021 | 1022 | ```java 1023 | public static String toCamelCase(String input) { 1024 | Matcher matcher = Pattern.compile("[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+").matcher(input); 1025 | List matchedParts = new ArrayList<>(); 1026 | while (matcher.find()) { 1027 | matchedParts.add(matcher.group(0)); 1028 | } 1029 | String s = matchedParts.stream() 1030 | .map(x -> x.substring(0, 1).toUpperCase() + x.substring(1).toLowerCase()) 1031 | .collect(Collectors.joining()); 1032 | return s.substring(0, 1).toLowerCase() + s.substring(1); 1033 | } 1034 | 1035 | ``` 1036 | 1037 | ### toKebabCase 1038 | 1039 | Converts a string to kebab case. 1040 | 1041 | ```java 1042 | public static String toKebabCase(String input) { 1043 | Matcher matcher = Pattern.compile("[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+").matcher(input); 1044 | List matchedParts = new ArrayList<>(); 1045 | while (matcher.find()) { 1046 | matchedParts.add(matcher.group(0)); 1047 | } 1048 | return matchedParts.stream() 1049 | .map(String::toLowerCase) 1050 | .collect(Collectors.joining("-")); 1051 | } 1052 | ``` 1053 | 1054 | ### match 1055 | 1056 | ```java 1057 | public static List match(String input, String regex) { 1058 | Matcher matcher = Pattern.compile(regex).matcher(input); 1059 | List matchedParts = new ArrayList<>(); 1060 | while (matcher.find()) { 1061 | matchedParts.add(matcher.group(0)); 1062 | } 1063 | return matchedParts; 1064 | } 1065 | 1066 | ``` 1067 | 1068 | ### toSnakeCase 1069 | 1070 | Converts a string to snake case. 1071 | 1072 | ```java 1073 | public static String toSnakeCase(String input) { 1074 | Matcher matcher = Pattern.compile("[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+").matcher(input); 1075 | List matchedParts = new ArrayList<>(); 1076 | while (matcher.find()) { 1077 | matchedParts.add(matcher.group(0)); 1078 | } 1079 | return matchedParts.stream() 1080 | .map(String::toLowerCase) 1081 | .collect(Collectors.joining("_")); 1082 | } 1083 | ``` 1084 | 1085 | ### truncateString 1086 | 1087 | Truncates a string up to a specified length. 1088 | 1089 | ```java 1090 | public static String truncateString(String input, int num) { 1091 | return input.length() > num 1092 | ? input.substring(0, num > 3 ? num - 3 : num) + "..." 1093 | : input; 1094 | } 1095 | ``` 1096 | 1097 | ### words 1098 | 1099 | Converts a given string into an array of words. 1100 | 1101 | ```Java 1102 | public static String[] words(String input) { 1103 | return Arrays.stream(input.split("[^a-zA-Z-]+")) 1104 | .filter(s -> !s.isEmpty()) 1105 | .toArray(String[]::new); 1106 | } 1107 | ``` 1108 | 1109 | ### stringToIntegers 1110 | 1111 | Converts a String of numbers separated by space to an array of ints. 1112 | 1113 | ```Java 1114 | public static int[] stringToIntegers(String numbers) { 1115 | return Arrays.stream(numbers.split(" ")).mapToInt(Integer::parseInt).toArray(); 1116 | } 1117 | ``` 1118 | 1119 | 1120 | ## IO 1121 | 1122 | ### convertInputStreamToString 1123 | 1124 | Converts InputStream to a String. 1125 | 1126 | ```java 1127 | public static String convertInputStreamToString(final InputStream in) throws IOException { 1128 | ByteArrayOutputStream result = new ByteArrayOutputStream(); 1129 | byte[] buffer = new byte[1024]; 1130 | int length; 1131 | while ((length = in.read(buffer)) != -1) { 1132 | result.write(buffer, 0, length); 1133 | } 1134 | return result.toString(StandardCharsets.UTF_8.name()); 1135 | } 1136 | ``` 1137 | 1138 | ### readFileAsString 1139 | 1140 | Reads content of a file to a String 1141 | 1142 | ```java 1143 | public String readFileAsString(Path path) throws IOException { 1144 | return new String(Files.readAllBytes(path)); 1145 | } 1146 | ``` 1147 | 1148 | ### getCurrentWorkingDirectoryPath 1149 | 1150 | ```java 1151 | public static String getCurrentWorkingDirectoryPath() { 1152 | return FileSystems.getDefault().getPath("").toAbsolutePath().toString(); 1153 | } 1154 | ``` 1155 | 1156 | ### tmpDirName 1157 | 1158 | Returns the value of `java.io.tmpdir` system property. It appends separator if not present at the end. 1159 | 1160 | ```java 1161 | public static String tmpDirName() { 1162 | String tmpDirName = System.getProperty("java.io.tmpdir"); 1163 | if (!tmpDirName.endsWith(File.separator)) { 1164 | tmpDirName += File.separator; 1165 | } 1166 | 1167 | return tmpDirName; 1168 | } 1169 | ``` 1170 | 1171 | ## Exception 1172 | 1173 | ### stackTraceAsString 1174 | 1175 | Converts exception stack trace to a String. 1176 | 1177 | ```java 1178 | public static String stackTraceAsString(final Throwable throwable) { 1179 | final StringWriter sw = new StringWriter(); 1180 | throwable.printStackTrace(new PrintWriter(sw)); 1181 | return sw.toString(); 1182 | } 1183 | ``` 1184 | ## System 1185 | 1186 | ### osName 1187 | 1188 | Gets the name of the operating system as a lower case String. 1189 | 1190 | ```java 1191 | public static String osName() { 1192 | return System.getProperty("os.name").toLowerCase(); 1193 | } 1194 | ``` 1195 | 1196 | ### isDebuggerEnabled 1197 | 1198 | Checks if debugger is attached to the JVM. 1199 | 1200 | ```java 1201 | public static boolean isDebuggerAttached() { 1202 | final RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); 1203 | return runtimeMXBean.getInputArguments() 1204 | .stream() 1205 | .anyMatch(arg -> arg.contains("-agentlib:jdwp")); 1206 | 1207 | } 1208 | ``` 1209 | 1210 | ## Class 1211 | 1212 | ### getAllInterfaces 1213 | 1214 | This methods returns all the interfaces implemented by the given class and its superclasses. 1215 | 1216 | This method works by concatenating two streams. The first stream is recursively built by creating a stream with the interface and all the interfaces implemented by the the interface. The second stream does the same for the super classes. The result is the concatenation of the two streams after removing the duplicates. 1217 | 1218 | ```java 1219 | public static List> getAllInterfaces(Class cls) { 1220 | return Stream.concat( 1221 | Arrays.stream(cls.getInterfaces()).flatMap(intf -> 1222 | Stream.concat(Stream.of(intf), getAllInterfaces(intf).stream())), 1223 | cls.getSuperclass() == null ? Stream.empty() : getAllInterfaces(cls.getSuperclass()).stream() 1224 | ).distinct().collect(Collectors.toList()); 1225 | } 1226 | ``` 1227 | 1228 | ### isInnerClass 1229 | 1230 | This method checks if the specified class is an inner class or static nested class 1231 | 1232 | ```Java 1233 | public static boolean isInnerClass(final Class cls) { 1234 | return cls != null && cls.getEnclosingClass() != null; 1235 | } 1236 | ``` 1237 | 1238 | ## Enum 1239 | 1240 | ### getEnumMap 1241 | 1242 | Converts to enum to Map where key is the name and value is Enum itself. 1243 | 1244 | ```java 1245 | public static > Map getEnumMap(final Class enumClass) { 1246 | return Arrays.stream(enumClass.getEnumConstants()) 1247 | .collect(Collectors.toMap(Enum::name, Function.identity())); 1248 | } 1249 | ``` 1250 | 1251 | ## In News 1252 | 1253 | 1. Jetbrains Java Annotated Monthly covered little-java-functions in their [January newsletter](https://blog.jetbrains.com/idea/2018/01/java-annotated-monthly-january-2018/). 1254 | 2. JavaChannel podcast covered little-java-functions in their [episode 11](https://javachannel.org/posts/javachannels-interesting-links-podcast-episode-11/). 1255 | 3. little-java-functions was Github trending repository on 8th January 2018. 1256 | 1257 | ## Thanks 1258 | 1259 | This project started as a Java fork of [30-seconds-of-code](https://github.com/Chalarangelo/30-seconds-of-code). Thanks to the project collaborators for the effort. 1260 | --------------------------------------------------------------------------------