From fdc17210463817766b59775a48fcfe66422e22ae Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 12 Nov 2016 16:52:46 +0300 Subject: [PATCH 1/9] Initial commit with IDEA project and prewritten files. --- 08-Streams/.idea/compiler.xml | 26 +++ .../.idea/copyright/profiles_settings.xml | 3 + 08-Streams/.idea/gradle.xml | 18 ++ .../Gradle__com_google_guava_guava_19_0.xml | 11 + .../libraries/Gradle__junit_junit_4_11.xml | 11 + ...Gradle__org_hamcrest_hamcrest_core_1_3.xml | 11 + 08-Streams/.idea/misc.xml | 19 ++ 08-Streams/.idea/modules.xml | 10 + 08-Streams/.idea/modules/08-Streams.iml | 12 + 08-Streams/.idea/modules/08-Streams_main.iml | 14 ++ 08-Streams/.idea/modules/08-Streams_test.iml | 18 ++ 08-Streams/build.gradle | 15 ++ 08-Streams/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53556 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + 08-Streams/gradlew | 164 ++++++++++++++ 08-Streams/gradlew.bat | 90 ++++++++ 08-Streams/settings.gradle | 2 + .../bachelor2015/veselov/hw08/Album.java | 29 +++ .../bachelor2015/veselov/hw08/Artist.java | 14 ++ .../veselov/hw08/FirstPartTasks.java | 75 +++++++ .../veselov/hw08/SecondPartTasks.java | 33 +++ .../bachelor2015/veselov/hw08/Track.java | 20 ++ .../veselov/hw08/FirstPartTasksTest.java | 206 ++++++++++++++++++ .../veselov/hw08/SecondPartTasksTest.java | 28 +++ 24 files changed, 835 insertions(+) create mode 100644 08-Streams/.idea/compiler.xml create mode 100644 08-Streams/.idea/copyright/profiles_settings.xml create mode 100644 08-Streams/.idea/gradle.xml create mode 100644 08-Streams/.idea/libraries/Gradle__com_google_guava_guava_19_0.xml create mode 100644 08-Streams/.idea/libraries/Gradle__junit_junit_4_11.xml create mode 100644 08-Streams/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml create mode 100644 08-Streams/.idea/misc.xml create mode 100644 08-Streams/.idea/modules.xml create mode 100644 08-Streams/.idea/modules/08-Streams.iml create mode 100644 08-Streams/.idea/modules/08-Streams_main.iml create mode 100644 08-Streams/.idea/modules/08-Streams_test.iml create mode 100644 08-Streams/build.gradle create mode 100644 08-Streams/gradle/wrapper/gradle-wrapper.jar create mode 100644 08-Streams/gradle/wrapper/gradle-wrapper.properties create mode 100755 08-Streams/gradlew create mode 100644 08-Streams/gradlew.bat create mode 100644 08-Streams/settings.gradle create mode 100644 08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Album.java create mode 100644 08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Artist.java create mode 100644 08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java create mode 100644 08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java create mode 100644 08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Track.java create mode 100644 08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasksTest.java create mode 100644 08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java diff --git a/08-Streams/.idea/compiler.xml b/08-Streams/.idea/compiler.xml new file mode 100644 index 0000000..e5d3af3 --- /dev/null +++ b/08-Streams/.idea/compiler.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/copyright/profiles_settings.xml b/08-Streams/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/08-Streams/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/08-Streams/.idea/gradle.xml b/08-Streams/.idea/gradle.xml new file mode 100644 index 0000000..ab6e46d --- /dev/null +++ b/08-Streams/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/libraries/Gradle__com_google_guava_guava_19_0.xml b/08-Streams/.idea/libraries/Gradle__com_google_guava_guava_19_0.xml new file mode 100644 index 0000000..7a74e8c --- /dev/null +++ b/08-Streams/.idea/libraries/Gradle__com_google_guava_guava_19_0.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/libraries/Gradle__junit_junit_4_11.xml b/08-Streams/.idea/libraries/Gradle__junit_junit_4_11.xml new file mode 100644 index 0000000..dc26b34 --- /dev/null +++ b/08-Streams/.idea/libraries/Gradle__junit_junit_4_11.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml b/08-Streams/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 0000000..8262f72 --- /dev/null +++ b/08-Streams/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/misc.xml b/08-Streams/.idea/misc.xml new file mode 100644 index 0000000..9793229 --- /dev/null +++ b/08-Streams/.idea/misc.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/modules.xml b/08-Streams/.idea/modules.xml new file mode 100644 index 0000000..01855ab --- /dev/null +++ b/08-Streams/.idea/modules.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/modules/08-Streams.iml b/08-Streams/.idea/modules/08-Streams.iml new file mode 100644 index 0000000..43d1e6c --- /dev/null +++ b/08-Streams/.idea/modules/08-Streams.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/modules/08-Streams_main.iml b/08-Streams/.idea/modules/08-Streams_main.iml new file mode 100644 index 0000000..d7d928d --- /dev/null +++ b/08-Streams/.idea/modules/08-Streams_main.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/.idea/modules/08-Streams_test.iml b/08-Streams/.idea/modules/08-Streams_test.iml new file mode 100644 index 0000000..7de1892 --- /dev/null +++ b/08-Streams/.idea/modules/08-Streams_test.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/08-Streams/build.gradle b/08-Streams/build.gradle new file mode 100644 index 0000000..c18a94b --- /dev/null +++ b/08-Streams/build.gradle @@ -0,0 +1,15 @@ +group 'package ru.spbau.bachelor2015.veselov.hw08' +version '1.0-SNAPSHOT' + +apply plugin: 'java' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + testCompile group: 'junit', name: 'junit', version: '4.11' + compile group: 'com.google.guava', name: 'guava', version: '19.0' +} diff --git a/08-Streams/gradle/wrapper/gradle-wrapper.jar b/08-Streams/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..ca78035ef0501d802d4fc55381ef2d5c3ce0ec6e GIT binary patch literal 53556 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�H$uJM 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/08-Streams/gradlew.bat b/08-Streams/gradlew.bat new file mode 100644 index 0000000..f6d5974 --- /dev/null +++ b/08-Streams/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/08-Streams/settings.gradle b/08-Streams/settings.gradle new file mode 100644 index 0000000..8662d2c --- /dev/null +++ b/08-Streams/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = '08-Streams' + diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Album.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Album.java new file mode 100644 index 0000000..da26fb2 --- /dev/null +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Album.java @@ -0,0 +1,29 @@ +package ru.spbau.bachelor2015.veselov.hw08; + +import java.util.Arrays; +import java.util.List; + +public class Album { + + private final String name; + private final List tracks; + private final Artist artist; + + public Album(Artist artist, String name, Track... tracks) { + this.name = name; + this.tracks = Arrays.asList(tracks); + this.artist = artist; + } + + public String getName() { + return name; + } + + public List getTracks() { + return tracks; + } + + public Artist getArtist() { + return artist; + } +} diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Artist.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Artist.java new file mode 100644 index 0000000..111a9c1 --- /dev/null +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Artist.java @@ -0,0 +1,14 @@ +package ru.spbau.bachelor2015.veselov.hw08; + +public class Artist { + + private final String name; + + public Artist(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java new file mode 100644 index 0000000..1f94820 --- /dev/null +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java @@ -0,0 +1,75 @@ +package ru.spbau.bachelor2015.veselov.hw08; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public final class FirstPartTasks { + + private FirstPartTasks() {} + + // Список названий альбомов + public static List allNames(Stream albums) { + throw new UnsupportedOperationException(); + } + + // Список названий альбомов, отсортированный лексикографически по названию + public static List allNamesSorted(Stream albums) { + throw new UnsupportedOperationException(); + } + + // Список треков, отсортированный лексикографически по названию, включающий все треки альбомов из 'albums' + public static List allTracksSorted(Stream albums) { + throw new UnsupportedOperationException(); + } + + // Список альбомов, в которых есть хотя бы один трек с рейтингом более 95, отсортированный по названию + public static List sortedFavorites(Stream s) { + throw new UnsupportedOperationException(); + } + + // Сгруппировать альбомы по артистам + public static Map> groupByArtist(Stream albums) { + throw new UnsupportedOperationException(); + } + + // Сгруппировать альбомы по артистам (в качестве значения вместо объекта 'Artist' использовать его имя) + public static Map> groupByArtistMapName(Stream albums) { + throw new UnsupportedOperationException(); + } + + // Число повторяющихся альбомов в потоке + public static long countAlbumDuplicates(Stream albums) { + throw new UnsupportedOperationException(); + } + + // Альбом, в котором максимум рейтинга минимален + // (если в альбоме нет ни одного трека, считать, что максимум рейтинга в нем --- 0) + public static Optional minMaxRating(Stream albums) { + throw new UnsupportedOperationException(); + } + + // Список альбомов, отсортированный по убыванию среднего рейтинга его треков (0, если треков нет) + public static List sortByAverageRating(Stream albums) { + throw new UnsupportedOperationException(); + } + + // Произведение всех чисел потока по модулю 'modulo' + // (все числа от 0 до 10000) + public static int moduloProduction(IntStream stream, int modulo) { + throw new UnsupportedOperationException(); + } + + // Вернуть строку, состояющую из конкатенаций переданного массива, и окруженную строками "<", ">" + // см. тесты + public static String joinTo(String... strings) { + throw new UnsupportedOperationException(); + } + + // Вернуть поток из объектов класса 'clazz' + public static Stream filterIsInstance(Stream s, Class clazz) { + throw new UnsupportedOperationException(); + } +} diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java new file mode 100644 index 0000000..d0250a5 --- /dev/null +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java @@ -0,0 +1,33 @@ +package ru.spbau.bachelor2015.veselov.hw08; + +import java.util.List; +import java.util.Map; + +public final class SecondPartTasks { + + private SecondPartTasks() {} + + // Найти строки из переданных файлов, в которых встречается указанная подстрока. + public static List findQuotes(List paths, CharSequence sequence) { + throw new UnsupportedOperationException(); + } + + // В квадрат с длиной стороны 1 вписана мишень. + // Стрелок атакует мишень и каждый раз попадает в произвольную точку квадрата. + // Надо промоделировать этот процесс с помощью класса java.util.Random и посчитать, какова вероятность попасть в мишень. + public static double piDividedBy4() { + throw new UnsupportedOperationException(); + } + + // Дано отображение из имени автора в список с содержанием его произведений. + // Надо вычислить, чья общая длина произведений наибольшая. + public static String findPrinter(Map> compositions) { + throw new UnsupportedOperationException(); + } + + // Вы крупный поставщик продуктов. Каждая торговая сеть делает вам заказ в виде Map<Товар, Количество>. + // Необходимо вычислить, какой товар и в каком количестве надо поставить. + public static Map calculateGlobalOrder(List> orders) { + throw new UnsupportedOperationException(); + } +} diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Track.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Track.java new file mode 100644 index 0000000..38a1e4d --- /dev/null +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/Track.java @@ -0,0 +1,20 @@ +package ru.spbau.bachelor2015.veselov.hw08; + +public class Track { + + private final String name; + private final int rating; + + public Track(String name, int rating) { + this.name = name; + this.rating = rating; + } + + public String getName() { + return name; + } + + public int getRating() { + return rating; + } +} \ No newline at end of file diff --git a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasksTest.java b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasksTest.java new file mode 100644 index 0000000..586fe5b --- /dev/null +++ b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasksTest.java @@ -0,0 +1,206 @@ +package ru.spbau.bachelor2015.veselov.hw08; + +import com.google.common.collect.ImmutableMap; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static org.junit.Assert.*; +import static ru.spbau.bachelor2015.veselov.hw08.FirstPartTasks.*; + +public class FirstPartTasksTest { + + @Test + public void testAllNames() { + assertEquals( + Arrays.asList("Sun Structures", "Keep In The Dark"), + allNames(Stream.of(ALBUM_0, ALBUM_1))); + + assertEquals( + Collections.emptyList(), + allNames(Stream.of())); + } + + @Test + public void testAllNamesSorted() { + assertEquals( + Arrays.asList("Keep In The Dark", "Sun Structures"), + allNamesSorted(Stream.of(ALBUM_0, ALBUM_1))); + + assertEquals( + Collections.emptyList(), + allNamesSorted(Stream.of())); + } + + @Test + public void testAllTracksSorted() { + assertEquals( + Arrays.asList( + "A Question Isn't Answered", "Colours to Life", "Fragment's Light", + "Jewel of Mine Eye", "Keep in the Dark", "Keep in the Dark", "Mesmerise", + "Move With The Season", "Sand Dance", "Shelter Song", "Sun Structures", + "Test of Time", "The Golden Throne", "The Guesser"), + allTracksSorted(Stream.of(ALBUM_0, ALBUM_1))); + + assertEquals( + Collections.emptyList(), + allTracksSorted(Stream.of())); + } + + @Test + public void testSortedFavorites() { + assertEquals( + Arrays.asList(ALBUM_13, ALBUM_18, ALBUM_10, ALBUM_5, ALBUM_12, ALBUM_4), + sortedFavorites(Stream.of(ALL_ALBUMS))); + + assertEquals( + Collections.emptyList(), + sortedFavorites(Stream.of())); + } + + @Test + public void testGroupByArtist() { + assertEquals( + ImmutableMap.of( + ARTIST_0, Arrays.asList(ALBUM_2, ALBUM_3), + ARTIST_3, Arrays.asList(ALBUM_9, ALBUM_10), + ARTIST_7, Arrays.asList(ALBUM_17, ALBUM_19)), + groupByArtist(Stream.of(ALBUM_2, ALBUM_9, ALBUM_3, ALBUM_10, ALBUM_17, ALBUM_19))); + + assertEquals( + Collections.emptyMap(), + groupByArtist(Stream.of())); + } + + @Test + public void testGroupByArtistMapName() { + assertEquals( + ImmutableMap.of( + ARTIST_0, Arrays.asList(ALBUM_2.getName(), ALBUM_3.getName()), + ARTIST_3, Arrays.asList(ALBUM_9.getName(), ALBUM_10.getName()), + ARTIST_7, Arrays.asList(ALBUM_17.getName(), ALBUM_19.getName())), + groupByArtistMapName(Stream.of(ALBUM_2, ALBUM_9, ALBUM_3, ALBUM_10, ALBUM_17, ALBUM_19))); + + assertEquals( + Collections.emptyMap(), + groupByArtistMapName(Stream.of())); + } + + @Test + public void testCountAlbumDuplicates() { + assertEquals( + 0, + countAlbumDuplicates(Stream.of(ALBUM_0, ALBUM_1, ALBUM_4))); + + assertEquals( + 0, + countAlbumDuplicates(Stream.of())); + + assertEquals( + 3, + countAlbumDuplicates(Stream.of(ALBUM_0, ALBUM_1, ALBUM_2, ALBUM_3, ALBUM_4, ALBUM_5, ALBUM_6, + ALBUM_7, ALBUM_8, ALBUM_9, ALBUM_10, ALBUM_11, ALBUM_12, ALBUM_13, ALBUM_14, ALBUM_15, ALBUM_16, + ALBUM_17, ALBUM_4, ALBUM_1, ALBUM_3, ALBUM_18, ALBUM_19))); + } + + @Test + public void testMinMaxRating() { + assertEquals( + Optional.of(ALBUM_9), + minMaxRating(Stream.of(ALBUM_2, ALBUM_9, ALBUM_3, ALBUM_10, ALBUM_17, ALBUM_19))); + + assertEquals( + Optional.empty(), + minMaxRating(Stream.of())); + } + + @Test + public void testSortByAverageRating() { + assertEquals( + Arrays.asList(ALBUM_10, ALBUM_3, ALBUM_2, ALBUM_9), + sortByAverageRating(Stream.of(ALBUM_2, ALBUM_9, ALBUM_3, ALBUM_10))); + + assertEquals( + Collections.emptyList(), + sortByAverageRating(Stream.of())); + } + + @Test + public void testModuloProduction() { + assertEquals( + 2, + moduloProduction(IntStream.of(1, 3, 5, 7, 2), 4)); + + assertEquals( + 720, + moduloProduction(IntStream.of(1, 2, 3, 4, 5, 6), 10000)); + } + + @Test + public void testJoinTo() { + assertEquals( + "", + joinTo("abc", "cde")); + + assertEquals( + "", + joinTo("abc")); + + assertEquals( + "<>", + joinTo()); + } + + @Test + public void testFilterIsInstance() { + assertEquals( + Arrays.asList("", "cde"), + filterIsInstance(Stream.of("", 1, 2.0, "cde"), CharSequence.class).collect(Collectors.toList())); + + assertEquals( + Collections.emptyList(), + filterIsInstance(Stream.of("", 1, 2.0, "cde"), Void.class).collect(Collectors.toList())); + + assertEquals( + Arrays.asList("", 1, 2.0, "cde"), + filterIsInstance(Stream.of("", 1, 2.0, "cde"), Object.class).collect(Collectors.toList())); + } + + private static final Artist ARTIST_0 = new Artist("Morcheeba"); + private static final Artist ARTIST_1 = new Artist("Temples"); + private static final Artist ARTIST_2 = new Artist("God Help the Girl"); + private static final Artist ARTIST_3 = new Artist("All India Radio"); + private static final Artist ARTIST_4 = new Artist("UNKLE"); + private static final Artist ARTIST_5 = new Artist("Bonobo"); + private static final Artist ARTIST_6 = new Artist("Grimes"); + private static final Artist ARTIST_7 = new Artist("Massive Attack"); + private static final Album ALBUM_0 = new Album(ARTIST_0, "Sun Structures", new Track("Shelter Song", 85), new Track("Sun Structures", 53), new Track("The Golden Throne", 72), new Track("Keep in the Dark", 49), new Track("Mesmerise", 85), new Track("Move With The Season", 16), new Track("Colours to Life", 37), new Track("A Question Isn't Answered", 50), new Track("The Guesser", 53), new Track("Test of Time", 92), new Track("Sand Dance", 21), new Track("Fragment's Light", 61)); + private static final Album ALBUM_1 = new Album(ARTIST_0, "Keep In The Dark", new Track("Keep in the Dark", 89), new Track("Jewel of Mine Eye", 83)); + private static final Album ALBUM_2 = new Album(ARTIST_0, "Big Calm", new Track("The Sea", 72), new Track("Shoulder Holster", 26), new Track("Part of the Process", 31), new Track("Blindfold", 84), new Track("Let Me See", 55), new Track("Bullet Proof", 24), new Track("Over and Over", 1), new Track("Friction", 56), new Track("diggin' in a watery grave", 53), new Track("Fear and Love", 5), new Track("Big Calm", 37)); + private static final Album ALBUM_3 = new Album(ARTIST_0, "Charango", new Track("Slow Down", 0), new Track("Otherwise", 36), new Track("Aqualung", 82), new Track("Sao Paulo", 44), new Track("Charango (Feat: Pace Won)", 20), new Track("What New York Couples Fight About (Feat: Kurt Wagner)", 50), new Track("Undress Me Now", 26), new Track("Way Beyond", 4), new Track("Women Lose Weight (Feat: Slick Rick)", 76), new Track("Get Along (Feat: Pace Won)", 88), new Track("Public Displays of Affection", 15), new Track("The Great London Traffic Warden Massacre", 43), new Track("Slow Down (Instrumental)", 94), new Track("Otherwise (Instrumental)", 52), new Track("Aqualung (Instrumental)", 19), new Track("Sao Paulo (Instrumental)", 21), new Track("Charango (Feat: Pace Won) (Instrumental)", 32), new Track("What New York Couples Fight About (Instrumental)", 47), new Track("Undress Me Now (Instrumental)", 55), new Track("Way Beyond (Instrumental)", 81), new Track("Women Lose Weight (Feat: Slick Rick) (Instrumental)", 77), new Track("Get Along (Feat: Pace Won) (Instrumental)", 76), new Track("Public Displays Of Affection (Instrumental)", 35), new Track("The Great London Traffic Warden Massacre (Instrumental)", 58)); + private static final Album ALBUM_4 = new Album(ARTIST_1, "Shelter Song", new Track("Shelter Song", 99), new Track("Prisms", 87)); + private static final Album ALBUM_5 = new Album(ARTIST_2, "God Help The Girl", new Track("I Suppose That Was A Prayer", 30), new Track("Act of the Apostle", 33), new Track("I Dumped You First", 52), new Track("Pretty When The Wind Blows", 75), new Track("I Know I Have To Eat", 53), new Track("God Help the Girl", 34), new Track("The Psychiatrist Is In", 35), new Track("The God Of Music", 86), new Track("If You Could Speak", 48), new Track("The Catwalk Of The Dukes", 42), new Track("Perfection as a Hipster", 43), new Track("Fuck This Shit", 50), new Track("Pretty Eve in the Tub", 14), new Track("A loving Kind Of Boy", 36), new Track("What Do You Want This Band To Sound Like", 43), new Track("Come Monday Night", 50), new Track("Collective Idiocy", 68), new Track("I'm Not Rich", 90), new Track("I'll Have to Dance With Cassie", 6), new Track("Stalinist Russia", 14), new Track("Baby’s Just Waiting", 50), new Track("Partick Whistle", 54), new Track("Musician, Please Take Heed", 33), new Track("I Just Want Your Jeans", 21), new Track("Invisible", 72), new Track("The World's Last Cassette", 98), new Track("A Down and Dusky Blonde", 51), new Track("Dress Up In You", 17)); + private static final Album ALBUM_6 = new Album(ARTIST_2, "God Help The Girl sd (Original Motion Picture Soundtrack)"); + private static final Album ALBUM_7 = new Album(ARTIST_2, "Stills EP"); + private static final Album ALBUM_8 = new Album(ARTIST_3, "Echo Other", new Track("Tropic of Unicorn", 18), new Track("Four Three", 86), new Track("The Time", 36), new Track("Sunshine Briefly", 33), new Track("Elizabethland", 41), new Track("The Quiet Ambient", 21), new Track("Song of the See", 95), new Track("Mexicola", 36), new Track("Ghost Dirt", 49), new Track("Whistle", 2), new Track("Echo Other", 13), new Track("Endless Highway", 89)); + private static final Album ALBUM_9 = new Album(ARTIST_3, "Permanent Evolutions", new Track("Open Sky Experiment (St-244 Remix)", 11), new Track("Permanent Revolutions (Don Meers remix)", 14), new Track("Little Mexico", 2), new Track("How Many, For How Long (Morphodic Bliss Mix)", 59), new Track("Dark Ambient (am mix)", 53), new Track("Life and How to Do It", 19), new Track("For Angel (All India Radio vs. Don Meers Mix)", 24), new Track("Lo Fi Groovy", 67), new Track("Walking On A.I.R.", 47), new Track("Delhi Dub", 64), new Track("Pray To The TV Funk (Left Brain Mix)", 69), new Track("A Moment (TV Version)", 1), new Track("Old India", 4), new Track("The Long Goodbye", 79)); + private static final Album ALBUM_10 = new Album(ARTIST_3, "Film Musik", new Track("The Quiet Ambient", 7), new Track("Last Port Of Call", 17), new Track("Permanent Revolutions", 84), new Track("Sunshine Briefly", 76), new Track("Mexicola", 86), new Track("Evening Star", 97), new Track("Horse Groove", 30), new Track("Waukaringa", 95), new Track("Deady Boy", 67), new Track("The Time", 57), new Track("Doing Stuff", 70), new Track("Far Away (Instrumental)", 37), new Track("Harmonium Across The Sea", 34), new Track("Dry (film mix)", 22), new Track("Gunslinger 3", 29), new Track("Its Happy Time", 35)); + private static final Album ALBUM_11 = new Album(ARTIST_4, "Psyence Fiction", new Track("Guns Blazing (Drums Of Death Pt. 1)", 17), new Track("U.N.K.L.E. Main Title Theme", 80), new Track("Lonely Soul", 51), new Track("Getting Ahead In The Lucrative Field Of Artist Management", 49), new Track("Nursery Rhyme/ Breather", 9), new Track("Celestial Annihilation", 36), new Track("The Knock (Drums Of Death Pt. 2)", 13), new Track("Chaos", 51), new Track("Rabbit in Your Headlights", 49), new Track("Outro (Mandatory)", 21)); + private static final Album ALBUM_12 = new Album(ARTIST_4, "Never, Never, Land", new Track("Back And Forth", 79), new Track("Eye for an Eye", 59), new Track("In A State", 47), new Track("Safe In Mind (Please Get This Gun From Out My Face)", 99), new Track("I Need Something Stronger", 39), new Track("What Are You To Me?", 14), new Track("Panic Attack", 88), new Track("Invasion", 49), new Track("Reign", 91), new Track("Glow", 87), new Track("Inside", 76)); + private static final Album ALBUM_13 = new Album(ARTIST_5, "Black Sands", new Track("Prelude", 43), new Track("Kiara", 29), new Track("Kong", 0), new Track("Eyesdown", 97), new Track("El Toro", 98), new Track("We Could Forever", 18), new Track("1009", 27), new Track("All in Forms", 20), new Track("The Keeper", 90), new Track("Stay the Same", 88), new Track("Animals", 49), new Track("Black Sands", 14)); + private static final Album ALBUM_14 = new Album(ARTIST_5, "Days to Come", new Track("Intro", 68), new Track("Days To Come", 41), new Track("Between The Lines", 79), new Track("The Fever", 81), new Track("Ketto", 6), new Track("Nightlite feat. Bajka", 32), new Track("Transmission 94 (Parts 1 & 2)", 19), new Track("On Your Marks", 3), new Track("If You Stayed Over", 7), new Track("Walk In The Sky", 74), new Track("Recurring", 32)); + private static final Album ALBUM_15 = new Album(ARTIST_6, "Visions", new Track("Infinite ❤ Without Fulfillment", 37), new Track("Genesis", 39), new Track("Oblivion", 26), new Track("Eight", 65), new Track("Circumambient", 37), new Track("Vowels = Space and Time", 20), new Track("Visiting Statue", 54), new Track("Be a Body (侘寂)", 22), new Track("Colour Of Moonlight (Antiochus) (Ft. Doldrums)", 36), new Track("Symphonia IX (My Wait Is U)", 78), new Track("Nightmusic (Ft. Majical Cloudz)", 8), new Track("Skin", 44), new Track("Know the Way", 72)); + private static final Album ALBUM_16 = new Album(ARTIST_6, "Art Angels"); + private static final Album ALBUM_17 = new Album(ARTIST_7, "Mezzanine", new Track("Angel", 75), new Track("Risingson", 26), new Track("Teardrop", 93), new Track("Inertia Creeps", 65), new Track("Exchange", 76), new Track("Dissolved Girl", 87), new Track("Man Next Door", 50), new Track("Black Milk", 45), new Track("Mezzanine", 5), new Track("Group Four", 95), new Track("(Exchange)", 89)); + private static final Album ALBUM_18 = new Album(ARTIST_7, "Blue Lines", new Track("Safe From Harm", 99), new Track("One Love", 71), new Track("Blue Lines", 89), new Track("Be Thankful for What You've Got", 20), new Track("Five Man Army", 10), new Track("Unfinished Sympathy", 58), new Track("Daydreaming", 60), new Track("Lately", 27), new Track("Hymn Of The Big Wheel", 27)); + private static final Album ALBUM_19 = new Album(ARTIST_7, "Heligoland", new Track("Pray for Rain", 61), new Track("Babel", 26), new Track("Splitting the Atom", 37), new Track("Girl I Love You", 2), new Track("Psyche", 37), new Track("Flat of the Blade", 74), new Track("Paradise Circus", 11), new Track("Rush Minute", 53), new Track("Saturday Come Slow", 91), new Track("Atlas Air (Instrumental)", 41), new Track("Paradise Circus (Gui Boratto Remix)", 69), new Track("Fatalism (Ryuichi Sakamoto & Yukihiro Takahashi Remix)", 24), new Track("Girl I Love You (She is Danger Remix)", 7), new Track("Paradise Circus (Breakage's Tight Rope Remix)", 92)); + private static final Album[] ALL_ALBUMS = new Album[]{ALBUM_0, ALBUM_1, ALBUM_2, ALBUM_3, ALBUM_4, ALBUM_5, ALBUM_6, + ALBUM_7, ALBUM_8, ALBUM_9, ALBUM_10, ALBUM_11, ALBUM_12, ALBUM_13, ALBUM_14, ALBUM_15, ALBUM_16, ALBUM_17, + ALBUM_18, ALBUM_19 + }; +} diff --git a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java new file mode 100644 index 0000000..6862ed9 --- /dev/null +++ b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java @@ -0,0 +1,28 @@ +package ru.spbau.bachelor2015.veselov.hw08; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class SecondPartTasksTest { + + @Test + public void testFindQuotes() { + fail(); + } + + @Test + public void testPiDividedBy4() { + fail(); + } + + @Test + public void testFindPrinter() { + fail(); + } + + @Test + public void testCalculateGlobalOrder() { + fail(); + } +} From eedd2325ed9523969b0624bec2bdd0d2afb7bd5d Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 12 Nov 2016 18:43:52 +0300 Subject: [PATCH 2/9] Solve first part. --- .../veselov/hw08/FirstPartTasks.java | 59 ++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java index 1f94820..eced0db 100644 --- a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java @@ -1,8 +1,9 @@ package ru.spbau.bachelor2015.veselov.hw08; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; +import java.util.function.Function; +import java.util.function.ToDoubleFunction; +import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -12,64 +13,92 @@ private FirstPartTasks() {} // Список названий альбомов public static List allNames(Stream albums) { - throw new UnsupportedOperationException(); + return albums.map(Album::getName).collect(Collectors.toList()); } // Список названий альбомов, отсортированный лексикографически по названию public static List allNamesSorted(Stream albums) { - throw new UnsupportedOperationException(); + return albums.map(Album::getName).sorted().collect(Collectors.toList()); } // Список треков, отсортированный лексикографически по названию, включающий все треки альбомов из 'albums' public static List allTracksSorted(Stream albums) { - throw new UnsupportedOperationException(); + return albums.flatMap(a -> a.getTracks().stream()).map(Track::getName).sorted().collect(Collectors.toList()); } // Список альбомов, в которых есть хотя бы один трек с рейтингом более 95, отсортированный по названию public static List sortedFavorites(Stream s) { - throw new UnsupportedOperationException(); + return s.filter(a -> a.getTracks() + .stream() + .anyMatch(t -> t.getRating() > 95)) + .sorted(Comparator.comparing(Album::getName)) + .collect(Collectors.toList()); } // Сгруппировать альбомы по артистам public static Map> groupByArtist(Stream albums) { - throw new UnsupportedOperationException(); + return albums.collect(Collectors.groupingBy(Album::getArtist)); } // Сгруппировать альбомы по артистам (в качестве значения вместо объекта 'Artist' использовать его имя) public static Map> groupByArtistMapName(Stream albums) { - throw new UnsupportedOperationException(); + return albums.collect(Collectors.groupingBy(Album::getArtist, + Collectors.mapping(Album::getName, + Collectors.toList()))); } // Число повторяющихся альбомов в потоке public static long countAlbumDuplicates(Stream albums) { - throw new UnsupportedOperationException(); + return albums.collect(Collectors.toMap(Function.identity(), a -> 1, (a, b) -> a + b)) + .values() + .stream() + .filter(n -> n > 1) + .count(); } // Альбом, в котором максимум рейтинга минимален // (если в альбоме нет ни одного трека, считать, что максимум рейтинга в нем --- 0) public static Optional minMaxRating(Stream albums) { - throw new UnsupportedOperationException(); + return albums.collect(Collectors.toMap(Function.identity(), + a -> a.getTracks() + .stream() + .mapToInt(Track::getRating) + .reduce(Integer::max) + .orElse(0))) + .entrySet() + .stream() + .min(Comparator.comparingInt(Map.Entry::getValue)) + .map(Map.Entry::getKey); } // Список альбомов, отсортированный по убыванию среднего рейтинга его треков (0, если треков нет) public static List sortByAverageRating(Stream albums) { - throw new UnsupportedOperationException(); + return albums.collect(Collectors.toMap(Function.identity(), + a -> a.getTracks() + .stream() + .collect(Collectors.averagingInt(Track::getRating)))) + .entrySet() + .stream() + .sorted(Comparator.comparingDouble((ToDoubleFunction) e -> (Double) e.getValue()) + .reversed()) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); } // Произведение всех чисел потока по модулю 'modulo' // (все числа от 0 до 10000) public static int moduloProduction(IntStream stream, int modulo) { - throw new UnsupportedOperationException(); + return stream.reduce(1, (a, b) -> (a * b) % modulo); } // Вернуть строку, состояющую из конкатенаций переданного массива, и окруженную строками "<", ">" // см. тесты public static String joinTo(String... strings) { - throw new UnsupportedOperationException(); + return Arrays.stream(strings).collect(Collectors.joining(", ", "<", ">")); } // Вернуть поток из объектов класса 'clazz' public static Stream filterIsInstance(Stream s, Class clazz) { - throw new UnsupportedOperationException(); + return s.filter(clazz::isInstance).map(o -> (R) o); } } From 752a77b081e6d6819b6338f835625dd43318f441 Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 12 Nov 2016 19:47:34 +0300 Subject: [PATCH 3/9] Implement piDividedBy4 and add test for this method. --- .../bachelor2015/veselov/hw08/SecondPartTasks.java | 12 +++++++++++- .../veselov/hw08/SecondPartTasksTest.java | 7 +++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java index d0250a5..b678964 100644 --- a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java @@ -2,6 +2,9 @@ import java.util.List; import java.util.Map; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.Stream; public final class SecondPartTasks { @@ -16,7 +19,14 @@ public static List findQuotes(List paths, CharSequence sequence) // Стрелок атакует мишень и каждый раз попадает в произвольную точку квадрата. // Надо промоделировать этот процесс с помощью класса java.util.Random и посчитать, какова вероятность попасть в мишень. public static double piDividedBy4() { - throw new UnsupportedOperationException(); + Random generator = new Random(); + return Stream.generate(() -> + { + if (Math.hypot(generator.nextDouble(), generator.nextDouble()) <= 1.0) return 1; + else return 0; + }) + .limit(1000000) + .collect(Collectors.averagingInt(a -> a)); } // Дано отображение из имени автора в список с содержанием его произведений. diff --git a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java index 6862ed9..ee27458 100644 --- a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java +++ b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java @@ -2,7 +2,9 @@ import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.piDividedBy4; public class SecondPartTasksTest { @@ -13,7 +15,8 @@ public void testFindQuotes() { @Test public void testPiDividedBy4() { - fail(); + // Probability < 10^(-86) + assertTrue(Math.abs(piDividedBy4() - Math.PI / 4.0) < 0.01); } @Test From d359b19b63efd9e05d598599da05b63d22d852c4 Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 12 Nov 2016 21:09:31 +0300 Subject: [PATCH 4/9] Implement calculateGlobalOrder and add test for this method. --- .../veselov/hw08/SecondPartTasks.java | 10 +++++++++- .../veselov/hw08/SecondPartTasksTest.java | 20 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java index b678964..147dc3f 100644 --- a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java @@ -1,5 +1,6 @@ package ru.spbau.bachelor2015.veselov.hw08; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; @@ -38,6 +39,13 @@ public static String findPrinter(Map> compositions) { // Вы крупный поставщик продуктов. Каждая торговая сеть делает вам заказ в виде Map<Товар, Количество>. // Необходимо вычислить, какой товар и в каком количестве надо поставить. public static Map calculateGlobalOrder(List> orders) { - throw new UnsupportedOperationException(); + return orders.stream().reduce(new HashMap<>(), + (acc, map) -> { + map.entrySet() + .forEach(e -> acc.merge(e.getKey(), + e.getValue(), + (a, b) -> a + b)); + return acc; + }); } } diff --git a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java index ee27458..5a6a2ae 100644 --- a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java +++ b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java @@ -1,9 +1,14 @@ package ru.spbau.bachelor2015.veselov.hw08; +import com.google.common.collect.ImmutableMap; import org.junit.Test; +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.calculateGlobalOrder; import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.piDividedBy4; public class SecondPartTasksTest { @@ -26,6 +31,19 @@ public void testFindPrinter() { @Test public void testCalculateGlobalOrder() { - fail(); + assertEquals( + ImmutableMap.of("A", 10, + "B", 9, + "C", 5), + calculateGlobalOrder(Arrays.asList( + ImmutableMap.of("A", 5, + "B", 3), + ImmutableMap.of("A", 3, + "B", 6, + "C", 4), + ImmutableMap.of("A", 2, + "C", 1) + )) + ); } } From 2bcdef1fd8989546985f2fb4e953399834789ff0 Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 12 Nov 2016 21:50:15 +0300 Subject: [PATCH 5/9] Implement findPrinter and add test for this method. --- .../bachelor2015/veselov/hw08/SecondPartTasks.java | 14 +++++++++----- .../veselov/hw08/SecondPartTasksTest.java | 10 +++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java index 147dc3f..83e08fa 100644 --- a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java @@ -1,9 +1,6 @@ package ru.spbau.bachelor2015.veselov.hw08; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -33,7 +30,14 @@ public static double piDividedBy4() { // Дано отображение из имени автора в список с содержанием его произведений. // Надо вычислить, чья общая длина произведений наибольшая. public static String findPrinter(Map> compositions) { - throw new UnsupportedOperationException(); + return compositions.entrySet() + .stream() + .collect(Collectors.maxBy( + Comparator.comparingInt(e -> e.getValue() + .stream() + .collect(Collectors.summingInt(String::length))))) + .get() + .getKey(); } // Вы крупный поставщик продуктов. Каждая торговая сеть делает вам заказ в виде Map<Товар, Количество>. diff --git a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java index 5a6a2ae..6a05b8f 100644 --- a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java +++ b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java @@ -9,6 +9,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.calculateGlobalOrder; +import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.findPrinter; import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.piDividedBy4; public class SecondPartTasksTest { @@ -26,7 +27,14 @@ public void testPiDividedBy4() { @Test public void testFindPrinter() { - fail(); + assertEquals( + "B", + findPrinter(ImmutableMap.of( + "A", Arrays.asList("Ababa", "acaba", "c"), + "B", Arrays.asList("asdasd", "afasdfsadfsaddfsadfasdfasd"), + "C", Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h") + )) + ); } @Test From f5b9af96f36fed9e8b192075b60f0e3bf7bf2a66 Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 12 Nov 2016 21:54:08 +0300 Subject: [PATCH 6/9] Simplify minMaxRating method. --- .../veselov/hw08/FirstPartTasks.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java index eced0db..de71288 100644 --- a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java @@ -59,16 +59,13 @@ public static long countAlbumDuplicates(Stream albums) { // Альбом, в котором максимум рейтинга минимален // (если в альбоме нет ни одного трека, считать, что максимум рейтинга в нем --- 0) public static Optional minMaxRating(Stream albums) { - return albums.collect(Collectors.toMap(Function.identity(), - a -> a.getTracks() - .stream() - .mapToInt(Track::getRating) - .reduce(Integer::max) - .orElse(0))) - .entrySet() - .stream() - .min(Comparator.comparingInt(Map.Entry::getValue)) - .map(Map.Entry::getKey); + return albums.collect(Collectors.minBy( + Comparator.comparingInt(a -> a.getTracks() + .stream() + .mapToInt(Track::getRating) + .reduce(Integer::max) + .orElse(0)) + )); } // Список альбомов, отсортированный по убыванию среднего рейтинга его треков (0, если треков нет) From 39b56bed79b9d3f5fc6ae74625c6c467a4d4b283 Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 12 Nov 2016 21:58:30 +0300 Subject: [PATCH 7/9] Simplify sortByAverageRating method. --- .../bachelor2015/veselov/hw08/FirstPartTasks.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java index de71288..0b1d404 100644 --- a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/FirstPartTasks.java @@ -70,15 +70,11 @@ public static Optional minMaxRating(Stream albums) { // Список альбомов, отсортированный по убыванию среднего рейтинга его треков (0, если треков нет) public static List sortByAverageRating(Stream albums) { - return albums.collect(Collectors.toMap(Function.identity(), - a -> a.getTracks() - .stream() - .collect(Collectors.averagingInt(Track::getRating)))) - .entrySet() - .stream() - .sorted(Comparator.comparingDouble((ToDoubleFunction) e -> (Double) e.getValue()) + return albums.sorted(Comparator.comparingDouble( + (ToDoubleFunction) a -> a.getTracks() + .stream() + .collect(Collectors.averagingInt(Track::getRating))) .reversed()) - .map(Map.Entry::getKey) .collect(Collectors.toList()); } From b581c40c40a0faff7cfde71c605af89bb72d12e6 Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 12 Nov 2016 22:14:24 +0300 Subject: [PATCH 8/9] Implement findQuotes and add test for this method. --- .../bachelor2015/veselov/hw08/SecondPartTasks.java | 14 +++++++++++++- .../veselov/hw08/SecondPartTasksTest.java | 8 +++----- 08-Streams/test/test1 | 3 +++ 08-Streams/test/test2 | 3 +++ 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 08-Streams/test/test1 create mode 100644 08-Streams/test/test2 diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java index 83e08fa..fdb696e 100644 --- a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java @@ -1,5 +1,8 @@ package ru.spbau.bachelor2015.veselov.hw08; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -10,7 +13,16 @@ private SecondPartTasks() {} // Найти строки из переданных файлов, в которых встречается указанная подстрока. public static List findQuotes(List paths, CharSequence sequence) { - throw new UnsupportedOperationException(); + return paths.stream() + .flatMap(s -> { + try { + return Files.lines(Paths.get(s)); + } catch (IOException e) { + return Stream.of(); + } + }) + .filter(s -> s.contains(sequence)) + .collect(Collectors.toList()); } // В квадрат с длиной стороны 1 вписана мишень. diff --git a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java index 6a05b8f..dae1118 100644 --- a/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java +++ b/08-Streams/src/test/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasksTest.java @@ -7,16 +7,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.calculateGlobalOrder; -import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.findPrinter; -import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.piDividedBy4; +import static ru.spbau.bachelor2015.veselov.hw08.SecondPartTasks.*; public class SecondPartTasksTest { @Test public void testFindQuotes() { - fail(); + assertEquals(Arrays.asList("AtestA", "BtestB", "AtestA", "BtestB"), + findQuotes(Arrays.asList("test/test1", "test/test2"), "test")); } @Test diff --git a/08-Streams/test/test1 b/08-Streams/test/test1 new file mode 100644 index 0000000..22c1ed0 --- /dev/null +++ b/08-Streams/test/test1 @@ -0,0 +1,3 @@ +AtestA +AtsetA +BtestB diff --git a/08-Streams/test/test2 b/08-Streams/test/test2 new file mode 100644 index 0000000..d63bba8 --- /dev/null +++ b/08-Streams/test/test2 @@ -0,0 +1,3 @@ +AtestA +BtestB +BtsetB From 969e6a27827f03e04e35aebe0caa0db231072ccb Mon Sep 17 00:00:00 2001 From: Ivan Veselov Date: Sat, 19 Nov 2016 13:08:44 +0300 Subject: [PATCH 9/9] Replace exception ignoring with its rethrowing. --- .../ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java index fdb696e..73e23f1 100644 --- a/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java +++ b/08-Streams/src/main/java/ru/spbau/bachelor2015/veselov/hw08/SecondPartTasks.java @@ -18,7 +18,7 @@ public static List findQuotes(List paths, CharSequence sequence) try { return Files.lines(Paths.get(s)); } catch (IOException e) { - return Stream.of(); + throw new RuntimeException(e); } }) .filter(s -> s.contains(sequence))