├── .gitignore ├── LICENSE ├── README.md ├── TASKS.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── labs ├── sem1 │ ├── lab1 │ │ ├── Dop.java │ │ ├── Int.java │ │ └── Main.java │ ├── lab10 │ │ ├── DebugStack.java │ │ ├── Dop.java │ │ ├── Logger.java │ │ ├── Main.java │ │ ├── Stack.java │ │ ├── SynchroStack.java │ │ ├── SynchroStackFast.java │ │ └── results │ │ │ ├── DebugStack.csv │ │ │ ├── SynchroStack.csv │ │ │ └── SynchroStackFast.csv │ ├── lab2 │ │ ├── Dop.java │ │ ├── Main.java │ │ └── Matrix.java │ ├── lab3 │ │ ├── Dop.java │ │ ├── FourPartMatrix.java │ │ ├── Main.java │ │ ├── Matrix.java │ │ ├── MatrixException.java │ │ └── SquareMatrix.java │ ├── lab4 │ │ ├── Dop.java │ │ ├── Main.java │ │ └── SortedIntegerList.java │ ├── lab5 │ │ ├── Dop.java │ │ ├── IMatrix.java │ │ ├── Main.java │ │ ├── Matrix.java │ │ ├── SparseMatrix.java │ │ ├── SquareMatrix.java │ │ └── UsualMatrix.java │ ├── lab6 │ │ ├── task1 │ │ │ ├── Dop.java │ │ │ ├── FormattedInput.java │ │ │ └── Main.java │ │ └── task2 │ │ │ ├── EncodingConverter.java │ │ │ ├── input.txt │ │ │ └── output.txt │ ├── lab7 │ │ ├── Dop.java │ │ ├── Main.java │ │ ├── Settings.java │ │ ├── library.csv │ │ ├── settings.bin │ │ └── settings.txt │ ├── lab8 │ │ ├── Dop.java │ │ ├── Main.java │ │ ├── MeasureTime.java │ │ ├── ParallelMatrixProduct.java │ │ └── ParallelVectorMatrixProduct.java │ └── lab9 │ │ ├── Deadlock.java │ │ ├── Dop.java │ │ └── docs │ │ ├── harry-potter.txt │ │ ├── hitchhikers-guide.txt │ │ └── war-and-peace.txt └── sem2 │ ├── lab11 │ ├── Client.java │ ├── Server.java │ └── dop │ │ ├── Client.java │ │ └── Server.java │ └── lab12 │ ├── Client.java │ ├── Server.java │ └── dop │ ├── Client.java │ └── Server.java ├── servlets ├── lab13 │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── dev │ │ │ └── potat │ │ │ └── servlets │ │ │ └── lab13 │ │ │ ├── AddressBook.java │ │ │ ├── AddressBookStore.java │ │ │ ├── Contact.java │ │ │ ├── DeleteServlet.java │ │ │ ├── UpdateServlet.java │ │ │ └── ViewServlet.java │ │ └── webapp │ │ ├── WEB-INF │ │ └── web.xml │ │ ├── form_delete.jsp │ │ ├── form_update.jsp │ │ ├── index.jsp │ │ ├── info.jsp │ │ └── view.jsp ├── lab15 │ ├── build.gradle │ ├── db.json │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ ├── src │ │ └── main │ │ │ ├── java │ │ │ └── dev │ │ │ │ └── potat │ │ │ │ └── servlets │ │ │ │ └── lab15 │ │ │ │ ├── AdBoard.java │ │ │ │ ├── AdBoardStore.java │ │ │ │ ├── AddServlet.java │ │ │ │ ├── Advertisement.java │ │ │ │ ├── LoginServlet.java │ │ │ │ ├── LogoutServlet.java │ │ │ │ ├── User.java │ │ │ │ ├── UserStore.java │ │ │ │ ├── ViewServlet.java │ │ │ │ └── VoteServlet.java │ │ │ └── webapp │ │ │ ├── WEB-INF │ │ │ └── web.xml │ │ │ ├── add.jsp │ │ │ ├── info.jsp │ │ │ ├── login.jsp │ │ │ └── view.jsp │ └── users.json └── lab16 │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ ├── main │ ├── java │ │ └── dev │ │ │ └── potat │ │ │ └── servlets │ │ │ └── lab16 │ │ │ ├── ListItem.java │ │ │ ├── ListServlet.java │ │ │ └── ListStore.java │ └── webapp │ │ ├── WEB-INF │ │ └── web.xml │ │ └── view.jsp │ └── test │ └── java │ └── dev │ └── potat │ └── servlets │ └── lab16 │ └── TestSaveAndLoad.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | compile/ 4 | **/build/ 5 | out/ 6 | 7 | # Log file 8 | *.log 9 | 10 | # BlueJ files 11 | *.ctxt 12 | 13 | # Mobile Tools for Java (J2ME) 14 | .mtj.tmp/ 15 | 16 | # Package Files # 17 | *.jar 18 | *.war 19 | *.nar 20 | *.ear 21 | *.zip 22 | *.tar.gz 23 | *.rar 24 | 25 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 26 | hs_err_pid* 27 | 28 | # vscode files 29 | .vscode/ 30 | 31 | # Gradle 32 | .gradle 33 | !gradle-wrapper.jar 34 | 35 | # IntelliJ 36 | .idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Cyber Potato 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `SUAI` Java Labs 2 | 3 | A repository for learning Java in SUAI university 4 | 5 | ## Useful links 6 | 7 | File with tasks for laboratory works: [Google Docs](https://docs.google.com/document/d/1TUxcZclZ6zkdXw5X98irdYX5vn2FBd_-oBdZ2_1vPT0) 8 | My formatted Lab tasks: [TASKS.md](TASKS.md) 9 | 10 | ## How to compile and run 11 | 12 | 1. Clone this repository 13 | ```bash 14 | git clone https://github.com/cypotat/Java-Labs.git 15 | cd Java-Labs/src 16 | ``` 17 | 2. Compile the specific lab 18 | 19 | ```bash 20 | javac labs/sem1/lab1/*.java 21 | ``` 22 | 23 | 3. Run it! 24 | ```bash 25 | java labs.sem1.lab1.Main 26 | ``` 27 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potat-dev/JavaLabs/057fd364ee1d4a95e1530427c24afa630494f671/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /labs/sem1/lab1/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab1; 2 | 3 | // Доп: 4 | // Создать класс Circle для работы с фигурой круг 5 | // Мтоды: bool isInside(int x, y) и zoom(int amount) 6 | 7 | public class Dop { 8 | public static void main(String[] args) { 9 | Circle circle = new Circle(0, 0, 10); 10 | 11 | System.out.println(circle.isInside(0, 0)); 12 | System.out.println(circle.isInside(0, 10)); 13 | 14 | System.out.println(circle.isInside(0, 12)); 15 | 16 | circle.zoom(2); 17 | System.out.println(circle.isInside(0, 12)); 18 | } 19 | } 20 | 21 | class Circle { 22 | private int x, y, r; 23 | 24 | public Circle() { 25 | x = 0; 26 | y = 0; 27 | r = 0; 28 | } 29 | 30 | public Circle(int x, int y, int r) { 31 | this.x = x; 32 | this.y = y; 33 | this.r = r; 34 | } 35 | 36 | public boolean isInside(int x, int y) { 37 | return Math.sqrt(Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2)) <= r; 38 | } 39 | 40 | public void zoom(int amount) { 41 | r *= amount; 42 | } 43 | } -------------------------------------------------------------------------------- /labs/sem1/lab1/Int.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab1; 2 | 3 | public class Int { 4 | private int value; 5 | 6 | public Int() { 7 | this.value = 0; 8 | } 9 | 10 | public String toString() { 11 | return String.valueOf(this.value); 12 | } 13 | 14 | public void increment() { 15 | this.value++; 16 | } 17 | 18 | public void decrement() { 19 | this.value--; 20 | } 21 | 22 | public void add(Int other) { 23 | this.value += other.value; 24 | } 25 | 26 | public void subtract(Int other) { 27 | this.value -= other.value; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /labs/sem1/lab1/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab1; 2 | 3 | // Напишите класс, реализующий правильные с объектно-ориентированной точки зрения целые числа. При 4 | // создании нового объекта должно создаваться число, равное нулю. В классе должны быть определены: 5 | 6 | // - методы increment() и decrement(), соответственно увеличивающие и уменьшающие число на 1 7 | // - методы add(Int n) и subtract(Int n), увеличивающие и уменьшающие число на n 8 | // - метод toString() 9 | 10 | // - в методах add и subtract передаются значения типа Int (с большой буквы), а не стандартный int 11 | // - применить инкриминирование 1000 раз - плохой вариант 12 | // - для сдачи основного задания нельзя придумывать свои методы и конструкторы, нужно использовать 13 | // указанные выше 14 | 15 | // Напишите наиболее короткую программу, которая используя только класс Int, выводит на экран число 16 | // 1000. Программа должна быть чисто объектно-ориентированной. В частности, в ней нельзя 17 | // использовать оператор присваивания. 18 | 19 | public class Main { 20 | public static void main(String[] args) { 21 | test1(); 22 | } 23 | 24 | public static void test1() { 25 | Int a = new Int(); 26 | a.increment(); 27 | 28 | for (int i = 0; i < 7; i++) { 29 | a.add(a); 30 | System.out.println(a); 31 | } 32 | 33 | for (int i = 0; i < 3; i++) { 34 | a.decrement(); 35 | } 36 | 37 | System.out.println(a); 38 | 39 | for (int i = 0; i < 3; i++) { 40 | a.add(a); 41 | System.out.println(a); 42 | } 43 | } 44 | 45 | public static void test2() { 46 | Int a = new Int(); 47 | a.increment(); 48 | 49 | for (int i = 0; i < 10; i++) { 50 | a.add(a); 51 | System.out.println(a); 52 | } 53 | 54 | Int b = new Int(); 55 | 56 | for (int i = 0; i < 3; i++) { 57 | b.increment(); 58 | } 59 | 60 | for (int i = 0; i < 3; i++) { 61 | b.add(b); 62 | } 63 | 64 | a.subtract(b); 65 | System.out.println(a); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /labs/sem1/lab10/DebugStack.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab10; 2 | 3 | public class DebugStack extends Stack { 4 | protected boolean debug = false; 5 | Logger logger; 6 | 7 | public void setLogger(Object logger) { 8 | if (logger instanceof Logger) { 9 | this.logger = (Logger) logger; 10 | debug = true; 11 | } else { 12 | debug = false; 13 | } 14 | } 15 | 16 | public void push(int i) { 17 | if (debug) 18 | synchronized (logger) { 19 | logger.print("Push START"); 20 | } 21 | super.push(i); 22 | if (debug) 23 | synchronized (logger) { 24 | logger.print("Push END"); 25 | } 26 | } 27 | 28 | public int pop() { 29 | if (debug) 30 | synchronized (logger) { 31 | logger.print("Pop START"); 32 | } 33 | int i = super.pop(); 34 | if (debug) 35 | synchronized (logger) { 36 | logger.print("Pop END"); 37 | } 38 | return i; 39 | } 40 | 41 | public boolean equals(Object o) { 42 | if (debug) 43 | synchronized (logger) { 44 | logger.print("Equals START"); 45 | } 46 | boolean b = super.equals(o); 47 | if (debug) 48 | synchronized (logger) { 49 | logger.print("Equals END"); 50 | } 51 | return b; 52 | } 53 | 54 | public String toString() { 55 | if (debug) 56 | synchronized (logger) { 57 | logger.print("toString START"); 58 | } 59 | String s = super.toString(); 60 | if (debug) 61 | synchronized (logger) { 62 | logger.print("toString END"); 63 | } 64 | return s; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /labs/sem1/lab10/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab10; 2 | 3 | // Доп: 4 | // Реализовать класс iterativeParallelism, который будет обрабатывать списки в несколько потоков 5 | // должны быть реализованы следующие методы: 6 | 7 | // minimum(threads, list, comparator) - первый минимум 8 | // maximum(threads, list, comparator) - первый максимум 9 | // all(threads, list, predicate) - проверка, что все элементы списка удовлетворяют предикату 10 | // any(threads, list, predicate) - проверка, что есть элемент списка, удовлетворяющий предикату 11 | 12 | // Во все функции передается параметр threads - сколько потоков надо использовать при вычислении. Вы 13 | // можете рассчитывать, что число потоков не велико. Не следует рассчитывать на то, что переданные 14 | // компараторы, предикаты и функции работают быстро. 15 | 16 | import java.util.List; 17 | import java.util.concurrent.atomic.AtomicInteger; 18 | import java.util.function.Predicate; 19 | 20 | public class Dop { 21 | public static void main(String[] args) { 22 | List list = List.of(1, 2, 3, 4, -5, 6, 7, 8, -9, 10, 100); 23 | 24 | System.out.println(iterativeParallelism.minimum(3, list)); 25 | System.out.println(iterativeParallelism.maximum(3, list)); 26 | 27 | System.out.println(iterativeParallelism.all(3, list, x -> x > 0)); 28 | System.out.println(iterativeParallelism.any(3, list, x -> x < 0)); 29 | } 30 | } 31 | 32 | class iterativeParallelism { 33 | public static Integer minimum(Integer threadsCount, List values) { 34 | AtomicInteger currentMin = new AtomicInteger(Integer.MAX_VALUE); 35 | 36 | // create threads (pass currentMin to each thread as global variable) 37 | Thread[] threads = new Thread[threadsCount]; 38 | 39 | for (int i = 0; i < threadsCount; i++) { 40 | int startIdx = i * values.size() / threadsCount; 41 | int endIdx = (i + 1) * values.size() / threadsCount; 42 | 43 | threads[i] = new Thread(() -> { 44 | for (int j = startIdx; j < endIdx; j++) { 45 | if (values.get(j) < currentMin.get()) { 46 | currentMin.set(values.get(j)); 47 | } 48 | } 49 | }); 50 | } 51 | 52 | // start threads 53 | for (int i = 0; i < threadsCount; i++) { 54 | threads[i].start(); 55 | } 56 | 57 | // wait for threads to finish 58 | for (int i = 0; i < threadsCount; i++) { 59 | try { 60 | threads[i].join(); 61 | } catch (InterruptedException e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | 66 | return currentMin.get(); 67 | } 68 | 69 | public static Integer maximum(Integer threadsCount, List values) { 70 | AtomicInteger currentMax = new AtomicInteger(Integer.MIN_VALUE); 71 | 72 | // create threads (pass currentMax to each thread as global variable) 73 | Thread[] threads = new Thread[threadsCount]; 74 | 75 | for (int i = 0; i < threadsCount; i++) { 76 | int startIdx = i * values.size() / threadsCount; 77 | int endIdx = (i + 1) * values.size() / threadsCount; 78 | 79 | threads[i] = new Thread(() -> { 80 | for (int j = startIdx; j < endIdx; j++) { 81 | if (values.get(j) > currentMax.get()) { 82 | currentMax.set(values.get(j)); 83 | } 84 | } 85 | }); 86 | } 87 | 88 | // start threads 89 | for (int i = 0; i < threadsCount; i++) { 90 | threads[i].start(); 91 | } 92 | 93 | // wait for threads to finish 94 | for (int i = 0; i < threadsCount; i++) { 95 | try { 96 | threads[i].join(); 97 | } catch (InterruptedException e) { 98 | e.printStackTrace(); 99 | } 100 | } 101 | 102 | return currentMax.get(); 103 | } 104 | 105 | public static Boolean all( 106 | Integer threadsCount, List values, Predicate predicate) { 107 | AtomicInteger currentResult = new AtomicInteger(1); 108 | 109 | // create threads (pass currentResult to each thread as global variable) 110 | Thread[] threads = new Thread[threadsCount]; 111 | 112 | for (int i = 0; i < threadsCount; i++) { 113 | int startIdx = i * values.size() / threadsCount; 114 | int endIdx = (i + 1) * values.size() / threadsCount; 115 | 116 | threads[i] = new Thread(() -> { 117 | for (int j = startIdx; j < endIdx; j++) { 118 | if (!predicate.test(values.get(j))) { 119 | currentResult.set(0); 120 | } 121 | } 122 | }); 123 | } 124 | 125 | // start threads 126 | for (int i = 0; i < threadsCount; i++) { 127 | threads[i].start(); 128 | } 129 | 130 | // wait for threads to finish 131 | for (int i = 0; i < threadsCount; i++) { 132 | try { 133 | threads[i].join(); 134 | } catch (InterruptedException e) { 135 | e.printStackTrace(); 136 | } 137 | } 138 | 139 | return currentResult.get() == 1; 140 | } 141 | 142 | public static Boolean any( 143 | Integer threadsCount, List values, Predicate predicate) { 144 | AtomicInteger currentResult = new AtomicInteger(0); 145 | 146 | // create threads (pass currentResult to each thread as global variable) 147 | Thread[] threads = new Thread[threadsCount]; 148 | 149 | for (int i = 0; i < threadsCount; i++) { 150 | int startIdx = i * values.size() / threadsCount; 151 | int endIdx = (i + 1) * values.size() / threadsCount; 152 | 153 | threads[i] = new Thread(() -> { 154 | for (int j = startIdx; j < endIdx; j++) { 155 | if (predicate.test(values.get(j))) { 156 | currentResult.set(1); 157 | } 158 | } 159 | }); 160 | } 161 | 162 | // start threads 163 | for (int i = 0; i < threadsCount; i++) { 164 | threads[i].start(); 165 | } 166 | 167 | // wait for threads to finish 168 | for (int i = 0; i < threadsCount; i++) { 169 | try { 170 | threads[i].join(); 171 | } catch (InterruptedException e) { 172 | e.printStackTrace(); 173 | } 174 | } 175 | 176 | return currentResult.get() == 1; 177 | } 178 | } -------------------------------------------------------------------------------- /labs/sem1/lab10/Logger.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab10; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Paths; 6 | 7 | public class Logger { 8 | StringBuilder sb; 9 | String[] row; 10 | 11 | public Logger(int threadsCount) { 12 | sb = new StringBuilder(); 13 | // header of the CSV file 14 | row = new String[threadsCount + 1]; 15 | row[0] = "main"; 16 | for (int i = 1; i < row.length; i++) { 17 | row[i] = "Thread " + (i - 1); 18 | } 19 | // append header to the string 20 | sb.append(String.join(",", row) + "\n"); 21 | // empty row for next lines 22 | for (int i = 0; i < row.length; i++) { 23 | row[i] = "\"\""; 24 | } 25 | } 26 | 27 | public void print(String s) { 28 | // print s at the column of the current thread (other columns should be empty) 29 | // get current thread id from "Thread 0" -> 1 (main -> 0) 30 | String threadName = Thread.currentThread().getName(); 31 | int threadId = (threadName.equals("main")) ? 0 : Integer.parseInt(threadName.split(" ")[1]) + 1; 32 | // add s to the its column and append to the string 33 | row[threadId] = s; 34 | sb.append(String.join(",", row) + "\n"); 35 | // empty row for next lines 36 | row[threadId] = "\"\""; 37 | } 38 | 39 | public void writeFile(String filename) { 40 | // if file or folder doesn't exist, create it 41 | try { 42 | if (!Files.exists(Paths.get(filename))) { 43 | Files.createDirectories(Paths.get(filename).getParent()); 44 | Files.createFile(Paths.get(filename)); 45 | } 46 | // write the string to the file 47 | Files.write(Paths.get(filename), sb.toString().getBytes()); 48 | } catch (IOException e) { 49 | e.printStackTrace(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /labs/sem1/lab10/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab10; 2 | 3 | // Написать класс стек на основе связного списка (классом LinkedList пользоваться нельзя) с методами: 4 | // - модифицирующими: void push(int), int pop() 5 | // - читающими: equals(), toString() 6 | 7 | // Написать две реализации: 8 | // - SynchroStack - со стеком одновременно работать может только один поток 9 | // - SynchroStackFast - со стеком одновременно может работать либо один модифицирующий поток, либо несколько читающих потоков 10 | 11 | // Класс должен быть пригоден к использованию в многопоточных программах 12 | // В main с помощью замеров времени показать преимущество SynchroStackFast при работе в многопоточной программе. 13 | 14 | public class Main { 15 | public static void main(String[] args) { 16 | // classes to benchmark 17 | Class[] classes = { 18 | Stack.class, DebugStack.class, SynchroStack.class, SynchroStackFast.class }; 19 | 20 | int threadsPerMethod = 24; // threads per method 21 | int itersPerMethod = 1000; // iterations per method 22 | 23 | // logs file path 24 | String logsPath = "src/labs/sem1/lab10/results/%s.csv"; 25 | 26 | // initial size of stacks (to avoid empty stack errors) 27 | int initialSize = itersPerMethod * threadsPerMethod; 28 | 29 | // create stacks of each class 30 | Stack[] stacks = new Stack[classes.length]; 31 | for (int i = 0; i < classes.length; i++) { 32 | try { 33 | stacks[i] = (Stack) classes[i].getConstructor().newInstance(); 34 | for (int j = 0; j < initialSize; j++) { 35 | stacks[i].push(j); 36 | } 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | } 41 | 42 | // print type of stacks 43 | for (Stack stack : stacks) { 44 | Runnable[] methods = { 45 | () -> { // push (write operation) 46 | for (int i = 0; i < itersPerMethod; i++) { 47 | stack.push(i); 48 | } 49 | }, 50 | () -> { // pop (write operation) 51 | for (int i = 0; i < itersPerMethod; i++) { 52 | stack.pop(); 53 | } 54 | }, 55 | () -> { // equals (read operation, light) 56 | for (int i = 0; i < itersPerMethod * 20; i++) { 57 | stack.equals(stack); 58 | } 59 | }, 60 | () -> { // toString (read operation, heavy) 61 | for (int i = 0; i < itersPerMethod / 5; i++) { 62 | stack.toString(); 63 | } 64 | } 65 | }; 66 | 67 | // create threads 68 | Thread[] threads = new Thread[methods.length * threadsPerMethod]; 69 | for (int i = 0; i < methods.length; i++) { 70 | for (int j = 0; j < threadsPerMethod; j++) { 71 | int index = i * threadsPerMethod + j; 72 | threads[index] = new Thread(methods[i]); 73 | threads[index].setName("Thread " + index); 74 | } 75 | } 76 | 77 | Logger log = null; 78 | // set logger if stack is subclass of DebugStack and not DebugStack itself 79 | // because DebugStack is not synchronized (and therefore not thread-safe) 80 | if (stack instanceof DebugStack) { 81 | log = new Logger(threads.length); 82 | ((DebugStack) stack).setLogger(log); 83 | } 84 | 85 | // print stack type 86 | System.out.print("Benchmarking: " + stack.getClass().getSimpleName() + " "); 87 | 88 | // start measuring time 89 | long start = System.currentTimeMillis(); 90 | 91 | // start threads 92 | for (Thread thread : threads) { 93 | thread.start(); 94 | } 95 | 96 | // wait for threads to finish 97 | for (Thread thread : threads) { 98 | try { 99 | thread.join(); 100 | } catch (InterruptedException e) { 101 | e.printStackTrace(); 102 | } 103 | } 104 | 105 | // stop measuring time 106 | long end = System.currentTimeMillis(); 107 | System.out.println("- took " + (end - start) + " ms"); 108 | 109 | // write to file 110 | if (log != null) { 111 | log.writeFile(String.format(logsPath, stack.getClass().getSimpleName())); 112 | } 113 | } 114 | } 115 | } 116 | 117 | // example output: 118 | 119 | // Benchmarking: Stack - took 669 ms 120 | // Benchmarking: DebugStack - took 3725 ms 121 | // Benchmarking: SynchroStack - took 3845 ms 122 | // Benchmarking: SynchroStackFast - took 2180 ms 123 | -------------------------------------------------------------------------------- /labs/sem1/lab10/Stack.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab10; 2 | 3 | // class Stack - parent class for SynchroStack and SynchroStackFast 4 | 5 | public class Stack { 6 | protected StackNode head; 7 | protected int size = 0; 8 | 9 | public void push(int i) { 10 | StackNode node = new StackNode(i); 11 | node.next = head; 12 | head = node; 13 | size++; 14 | } 15 | 16 | public int pop() { 17 | if (head == null) { 18 | throw new RuntimeException("Stack is empty"); 19 | } 20 | int value = head.value; 21 | head = head.next; 22 | size--; 23 | return value; 24 | } 25 | 26 | public int size() { 27 | return size; 28 | } 29 | 30 | public boolean equals(Object o) { 31 | if (o == null) { 32 | return false; 33 | } 34 | if (o == this) { 35 | return true; 36 | } 37 | if (!(o instanceof Stack)) { 38 | return false; 39 | } 40 | Stack other = (Stack) o; 41 | StackNode node1 = head; 42 | StackNode node2 = other.head; 43 | while (node1 != null && node2 != null) { 44 | if (node1.value != node2.value) { 45 | return false; 46 | } 47 | node1 = node1.next; 48 | node2 = node2.next; 49 | } 50 | return node1 == null && node2 == null; 51 | } 52 | 53 | public String toString() { 54 | StringBuilder sb = new StringBuilder(); 55 | sb.append("["); 56 | StackNode node = head; 57 | while (node != null) { 58 | sb.append(node.value); 59 | sb.append(", "); 60 | node = node.next; 61 | } 62 | if (head != null) { 63 | sb.delete(sb.length() - 2, sb.length()); 64 | } 65 | sb.append("]"); 66 | return sb.toString(); 67 | } 68 | 69 | class StackNode { 70 | int value; 71 | StackNode next; 72 | 73 | StackNode(int value) { 74 | this.value = value; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /labs/sem1/lab10/SynchroStack.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab10; 2 | 3 | // с этим классом одновременно может работать один поток (для всех методов) 4 | 5 | public class SynchroStack extends Stack { 6 | // change this to extends DebugStack / Stack to enable / disable debug 7 | 8 | public synchronized void push(int i) { 9 | super.push(i); 10 | } 11 | 12 | public synchronized int pop() { 13 | return super.pop(); 14 | } 15 | 16 | public synchronized boolean equals(Object o) { 17 | return super.equals(o); 18 | } 19 | 20 | public synchronized String toString() { 21 | return super.toString(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /labs/sem1/lab10/SynchroStackFast.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab10; 2 | 3 | // с этим классом одновременно может работать один записывающий поток 4 | // (push и pop) и несколько читающих (equals и toString) 5 | // для этого есть два объекта-монитора: для записи и для чтения 6 | 7 | public class SynchroStackFast extends Stack { 8 | // change this to extends DebugStack / Stack to enable / disable debug 9 | 10 | Object readLock = new Object(); 11 | Object writeLock = new Object(); 12 | 13 | public void push(int i) { 14 | synchronized (writeLock) { 15 | super.push(i); 16 | } 17 | } 18 | 19 | public int pop() { 20 | synchronized (writeLock) { 21 | return super.pop(); 22 | } 23 | } 24 | 25 | public boolean equals(Object o) { 26 | synchronized (readLock) { 27 | return super.equals(o); 28 | } 29 | } 30 | 31 | public String toString() { 32 | synchronized (readLock) { 33 | return super.toString(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /labs/sem1/lab10/results/DebugStack.csv: -------------------------------------------------------------------------------- 1 | main,Thread 0,Thread 1,Thread 2,Thread 3,Thread 4,Thread 5,Thread 6,Thread 7 2 | "",Push START,"","","","","","","" 3 | "","","","","",Equals START,"","","" 4 | "","","","","",Equals END,"","","" 5 | "",Push END,"","","","","","","" 6 | "",Push START,"","","","","","","" 7 | "","","","","","",Equals START,"","" 8 | "","","","","","","",toString START,"" 9 | "","","","",Pop START,"","","","" 10 | "","","","",Pop END,"","","","" 11 | "","","","",Pop START,"","","","" 12 | "","","","",Pop END,"","","","" 13 | "","","","",Pop START,"","","","" 14 | "","",Push START,"","","","","","" 15 | "","",Push END,"","","","","","" 16 | "","",Push START,"","","","","","" 17 | "","",Push END,"","","","","","" 18 | "","",Push START,"","","","","","" 19 | "","","","",Pop END,"","","","" 20 | "","","","",Pop START,"","","","" 21 | "","","","","","","",toString END,"" 22 | "","","","","","","",toString START,"" 23 | "","","","","","","","",toString START 24 | "","","","","","",Equals END,"","" 25 | "","","","","","",Equals START,"","" 26 | "",Push END,"","","","","","","" 27 | "",Push START,"","","","","","","" 28 | "","","",Pop START,"","","","","" 29 | "","","",Pop END,"","","","","" 30 | "","","","","",Equals START,"","","" 31 | "","","","","",Equals END,"","","" 32 | "","","",Pop START,"","","","","" 33 | "","","",Pop END,"","","","","" 34 | "",Push END,"","","","","","","" 35 | "",Push START,"","","","","","","" 36 | "","","","","","",Equals END,"","" 37 | "","","","","","",Equals START,"","" 38 | "","","","","","",Equals END,"","" 39 | "","","","","","",Equals START,"","" 40 | "","","","","","","","",toString END 41 | "","","","","","","","",toString START 42 | "","","","","","","",toString END,"" 43 | "","","","","","","",toString START,"" 44 | "","","","",Pop END,"","","","" 45 | "","","","","","","",toString END,"" 46 | "","","","",Pop START,"","","","" 47 | "","","","","","","",toString START,"" 48 | "","","","",Pop END,"","","","" 49 | "","","","","","","",toString END,"" 50 | "","","","","","","",toString START,"" 51 | "","",Push END,"","","","","","" 52 | "","",Push START,"","","","","","" 53 | "","",Push END,"","","","","","" 54 | "","",Push START,"","","","","","" 55 | "","","","","","","",toString END,"" 56 | "","","","","","","","",toString END 57 | "","","","","","","","",toString START 58 | "","","","","","",Equals END,"","" 59 | "","","","","","","","",toString END 60 | "","","","","","",Equals START,"","" 61 | "","","","","","",Equals END,"","" 62 | "",Push END,"","","","","","","" 63 | "",Push START,"","","","","","","" 64 | "","","",Pop START,"","","","","" 65 | "","","",Pop END,"","","","","" 66 | "","","",Pop START,"","","","","" 67 | "","","",Pop END,"","","","","" 68 | "","","",Pop START,"","","","","" 69 | "","","","","",Equals START,"","","" 70 | "","","","","",Equals END,"","","" 71 | "","","",Pop END,"","","","","" 72 | "",Push END,"","","","","","","" 73 | "","","","","","","","",toString START 74 | "","",Push END,"","","","","","" 75 | "","","","","","","","",toString END 76 | "","","","","","","","",toString START 77 | "","","","","","","","",toString END 78 | "","","","","",Equals START,"","","" 79 | "","","","","",Equals END,"","","" 80 | "","","","","",Equals START,"","","" 81 | "","","","","",Equals END,"","","" 82 | -------------------------------------------------------------------------------- /labs/sem1/lab10/results/SynchroStack.csv: -------------------------------------------------------------------------------- 1 | main,Thread 0,Thread 1,Thread 2,Thread 3,Thread 4,Thread 5,Thread 6,Thread 7 2 | "",Push START,"","","","","","","" 3 | "",Push END,"","","","","","","" 4 | "",Push START,"","","","","","","" 5 | "",Push END,"","","","","","","" 6 | "",Push START,"","","","","","","" 7 | "",Push END,"","","","","","","" 8 | "",Push START,"","","","","","","" 9 | "",Push END,"","","","","","","" 10 | "",Push START,"","","","","","","" 11 | "",Push END,"","","","","","","" 12 | "","",Push START,"","","","","","" 13 | "","",Push END,"","","","","","" 14 | "","",Push START,"","","","","","" 15 | "","",Push END,"","","","","","" 16 | "","",Push START,"","","","","","" 17 | "","",Push END,"","","","","","" 18 | "","",Push START,"","","","","","" 19 | "","",Push END,"","","","","","" 20 | "","",Push START,"","","","","","" 21 | "","",Push END,"","","","","","" 22 | "","","",Pop START,"","","","","" 23 | "","","",Pop END,"","","","","" 24 | "","","",Pop START,"","","","","" 25 | "","","",Pop END,"","","","","" 26 | "","","",Pop START,"","","","","" 27 | "","","",Pop END,"","","","","" 28 | "","","",Pop START,"","","","","" 29 | "","","",Pop END,"","","","","" 30 | "","","",Pop START,"","","","","" 31 | "","","",Pop END,"","","","","" 32 | "","","","",Pop START,"","","","" 33 | "","","","",Pop END,"","","","" 34 | "","","","",Pop START,"","","","" 35 | "","","","",Pop END,"","","","" 36 | "","","","",Pop START,"","","","" 37 | "","","","",Pop END,"","","","" 38 | "","","","",Pop START,"","","","" 39 | "","","","",Pop END,"","","","" 40 | "","","","",Pop START,"","","","" 41 | "","","","",Pop END,"","","","" 42 | "","","","","","","","",toString START 43 | "","","","","","","","",toString END 44 | "","","","","","","","",toString START 45 | "","","","","","","","",toString END 46 | "","","","","","","","",toString START 47 | "","","","","","","","",toString END 48 | "","","","","","","","",toString START 49 | "","","","","","","","",toString END 50 | "","","","","","","","",toString START 51 | "","","","","","","","",toString END 52 | "","","","","","","",toString START,"" 53 | "","","","","","","",toString END,"" 54 | "","","","","","","",toString START,"" 55 | "","","","","","","",toString END,"" 56 | "","","","","","","",toString START,"" 57 | "","","","","","","",toString END,"" 58 | "","","","","","","",toString START,"" 59 | "","","","","","","",toString END,"" 60 | "","","","","","","",toString START,"" 61 | "","","","","","","",toString END,"" 62 | "","","","","","",Equals START,"","" 63 | "","","","","","",Equals END,"","" 64 | "","","","","","",Equals START,"","" 65 | "","","","","","",Equals END,"","" 66 | "","","","","","",Equals START,"","" 67 | "","","","","","",Equals END,"","" 68 | "","","","","","",Equals START,"","" 69 | "","","","","","",Equals END,"","" 70 | "","","","","","",Equals START,"","" 71 | "","","","","","",Equals END,"","" 72 | "","","","","",Equals START,"","","" 73 | "","","","","",Equals END,"","","" 74 | "","","","","",Equals START,"","","" 75 | "","","","","",Equals END,"","","" 76 | "","","","","",Equals START,"","","" 77 | "","","","","",Equals END,"","","" 78 | "","","","","",Equals START,"","","" 79 | "","","","","",Equals END,"","","" 80 | "","","","","",Equals START,"","","" 81 | "","","","","",Equals END,"","","" 82 | -------------------------------------------------------------------------------- /labs/sem1/lab10/results/SynchroStackFast.csv: -------------------------------------------------------------------------------- 1 | main,Thread 0,Thread 1,Thread 2,Thread 3,Thread 4,Thread 5,Thread 6,Thread 7 2 | "",Push START,"","","","","","","" 3 | "",Push END,"","","","","","","" 4 | "","","",Pop START,"","","","","" 5 | "","","",Pop END,"","","","","" 6 | "","","",Pop START,"","","","","" 7 | "","","",Pop END,"","","","","" 8 | "","",Push START,"","","","","","" 9 | "","",Push END,"","","","","","" 10 | "","","","","",Equals START,"","","" 11 | "","","","","",Equals END,"","","" 12 | "","",Push START,"","","","","","" 13 | "","",Push END,"","","","","","" 14 | "","",Push START,"","","","","","" 15 | "","","","","","",Equals START,"","" 16 | "","","","","","",Equals END,"","" 17 | "","",Push END,"","","","","","" 18 | "","",Push START,"","","","","","" 19 | "","",Push END,"","","","","","" 20 | "","","","","","",Equals START,"","" 21 | "","","","","","",Equals END,"","" 22 | "","","","","","",Equals START,"","" 23 | "","","","","","",Equals END,"","" 24 | "","","","","","",Equals START,"","" 25 | "","","","","","",Equals END,"","" 26 | "","","","","","",Equals START,"","" 27 | "","",Push START,"","","","","","" 28 | "","",Push END,"","","","","","" 29 | "","","","","","",Equals END,"","" 30 | "","","",Pop START,"","","","","" 31 | "","","",Pop END,"","","","","" 32 | "","","",Pop START,"","","","","" 33 | "","","",Pop END,"","","","","" 34 | "","","",Pop START,"","","","","" 35 | "","","","","","","","",toString START 36 | "","","",Pop END,"","","","","" 37 | "","","","","","","","",toString END 38 | "","","","","","","","",toString START 39 | "","","","",Pop START,"","","","" 40 | "","","","","","","","",toString END 41 | "","","","","","","","",toString START 42 | "","","","",Pop END,"","","","" 43 | "","","","",Pop START,"","","","" 44 | "","","","","","","","",toString END 45 | "","","","","","","","",toString START 46 | "","","","",Pop END,"","","","" 47 | "","","","",Pop START,"","","","" 48 | "","","","",Pop END,"","","","" 49 | "","","","",Pop START,"","","","" 50 | "","","","","","","","",toString END 51 | "","","","","","","","",toString START 52 | "","","","",Pop END,"","","","" 53 | "","","","",Pop START,"","","","" 54 | "","","","",Pop END,"","","","" 55 | "","","","","","","","",toString END 56 | "",Push START,"","","","","","","" 57 | "","","","","","","",toString START,"" 58 | "",Push END,"","","","","","","" 59 | "","","","","","","",toString END,"" 60 | "",Push START,"","","","","","","" 61 | "",Push END,"","","","","","","" 62 | "","","","","","","",toString START,"" 63 | "","","","","","","",toString END,"" 64 | "",Push START,"","","","","","","" 65 | "",Push END,"","","","","","","" 66 | "","","","","","","",toString START,"" 67 | "","","","","","","",toString END,"" 68 | "",Push START,"","","","","","","" 69 | "",Push END,"","","","","","","" 70 | "","","","","","","",toString START,"" 71 | "","","","","","","",toString END,"" 72 | "","","","","","","",toString START,"" 73 | "","","","","","","",toString END,"" 74 | "","","","","",Equals START,"","","" 75 | "","","","","",Equals END,"","","" 76 | "","","","","",Equals START,"","","" 77 | "","","","","",Equals END,"","","" 78 | "","","","","",Equals START,"","","" 79 | "","","","","",Equals END,"","","" 80 | "","","","","",Equals START,"","","" 81 | "","","","","",Equals END,"","","" 82 | -------------------------------------------------------------------------------- /labs/sem1/lab2/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab2; 2 | 3 | // Доп: 4 | // Добавить в класс метод rotate (int dir) 5 | // dir - направление вращения: 6 | // (1 - 90 градусов, 2 - 180 градусов, 3 - 270 градусов) 7 | 8 | class MatrixDop extends Matrix { 9 | public MatrixDop(int size) { 10 | super(size); 11 | } 12 | 13 | public void rotate(int direction) { 14 | Matrix result = new Matrix(this.size); 15 | switch (direction % 4) { 16 | case 1: 17 | for (int i = 0; i < this.size; i++) { 18 | for (int j = 0; j < this.size; j++) { 19 | result.matrix[i][j] = this.matrix[this.size - j - 1][i]; 20 | } 21 | } 22 | break; 23 | case 2: 24 | for (int i = 0; i < this.size; i++) { 25 | for (int j = 0; j < this.size; j++) { 26 | result.matrix[i][j] = this.matrix[this.size - i - 1][this.size - j - 1]; 27 | } 28 | } 29 | break; 30 | case 3: 31 | for (int i = 0; i < this.size; i++) { 32 | for (int j = 0; j < this.size; j++) { 33 | result.matrix[i][j] = this.matrix[j][this.size - i - 1]; 34 | } 35 | } 36 | break; 37 | } 38 | this.matrix = result.matrix; 39 | } 40 | } 41 | 42 | public class Dop { 43 | public static void main(String[] args) { 44 | MatrixDop matrix = new MatrixDop(3); 45 | 46 | // set some values 47 | matrix.setElement(0, 0, 1); 48 | matrix.setElement(0, 1, 2); 49 | matrix.setElement(0, 2, 3); 50 | matrix.setElement(1, 0, 4); 51 | matrix.setElement(1, 1, 5); 52 | matrix.setElement(1, 2, 6); 53 | matrix.setElement(2, 0, 7); 54 | matrix.setElement(2, 1, 8); 55 | matrix.setElement(2, 2, 9); 56 | 57 | // print the matrix 58 | System.out.println(matrix); 59 | 60 | matrix.rotate(1); 61 | System.out.println(matrix); 62 | 63 | matrix.rotate(2); 64 | System.out.println(matrix); 65 | 66 | matrix.rotate(3); 67 | System.out.println(matrix); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /labs/sem1/lab2/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab2; 2 | 3 | // Напишите класс Matrix, реализующий квадратные матрицы. В нем должны быть определены (во всех 4 | // методах предполагается, что передаваемые параметры всегда корректны): 5 | 6 | // - конструктор с целочисленным параметром - размером матрицы, создающий единичную матрицу; 7 | // - методы Matrix sum(Matrix) и Matrix product(Matrix), вычисляющие сумму и произведение матриц 8 | // - сеттеры и геттеры для обращения к элементам матрицы: setElement(int row, int column, int value) 9 | // и getElement(int row, int column) 10 | // - метод toString() (необходимо использовать StringArray или StringBuilder) 11 | 12 | // Напишите программу, выводящую первые 10 степеней матрицы: 13 | // [1 1] 14 | // [1 0] 15 | 16 | public class Main { 17 | public static void main(String[] args) { 18 | // create a matrix 19 | Matrix inputMatrix = new Matrix(2); 20 | 21 | // set some values 22 | inputMatrix.setElement(0, 0, 1); 23 | inputMatrix.setElement(0, 1, 1); 24 | inputMatrix.setElement(1, 0, 1); 25 | inputMatrix.setElement(1, 1, 0); 26 | 27 | // print the matrix 28 | System.out.println("Power 1:"); 29 | System.out.println(inputMatrix); 30 | 31 | // print the first 10 powers of the matrix 32 | Matrix matrix = inputMatrix; 33 | for (int i = 2; i <= 10; i++) { 34 | matrix = matrix.multiply(inputMatrix); 35 | System.out.println("Power " + i + ":"); 36 | System.out.println(matrix); 37 | } 38 | } 39 | 40 | public static void test() { 41 | // create a matrix 42 | Matrix matrix = new Matrix(3); 43 | 44 | // set some values 45 | matrix.setElement(0, 0, 1); 46 | matrix.setElement(0, 1, 2); 47 | matrix.setElement(0, 2, 3); 48 | matrix.setElement(1, 0, 4); 49 | matrix.setElement(1, 1, 5); 50 | matrix.setElement(1, 2, 6); 51 | matrix.setElement(2, 0, 7); 52 | matrix.setElement(2, 1, 8); 53 | matrix.setElement(2, 2, 9); 54 | 55 | // print the matrix 56 | System.out.println(matrix); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /labs/sem1/lab2/Matrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab2; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Matrix { 6 | protected int size; 7 | protected int[][] matrix; 8 | 9 | public Matrix() { 10 | this.size = 0; 11 | this.matrix = new int[0][0]; 12 | } 13 | 14 | public Matrix(int size) { 15 | this.size = size; 16 | this.matrix = new int[size][size]; 17 | } 18 | 19 | public void setElement(int row, int column, int value) { 20 | this.matrix[row][column] = value; 21 | } 22 | 23 | public int getElement(int row, int column) { 24 | return this.matrix[row][column]; 25 | } 26 | 27 | // multiply this matrix with another matrix 28 | public Matrix multiply(Matrix other) { 29 | Matrix result = new Matrix(this.size); 30 | 31 | for (int i = 0; i < this.size; i++) { 32 | for (int j = 0; j < this.size; j++) { 33 | int sum = 0; 34 | 35 | for (int k = 0; k < this.size; k++) { 36 | sum += this.matrix[i][k] * other.matrix[k][j]; 37 | } 38 | 39 | result.matrix[i][j] = sum; 40 | } 41 | } 42 | 43 | return result; 44 | } 45 | 46 | // sum this matrix with another matrix 47 | public Matrix add(Matrix other) { 48 | Matrix result = new Matrix(this.size); 49 | 50 | for (int i = 0; i < this.size; i++) { 51 | for (int j = 0; j < this.size; j++) { 52 | result.matrix[i][j] = this.matrix[i][j] + other.matrix[i][j]; 53 | } 54 | } 55 | 56 | return result; 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | StringBuilder builder = new StringBuilder(); 62 | 63 | for (int[] row : this.matrix) { 64 | builder.append(Arrays.toString(row)); 65 | builder.append("\n"); 66 | } 67 | 68 | return builder.toString(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /labs/sem1/lab3/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab3; 2 | 3 | // Доп: 4 | // Создать класс FourPartMatrix, расширяющий класс SquareMatrix. 5 | // Вторая четвертинка равна первой, четвертая - третьей. 6 | // Добавить MatrixSumException, MatrixProductException 7 | 8 | public class Dop { 9 | public static void main(String[] args) { 10 | FourPartMatrix matrix = new FourPartMatrix(6); 11 | 12 | matrix.setElement(0, 0, 1); 13 | matrix.setElement(0, 1, 2); 14 | matrix.setElement(1, 0, 3); 15 | matrix.setElement(1, 1, 4); 16 | 17 | System.out.println(matrix); 18 | 19 | matrix.setElement(3, 0, 7); 20 | matrix.setElement(4, 1, 7); 21 | matrix.setElement(5, 2, 7); 22 | 23 | System.out.println(matrix); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /labs/sem1/lab3/FourPartMatrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab3; 2 | 3 | public class FourPartMatrix extends SquareMatrix { 4 | protected int[][] second; 5 | 6 | public FourPartMatrix() { 7 | this(2); 8 | } 9 | 10 | public FourPartMatrix(int size) { 11 | super(size / 2, 0); 12 | second = new int[size / 2][size / 2]; 13 | rows = size; 14 | columns = size; 15 | if (size % 2 != 0) { 16 | throw new MatrixException("Size must be even"); 17 | } 18 | } 19 | 20 | public int getElement(int row, int column) { 21 | if (row < 0 || row >= rows || column < 0 || column >= columns) { 22 | throw new MatrixException("Index out of bounds"); 23 | } 24 | column = column < columns / 2 ? column : column - columns / 2; 25 | if (row < rows / 2) { 26 | return matrix[row][column]; 27 | } else { 28 | return second[row - rows / 2][column]; 29 | } 30 | } 31 | 32 | public void setElement(int row, int column, int value) { 33 | if (row < 0 || row >= rows || column < 0 || column >= columns) { 34 | throw new MatrixException("Index out of bounds"); 35 | } 36 | column = column < columns / 2 ? column : column - columns / 2; 37 | if (row < rows / 2) { 38 | matrix[row][column] = value; 39 | } else { 40 | second[row - rows / 2][column] = value; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /labs/sem1/lab3/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab3; 2 | 3 | // Напишите класс Matrix, реализующий матрицы и расширяющий его класс SquareMatrix, реализующий 4 | // квадратные матрицы В классах должны быть определены: 5 | 6 | // - конструкторы с параметрами размера матриц, создающие нулевую матрицу для Matrix 7 | // и единичную для SquareMatrix 8 | // - методы Matrix sum(Matrix) и Matrix product(Matrix), 9 | // вычисляющие сумму и произведение матриц (метод sum должен быть переопределен в SquareMatrix) 10 | // - методы setElement(int row, int column, int value) и getElement(int row, int column) 11 | // для обращения к элементам матрицы 12 | // - метод toString() 13 | 14 | // Напишите собственный класс исключения, расширяющий (наследующий) класс RuntimeException. 15 | // Во всех конструкторах и методах должны бросаться исключения в тех случаях, когда соответствующая 16 | // операция невозможна (например, при сложении матриц разных размеров). Исключения должны содержать 17 | // информацию о том, какая именно проблема возникла. Достаточно хранить эту информацию в виде 18 | // строки, возвращаемой методом getMessage() 19 | 20 | // Примените к написанной программе: 21 | // - Разложите классы по пакетам 22 | // - Напишите слово final в тех случаях, где оно разумно 23 | // - Реализуйте для матриц метод equals() 24 | 25 | public class Main { 26 | public static void main(String[] args) { 27 | SquareMatrix matrix1 = new SquareMatrix(2); 28 | SquareMatrix matrix2 = new SquareMatrix(2); 29 | 30 | matrix1.setElement(0, 0, 1); 31 | matrix1.setElement(0, 1, 2); 32 | matrix1.setElement(1, 0, 3); 33 | matrix1.setElement(1, 1, 4); 34 | 35 | matrix2.setElement(0, 0, 5); 36 | matrix2.setElement(0, 1, 6); 37 | matrix2.setElement(1, 0, 7); 38 | matrix2.setElement(1, 1, 8); 39 | 40 | System.out.println("matrix 1:"); 41 | System.out.println(matrix1); 42 | 43 | System.out.println("matrix 2:"); 44 | System.out.println(matrix2); 45 | 46 | SquareMatrix matrix3 = matrix1.sum(matrix2); 47 | 48 | System.out.println("matrix 1 + matrix 2:"); 49 | System.out.println(matrix3); 50 | 51 | SquareMatrix matrix4 = matrix1; 52 | System.out.println("matrix 4:"); 53 | System.out.println(matrix4); 54 | 55 | System.out.println("test of equals:"); 56 | System.out.println("matrix 1 equals matrix 2: " + matrix1.equals(matrix2)); 57 | System.out.println("matrix 1 equals matrix 4: " + matrix1.equals(matrix4)); 58 | 59 | System.out.println(); 60 | System.out.println("test of exceptions:"); 61 | 62 | SquareMatrix matrix5 = new SquareMatrix(3); 63 | SquareMatrix matrix6 = new SquareMatrix(2); 64 | 65 | try { 66 | SquareMatrix matrix7 = matrix5.sum(matrix6); 67 | System.out.println(matrix7); 68 | } catch (MatrixException e) { 69 | System.out.println(e.getMessage()); 70 | } 71 | 72 | try { 73 | SquareMatrix matrix7 = matrix5.sum(matrix5); 74 | System.out.println(matrix7.getElement(42, 42)); 75 | } catch (MatrixException e) { 76 | System.out.println(e.getMessage()); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /labs/sem1/lab3/Matrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab3; 2 | 3 | class Matrix { 4 | protected int rows; 5 | protected int columns; 6 | protected int[][] matrix; 7 | 8 | public Matrix(int rows, int columns) { 9 | this.rows = rows; 10 | this.columns = columns; 11 | this.matrix = new int[rows][columns]; 12 | } 13 | 14 | public Matrix(int size) { 15 | this(size, size); 16 | } 17 | 18 | public Matrix() { 19 | this(1, 1); 20 | } 21 | 22 | public Matrix sum(Matrix matrix) { 23 | if (this.rows != matrix.rows || this.columns != matrix.columns) { 24 | throw new MatrixSumException("Matrices have different sizes"); 25 | } 26 | 27 | Matrix result = new Matrix(this.rows, this.columns); 28 | 29 | for (int i = 0; i < this.rows; i++) { 30 | for (int j = 0; j < this.columns; j++) { 31 | result.setElement(i, j, this.getElement(i, j) + matrix.getElement(i, j)); 32 | } 33 | } 34 | 35 | return result; 36 | } 37 | 38 | public Matrix product(Matrix matrix) { 39 | if (this.columns != matrix.rows) { 40 | throw new MatrixProductException("Matrices have different sizes"); 41 | } 42 | 43 | Matrix result = new Matrix(this.rows, matrix.columns); 44 | 45 | for (int i = 0; i < this.rows; i++) { 46 | for (int j = 0; j < matrix.columns; j++) { 47 | for (int k = 0; k < this.columns; k++) { 48 | result.setElement( 49 | i, j, result.getElement(i, j) + this.getElement(i, k) * matrix.getElement(k, j)); 50 | } 51 | } 52 | } 53 | 54 | return result; 55 | } 56 | 57 | public void setElement(int row, int column, int value) { 58 | if (row < 0 || row >= this.rows || column < 0 || column >= this.columns) { 59 | throw new MatrixException("Index out of bounds"); 60 | } 61 | 62 | this.matrix[row][column] = value; 63 | } 64 | 65 | public int getElement(int row, int column) { 66 | if (row < 0 || row >= this.rows || column < 0 || column >= this.columns) { 67 | throw new MatrixException("Index out of bounds"); 68 | } 69 | 70 | return this.matrix[row][column]; 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | StringBuilder result = new StringBuilder(); 76 | 77 | for (int i = 0; i < this.rows; i++) { 78 | for (int j = 0; j < this.columns; j++) { 79 | result.append(this.getElement(i, j)).append(" "); 80 | } 81 | result.append("\n"); 82 | } 83 | 84 | return result.toString(); 85 | } 86 | 87 | @Override 88 | public boolean equals(Object obj) { 89 | if (obj == this) { 90 | return true; 91 | } 92 | 93 | if (obj == null || obj.getClass() != this.getClass()) { 94 | return false; 95 | } 96 | 97 | Matrix matrix = (Matrix) obj; 98 | 99 | if (this.rows != matrix.rows || this.columns != matrix.columns) { 100 | return false; 101 | } 102 | 103 | for (int i = 0; i < this.rows; i++) { 104 | for (int j = 0; j < this.columns; j++) { 105 | if (getElement(i, j) != matrix.getElement(i, j)) { 106 | return false; 107 | } 108 | } 109 | } 110 | 111 | return true; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /labs/sem1/lab3/MatrixException.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab3; 2 | 3 | class MatrixException extends RuntimeException { 4 | public MatrixException(String message) { 5 | super("Matrix Exception: " + message); 6 | } 7 | } 8 | 9 | class MatrixSumException extends MatrixException { 10 | public MatrixSumException(String message) { 11 | super("Matrix Sum Exception: " + message); 12 | } 13 | } 14 | 15 | class MatrixProductException extends MatrixException { 16 | public MatrixProductException(String message) { 17 | super("Matrix Product Exception: " + message); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /labs/sem1/lab3/SquareMatrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab3; 2 | 3 | class SquareMatrix extends Matrix { 4 | public SquareMatrix(int size) { 5 | super(size, size); 6 | for (int i = 0; i < size; i++) { 7 | matrix[i][i] = 1; 8 | } 9 | } 10 | 11 | public SquareMatrix() { 12 | this(1); 13 | } 14 | 15 | public SquareMatrix(int size, int fill) { 16 | super(size, size); 17 | if (fill == 0) { 18 | return; 19 | } 20 | for (int i = 0; i < size; i++) { 21 | for (int j = 0; j < size; j++) { 22 | matrix[i][j] = fill; 23 | } 24 | } 25 | } 26 | 27 | public SquareMatrix sum(SquareMatrix matrix) { 28 | // return (SquareMatrix) super.sum(matrix); 29 | // - is not correct, because we can't cast Matrix to SquareMatrix 30 | // because Matrix can be not SquareMatrix 31 | 32 | if (this.rows != matrix.rows) { 33 | throw new MatrixException("Matrices have different sizes"); 34 | } 35 | 36 | SquareMatrix result = new SquareMatrix(this.rows); 37 | 38 | for (int i = 0; i < this.rows; i++) { 39 | for (int j = 0; j < this.columns; j++) { 40 | result.setElement(i, j, this.getElement(i, j) + matrix.getElement(i, j)); 41 | } 42 | } 43 | 44 | return result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /labs/sem1/lab4/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab4; 2 | 3 | // Доп: 4 | // Добавить метод SortedList getLessThan(int value), 5 | // возвращающий список элементов, меньших value 6 | 7 | public class Dop { 8 | public static void main(String[] args) { 9 | SortedIntegerListDop list = new SortedIntegerListDop(true); 10 | for (int i = 0; i < 10; i++) { 11 | list.add(i); 12 | list.add(i + 10); 13 | } 14 | 15 | System.out.println(list); 16 | System.out.println(list.getLessThan(10)); 17 | } 18 | } 19 | 20 | class SortedIntegerListDop extends SortedIntegerList { 21 | public SortedIntegerListDop(boolean allowDuplicates) { 22 | super(allowDuplicates); 23 | } 24 | 25 | public SortedIntegerListDop() { 26 | super(); 27 | } 28 | 29 | public SortedIntegerList getLessThan(int value) { 30 | SortedIntegerList result = new SortedIntegerList(this.allowDuplicates); 31 | 32 | for (Integer i : list) { 33 | if (i < value) { 34 | result.add(i); 35 | } 36 | } 37 | 38 | return result; 39 | } 40 | } -------------------------------------------------------------------------------- /labs/sem1/lab4/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab4; 2 | 3 | // Напишите класс SortedIntegerList, который хранит отсортированный в порядке возрастания список 4 | // целых чисел. Внутри класса список должен храниться с помощью LinkedList 5 | 6 | // В классе SortedInteger List должны быть определены: 7 | // - Конструктор с булевским параметром. 8 | // Если этот параметр принимает значение true, то в создаваемом списке разрешены повторяющиеся 9 | // элементы, иначе - нет 10 | // - Методы add(int) и remove(int), которые, добавляют число в список / удаляют число из списка; 11 | // если добавление (удаление) невозможно - метод не делает ничего. Операции добавления / удаления 12 | // должны требовать не более чем одного прохода по списку 13 | // - Метод equals() 14 | 15 | // Примечание: везде использовать итератор 16 | // Напишите программу, проверяющую работу класса SortedIntegerList 17 | 18 | public class Main { 19 | public static void main(String[] args) { 20 | // проверка запрета повторений 21 | SortedIntegerList uniqueList = new SortedIntegerList(false); 22 | SortedIntegerList originalList = new SortedIntegerList(true); 23 | 24 | // проверка добавления 25 | for (int i = 0; i < 10; i++) { 26 | uniqueList.add(i); 27 | uniqueList.add(i); 28 | originalList.add(i); 29 | originalList.add(i); 30 | } 31 | 32 | // проверка equals 33 | System.out.println("uniqueList: " + uniqueList); 34 | System.out.println("originalList: " + originalList); 35 | System.out.println("uniqueList.equals(originalList): " + uniqueList.equals(originalList)); 36 | 37 | // проверка удаления 38 | for (int i = 0; i < 10; i++) { 39 | originalList.remove(i); 40 | } 41 | 42 | System.out.println("originalList after remove: " + originalList); 43 | System.out.println("uniqueList.equals(originalList): " + uniqueList.equals(originalList)); 44 | 45 | System.out.println("uniqueList.equals(uniqueList): " + uniqueList.equals(uniqueList)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /labs/sem1/lab4/SortedIntegerList.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab4; 2 | 3 | import java.util.LinkedList; 4 | import java.util.ListIterator; 5 | 6 | class SortedIntegerList { 7 | // список, в котором хранятся элементы 8 | protected LinkedList list; 9 | boolean allowDuplicates; 10 | 11 | public SortedIntegerList(boolean allowDuplicates) { 12 | this.allowDuplicates = allowDuplicates; 13 | list = new LinkedList(); 14 | } 15 | 16 | // конструктор по умолчанию 17 | public SortedIntegerList() { 18 | this(true); 19 | } 20 | 21 | public void add(int value) { 22 | if (list.isEmpty()) { 23 | list.add(value); 24 | } else { 25 | ListIterator iterator = list.listIterator(); 26 | while (iterator.hasNext()) { 27 | Integer current = iterator.next(); 28 | 29 | if (current > value) { 30 | iterator.previous(); 31 | iterator.add(value); 32 | return; 33 | } 34 | 35 | if (current == value && !allowDuplicates) { 36 | return; 37 | } 38 | } 39 | iterator.add(value); 40 | } 41 | } 42 | 43 | public void remove(int value) { 44 | // удаляем первое вхождение элемента 45 | list.removeFirstOccurrence(value); 46 | } 47 | 48 | @Override 49 | public boolean equals(Object obj) { 50 | if (obj == null) { 51 | return false; 52 | } 53 | 54 | if (obj == this) { 55 | return true; 56 | } 57 | 58 | if (!(obj instanceof SortedIntegerList)) { 59 | return false; 60 | } 61 | 62 | SortedIntegerList other = (SortedIntegerList) obj; 63 | 64 | if (this.list.size() != other.list.size()) { 65 | return false; 66 | } 67 | 68 | ListIterator iterator1 = this.list.listIterator(); 69 | ListIterator iterator2 = other.list.listIterator(); 70 | 71 | while (iterator1.hasNext()) { 72 | if (iterator1.next() != iterator2.next()) { 73 | return false; 74 | } 75 | } 76 | 77 | return true; 78 | } 79 | 80 | @Override 81 | public String toString() { 82 | StringBuilder sb = new StringBuilder(); 83 | sb.append("["); 84 | 85 | for (Integer i : list) { 86 | sb.append(i); 87 | sb.append(", "); 88 | } 89 | 90 | if (sb.length() > 1) { 91 | sb.delete(sb.length() - 2, sb.length()); 92 | } 93 | 94 | sb.append("]"); 95 | return sb.toString(); 96 | } 97 | } -------------------------------------------------------------------------------- /labs/sem1/lab5/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab5; 2 | 3 | // Доп: 4 | // Написать реализацию SparseMatrix на основе ArrayList> 5 | // и сравнить время работы с реализацией на основе LinkedList> 6 | 7 | import java.util.ArrayList; 8 | import java.util.LinkedList; 9 | import java.util.Locale; 10 | 11 | public class Dop { 12 | public static void main(String[] args) { 13 | final int matrixSize = 200; 14 | final int elementsCount = 200; 15 | 16 | SparseMatrix sparseMatrix = new SparseMatrix(matrixSize); 17 | SparseMatrixFast sparseMatrixFast = new SparseMatrixFast(matrixSize); 18 | 19 | System.out.println("With matrix size " + matrixSize + " and " + elementsCount + " elements:"); 20 | System.out.println(); 21 | 22 | for (int i = 0; i < elementsCount; i++) { 23 | int row = (int) (Math.random() * matrixSize); 24 | int column = (int) (Math.random() * matrixSize); 25 | int value = (int) (Math.random() * 1000); 26 | sparseMatrix.setElement(row, column, value); 27 | sparseMatrixFast.setElement(row, column, value); 28 | } 29 | 30 | long startTime = System.currentTimeMillis(); 31 | sparseMatrix.product(sparseMatrix); 32 | long mediumTime = System.currentTimeMillis(); 33 | sparseMatrixFast.product(sparseMatrixFast); 34 | long endTime = System.currentTimeMillis(); 35 | 36 | long delta1 = mediumTime - startTime; 37 | long delta2 = endTime - mediumTime; 38 | 39 | System.out.println("SparseMatrix time: " + delta1); 40 | System.out.println("SparseMatrixFast time: " + delta2); 41 | 42 | String times = String.format(Locale.US, "%.3f", (double) delta1 / delta2); 43 | System.out.println("SparseMatrixFast is " + times + " times faster"); 44 | } 45 | } 46 | 47 | class SparseMatrixFast extends Matrix { 48 | private ArrayList> rows; 49 | 50 | public SparseMatrixFast(int rows, int columns) { 51 | super(rows, columns); 52 | this.rows = new ArrayList>(); 53 | for (int i = 0; i < rows; i++) { 54 | this.rows.add(new LinkedList()); 55 | } 56 | } 57 | 58 | public SparseMatrixFast(int size) { 59 | this(size, size); 60 | } 61 | 62 | public double getElement(int row, int column) { 63 | for (SparseMatrixElement element : rows.get(row)) { 64 | if (element.getColumn() == column) { 65 | return element.getValue(); 66 | } 67 | } 68 | return 0; 69 | } 70 | 71 | public void setElement(int row, int column, double value) { 72 | for (SparseMatrixElement element : rows.get(row)) { 73 | if (element.getColumn() == column) { 74 | element.setValue(value); 75 | return; 76 | } 77 | } 78 | rows.get(row).add(new SparseMatrixElement(column, value)); 79 | } 80 | 81 | public SparseMatrixFast add(SparseMatrixFast matrix) { 82 | return (SparseMatrixFast) super.add(matrix); 83 | } 84 | 85 | public SparseMatrixFast product(SparseMatrixFast matrix) { 86 | return (SparseMatrixFast) super.product(matrix); 87 | } 88 | 89 | public Matrix createMatrix(int rows, int columns) { 90 | return new SparseMatrixFast(rows, columns); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /labs/sem1/lab5/IMatrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab5; 2 | 3 | public interface IMatrix { 4 | // интерфейс, который должны реализовать все матрицы 5 | // содержит методы, которые должны быть реализованы во всех матрицах 6 | 7 | public int getRows(); 8 | 9 | public int getColumns(); 10 | 11 | public double getElement(int row, int column); 12 | 13 | public void setElement(int row, int column, double value); 14 | } 15 | -------------------------------------------------------------------------------- /labs/sem1/lab5/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab5; 2 | 3 | // Напишите интерфейс IMatrix с несколькими реализациями - UsualMatrix и расширяющий его 4 | // SquareMatrix из предыдущих заданий и SparseMatrix для разреженных матриц. SparseMatrix 5 | // должен быть реализован с помощью LinkedList (возможно, вам потребуется создать какие-то еще 6 | // дополнительные классы, которые должны быть вложенными/внутренними). Все общие методы должны быть 7 | // представлены в интерфейсе IMatrix 8 | 9 | // Напишите программу, создающую 2 случайные матрицы размером 1000x1000 с 1000 ненулевых элементов в 10 | // каждой двумя способами - с помощью обычных и разреженных матриц. Проверьте, что сложение и 11 | // умножение для разных видов матриц дает одинаковые результаты 12 | 13 | import java.util.Locale; 14 | 15 | public class Main { 16 | public static void main(String[] args) { 17 | // settings 18 | final int matrixSize = 200; 19 | final int elementsCount = 200; 20 | 21 | // helper variables for time measuring 22 | long startTime, middleTime, endTime; 23 | long delta1, delta2; 24 | String times; 25 | 26 | SquareMatrix[] squareMatrices = new SquareMatrix[4]; 27 | SparseMatrix[] sparseMatrices = new SparseMatrix[4]; 28 | for (int i = 0; i < 4; i++) { 29 | squareMatrices[i] = new SquareMatrix(matrixSize); 30 | sparseMatrices[i] = new SparseMatrix(matrixSize); 31 | } 32 | 33 | // первые две матрицы - исходные, вторые две - результаты 34 | for (int i = 0; i < 2; i++) { 35 | for (int j = 0; j < elementsCount; j++) { 36 | int row = (int) (Math.random() * matrixSize); 37 | int column = (int) (Math.random() * matrixSize); 38 | double value = Math.random() * 1000; 39 | squareMatrices[i].setElement(row, column, value); 40 | sparseMatrices[i].setElement(row, column, value); 41 | } 42 | } 43 | 44 | System.out.println("With matrix size " + matrixSize + " and " + elementsCount + " elements:"); 45 | System.out.println(); 46 | 47 | // сложение 48 | System.out.print("adding square matrices... "); 49 | startTime = System.currentTimeMillis(); 50 | squareMatrices[2] = squareMatrices[0].add(squareMatrices[1]); 51 | middleTime = System.currentTimeMillis(); 52 | delta1 = middleTime - startTime; 53 | System.out.println("done in " + delta1 + " ms"); 54 | 55 | System.out.print("adding sparse matrices... "); 56 | middleTime = System.currentTimeMillis(); 57 | sparseMatrices[2] = sparseMatrices[0].add(sparseMatrices[1]); 58 | endTime = System.currentTimeMillis(); 59 | delta2 = endTime - middleTime; 60 | System.out.println("done in " + delta2 + " ms"); 61 | 62 | times = String.format(Locale.US, "%.2f", (double) delta2 / delta1); 63 | System.out.println("sparse matrix is " + times + " times faster"); 64 | 65 | // проверка на равенство 66 | System.out.print("square matrix sum equals sparse matrix sum: "); 67 | System.out.println(squareMatrices[2].equals((Matrix) sparseMatrices[2])); 68 | System.out.println(); 69 | 70 | // умножение 71 | System.out.print("multiplying square matrices... "); 72 | startTime = System.currentTimeMillis(); 73 | squareMatrices[3] = squareMatrices[0].product(squareMatrices[1]); 74 | middleTime = System.currentTimeMillis(); 75 | delta1 = middleTime - startTime; 76 | System.out.println("done in " + delta1 + " ms"); 77 | 78 | System.out.print("multiplying sparse matrices... "); 79 | middleTime = System.currentTimeMillis(); 80 | sparseMatrices[3] = sparseMatrices[0].product(sparseMatrices[1]); 81 | endTime = System.currentTimeMillis(); 82 | delta2 = endTime - middleTime; 83 | System.out.println("done in " + delta2 + " ms"); 84 | 85 | times = String.format(Locale.US, "%.2f", (double) delta2 / delta1); 86 | System.out.println("sparse matrix is " + times + " times faster"); 87 | 88 | // проверка на равенство 89 | System.out.print("square matrix product equals sparse matrix product: "); 90 | System.out.println(squareMatrices[3].equals((Matrix) sparseMatrices[3])); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /labs/sem1/lab5/Matrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab5; 2 | 3 | public abstract class Matrix implements IMatrix { 4 | // класс, от которого наследуются все матрицы 5 | // UsualMatrix, SquareMatrix и SparseMatrix 6 | 7 | protected int rows; 8 | protected int columns; 9 | 10 | public Matrix(int rows, int columns) { 11 | this.rows = rows; 12 | this.columns = columns; 13 | } 14 | 15 | public int getRows() { 16 | return rows; 17 | } 18 | 19 | public int getColumns() { 20 | return columns; 21 | } 22 | 23 | // методы, которые должны быть реализованы в наследниках 24 | 25 | public abstract double getElement(int row, int column); 26 | 27 | public abstract void setElement(int row, int column, double value); 28 | 29 | // методы, которые не зависят от реализации 30 | 31 | public void randomize() { 32 | for (int i = 0; i < getRows(); i++) { 33 | for (int j = 0; j < getColumns(); j++) { 34 | setElement(i, j, Math.random() * 1000); 35 | } 36 | } 37 | } 38 | 39 | public void randomize(int items) { 40 | for (int i = 0; i < items; i++) { 41 | int row = (int) (Math.random() * getRows()); 42 | int column = (int) (Math.random() * getColumns()); 43 | double value = Math.random() * 1000; 44 | setElement(row, column, value); 45 | } 46 | } 47 | 48 | public Matrix add(Matrix matrix) { 49 | if (getRows() != matrix.getRows() || getColumns() != matrix.getColumns()) { 50 | throw new IllegalArgumentException("Matrix sizes are not equal"); 51 | } 52 | 53 | Matrix result = createMatrix(getRows(), getColumns()); 54 | 55 | for (int i = 0; i < getRows(); i++) { 56 | for (int j = 0; j < getColumns(); j++) { 57 | result.setElement(i, j, getElement(i, j) + matrix.getElement(i, j)); 58 | } 59 | } 60 | 61 | return result; 62 | } 63 | 64 | public Matrix product(Matrix matrix) { 65 | if (getColumns() != matrix.getRows()) { 66 | throw new IllegalArgumentException("Matrix sizes are not equal"); 67 | } 68 | 69 | Matrix result = createMatrix(getRows(), matrix.getColumns()); 70 | 71 | for (int i = 0; i < getRows(); i++) { 72 | for (int j = 0; j < matrix.getColumns(); j++) { 73 | double sum = 0; 74 | 75 | for (int k = 0; k < getColumns(); k++) { 76 | sum += getElement(i, k) * matrix.getElement(k, j); 77 | } 78 | 79 | result.setElement(i, j, sum); 80 | } 81 | } 82 | 83 | return result; 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | StringBuilder builder = new StringBuilder(); 89 | 90 | for (int i = 0; i < getRows(); i++) { 91 | for (int j = 0; j < getColumns(); j++) { 92 | builder.append(getElement(i, j) + " "); 93 | } 94 | 95 | builder.append("\n"); 96 | } 97 | 98 | return builder.toString(); 99 | } 100 | 101 | @Override 102 | public boolean equals(Object obj) { 103 | if (obj == null) { 104 | return false; 105 | } 106 | 107 | // не нужно проверять, это объекты одного класса, 108 | // нужно проверять, что объекты - наследники одного класса Matrix 109 | if (!(obj instanceof Matrix)) { 110 | return false; 111 | } 112 | 113 | Matrix matrix = (Matrix) obj; 114 | 115 | if (getRows() != matrix.getRows() || getColumns() != matrix.getColumns()) { 116 | return false; 117 | } 118 | 119 | for (int i = 0; i < getRows(); i++) { 120 | for (int j = 0; j < getColumns(); j++) { 121 | if (getElement(i, j) != matrix.getElement(i, j)) { 122 | return false; 123 | } 124 | } 125 | } 126 | 127 | return true; 128 | } 129 | 130 | // метод, который должен быть переопределен в наследниках 131 | // почему не конструктор? потому что конструкторы не могут быть абстрактными 132 | protected abstract Matrix createMatrix(int rows, int columns); 133 | } -------------------------------------------------------------------------------- /labs/sem1/lab5/SparseMatrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab5; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class SparseMatrix extends Matrix { 6 | private LinkedList rows; 7 | 8 | public SparseMatrix(int rows, int columns) { 9 | super(rows, columns); 10 | this.rows = new LinkedList(); 11 | } 12 | 13 | public SparseMatrix(int size) { 14 | this(size, size); 15 | } 16 | 17 | public double getElement(int row, int column) { 18 | for (SparseMatrixRow currentRow : rows) { 19 | if (currentRow.getRow() == row) { 20 | for (SparseMatrixElement element : currentRow.getElements()) { 21 | if (element.getColumn() == column) { 22 | return element.getValue(); 23 | } 24 | } 25 | return 0; 26 | } 27 | } 28 | return 0; 29 | } 30 | 31 | public void setElement(int row, int column, double value) { 32 | for (SparseMatrixRow currentRow : rows) { 33 | if (currentRow.getRow() == row) { 34 | for (SparseMatrixElement element : currentRow.getElements()) { 35 | if (element.getColumn() == column) { 36 | element.setValue(value); 37 | return; 38 | } 39 | } 40 | currentRow.addElement(new SparseMatrixElement(column, value)); 41 | return; 42 | } 43 | } 44 | SparseMatrixRow newRow = new SparseMatrixRow(row); 45 | newRow.addElement(new SparseMatrixElement(column, value)); 46 | rows.add(newRow); 47 | } 48 | 49 | public SparseMatrix add(SparseMatrix matrix) { 50 | return (SparseMatrix) super.add(matrix); 51 | } 52 | 53 | public SparseMatrix product(SparseMatrix matrix) { 54 | return (SparseMatrix) super.product(matrix); 55 | } 56 | 57 | public Matrix createMatrix(int rows, int columns) { 58 | return new SparseMatrix(rows, columns); 59 | } 60 | } 61 | 62 | class SparseMatrixRow { 63 | private int row; 64 | private LinkedList elements; 65 | 66 | public SparseMatrixRow(int row) { 67 | this.row = row; 68 | elements = new LinkedList(); 69 | } 70 | 71 | public int getRow() { 72 | return row; 73 | } 74 | 75 | public LinkedList getElements() { 76 | return elements; 77 | } 78 | 79 | public void addElement(SparseMatrixElement element) { 80 | elements.add(element); 81 | } 82 | } 83 | 84 | class SparseMatrixElement { 85 | private int column; 86 | private double value; 87 | 88 | public SparseMatrixElement(int column, double value) { 89 | this.column = column; 90 | this.value = value; 91 | } 92 | 93 | public int getColumn() { 94 | return column; 95 | } 96 | 97 | public double getValue() { 98 | return value; 99 | } 100 | 101 | public void setValue(double value) { 102 | this.value = value; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /labs/sem1/lab5/SquareMatrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab5; 2 | 3 | public class SquareMatrix extends UsualMatrix { 4 | public SquareMatrix(int size) { 5 | super(size, size); 6 | } 7 | 8 | public SquareMatrix add(SquareMatrix matrix) { 9 | return (SquareMatrix) super.add(matrix); 10 | } 11 | 12 | public SquareMatrix product(SquareMatrix matrix) { 13 | return (SquareMatrix) super.product(matrix); 14 | } 15 | 16 | public Matrix createMatrix(int rows, int columns) { 17 | return new SquareMatrix(rows); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /labs/sem1/lab5/UsualMatrix.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab5; 2 | 3 | public class UsualMatrix extends Matrix { 4 | private double[][] matrix; 5 | 6 | public UsualMatrix(int size) { 7 | super(size, size); 8 | matrix = new double[size][size]; 9 | } 10 | 11 | public UsualMatrix(int rows, int columns) { 12 | super(rows, columns); 13 | matrix = new double[rows][columns]; 14 | } 15 | 16 | public double getElement(int row, int column) { 17 | return matrix[row][column]; 18 | } 19 | 20 | public void setElement(int row, int column, double value) { 21 | matrix[row][column] = value; 22 | } 23 | 24 | public UsualMatrix add(UsualMatrix matrix) { 25 | return (UsualMatrix) super.add(matrix); 26 | } 27 | 28 | public UsualMatrix product(UsualMatrix matrix) { 29 | return (UsualMatrix) super.product(matrix); 30 | } 31 | 32 | public Matrix createMatrix(int rows, int columns) { 33 | return new UsualMatrix(rows, columns); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /labs/sem1/lab6/task1/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab6.task1; 2 | 3 | // Доп: 4 | // Создать новый спецификатор, %a, который будет позволять вводить массивы 5 | // Введенный массив может быть любой длины 6 | // Окончание массива - конец строки или 'не число' 7 | 8 | import java.util.Iterator; 9 | import java.util.List; 10 | 11 | public class Dop { 12 | public static void main(String[] args) { 13 | String format = "%d %s %c %a %s %s"; 14 | String in = "1 lol 3 4 5 6 7 8 9 10 kek test"; 15 | 16 | System.out.println("Format: " + format); 17 | System.out.println("Input: " + in); 18 | System.out.println("Output:"); 19 | 20 | Object vals[] = ExtFormattedInput.sscanf(format, in); 21 | 22 | for (Object val : vals) { 23 | System.out.print(val.getClass().getName()); 24 | System.out.print(": "); 25 | System.out.println(val); 26 | } 27 | } 28 | } 29 | 30 | // FormattedInputArr - класс, который позволяет считывать массивы 31 | class ExtFormattedInput extends FormattedInput { 32 | static List availableTokens = List.of("%d", "%f", "%s", "%c", "%a"); 33 | 34 | // sscanf 35 | public static Object[] sscanf(String format, String in) { 36 | List input = List.of(in.split(" ")); 37 | List tokens = List.of(format.split(" ")); 38 | 39 | // check if format is valid 40 | for (String token : tokens) { 41 | if (!availableTokens.contains(token)) { 42 | throw new IllegalArgumentException("Invalid format"); 43 | } 44 | } 45 | 46 | // create list to store values 47 | List values = new java.util.ArrayList(); 48 | 49 | // iterators 50 | Iterator inputIterator = input.iterator(); 51 | Iterator tokensIterator = tokens.iterator(); 52 | 53 | // parse input 54 | String value = ""; 55 | boolean getNextValue = true; 56 | 57 | // parse input (including arrays) with try-catch 58 | while (inputIterator.hasNext() && tokensIterator.hasNext()) { 59 | String token = tokensIterator.next(); 60 | if (getNextValue) { // after array token, do not get next value 61 | value = inputIterator.next(); 62 | } 63 | 64 | try { 65 | switch (token) { 66 | case "%d": 67 | values.add(Integer.parseInt(value)); 68 | break; 69 | case "%f": 70 | values.add(Double.parseDouble(value)); 71 | break; 72 | case "%s": 73 | values.add(value); 74 | break; 75 | case "%c": 76 | if (value.length() != 1) { 77 | throw new RuntimeException("Input does not match format"); 78 | } else { 79 | values.add(value.charAt(0)); 80 | } 81 | break; 82 | case "%a": // array of integers terminated by non-integer or end of input 83 | List arr = new java.util.ArrayList(); 84 | while (inputIterator.hasNext()) { 85 | value = inputIterator.next(); 86 | try { 87 | arr.add(Integer.parseInt(value)); 88 | } catch (Exception e) { 89 | break; 90 | } 91 | } 92 | if (arr.size() > 0) { 93 | values.add(arr); 94 | } 95 | break; 96 | } 97 | getNextValue = !token.equals("%a"); 98 | } catch (Exception e) { 99 | throw new RuntimeException("Input does not match format"); 100 | } 101 | } 102 | 103 | // return values if no exception is thrown 104 | return values.toArray(); 105 | } 106 | } -------------------------------------------------------------------------------- /labs/sem1/lab6/task1/FormattedInput.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab6.task1; 2 | 3 | import java.util.List; 4 | 5 | public class FormattedInput { 6 | // supported formats: digit, float, string, character 7 | static List availableTokens = List.of("%d", "%f", "%s", "%c"); 8 | 9 | public static Object[] sscanf(String format, String input) { 10 | // tokenize input and format 11 | String[] inputTokens = input.split(" "); 12 | String[] formatTokens = format.split(" "); 13 | 14 | // check if input and format have same length 15 | if (formatTokens.length != inputTokens.length) { 16 | throw new RuntimeException("Input does not match format"); 17 | } 18 | 19 | // check if format is valid 20 | for (String token : formatTokens) { 21 | if (!availableTokens.contains(token)) { 22 | throw new IllegalArgumentException("Invalid format"); 23 | } 24 | } 25 | 26 | // create array to store values 27 | Object[] values = new Object[formatTokens.length]; 28 | 29 | // parse input with try-catch 30 | for (int i = 0; i < formatTokens.length; i++) { 31 | try { 32 | switch (formatTokens[i]) { 33 | case "%d": 34 | values[i] = Integer.parseInt(inputTokens[i]); 35 | break; 36 | case "%f": 37 | values[i] = Double.parseDouble(inputTokens[i]); 38 | break; 39 | case "%s": 40 | values[i] = inputTokens[i]; 41 | break; 42 | case "%c": 43 | if (inputTokens[i].length() != 1) { 44 | throw new RuntimeException("Input does not match format"); 45 | } else { 46 | values[i] = inputTokens[i].charAt(0); 47 | } 48 | break; 49 | } 50 | } catch (Exception e) { 51 | throw new RuntimeException("Input does not match format"); 52 | } 53 | } 54 | 55 | // return values if no exception is thrown 56 | return values; 57 | } 58 | 59 | public static Object[] scanf(String format) { 60 | java.util.Scanner scanner = new java.util.Scanner(System.in); 61 | while (true) { 62 | try { 63 | Object[] input = sscanf(format, scanner.nextLine()); 64 | scanner.close(); 65 | return input; 66 | } catch (Exception e) { 67 | System.out.println("Invalid input for format: " + format + ". Try again."); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /labs/sem1/lab6/task1/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab6.task1; 2 | 3 | // Реализовать класс FormattedInput с двумя статическими функциями: 4 | 5 | // Object[] scanf(String format) // Читает с System.in 6 | // Object[] sscanf(String format, String in) // Читает из строки in 7 | 8 | // format - строка со спецификацией формата ввода (может быть несколько спецификаторов в одной 9 | // строке, например, %d %d %f) 10 | 11 | // Список спецификаторов: 12 | // %d - целое int 13 | // %f - дробное double 14 | // %s - строка 15 | // %c - символ 16 | 17 | // Если ввод пользователя не соответствует спецификации, 18 | // то функция запрашивает ввод повторно 19 | 20 | public class Main { 21 | public static void main(String[] args) { 22 | System.out.print("Enter a number, a string and a character: "); 23 | Object vals[] = FormattedInput.scanf("%d %s %c"); 24 | 25 | for (Object val : vals) { 26 | System.out.print(val.getClass().getName()); 27 | System.out.print(": "); 28 | System.out.println(val); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /labs/sem1/lab6/task2/EncodingConverter.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab6.task2; 2 | 3 | // Реализовать программу EncodingConverter для перекодирования текстовых файлов из одной кодировки 4 | // в другую. Программа должна получать параметры из командной строки и контролировать их 5 | // корректность 6 | 7 | // Пример вызова: 8 | // java EncodingConverter in.txt out.txt utf8 cp1251 9 | 10 | import java.io.*; 11 | import java.nio.charset.Charset; 12 | import java.util.ArrayList; 13 | import java.util.Arrays; 14 | 15 | public class EncodingConverter { 16 | public static void main(String[] args) { 17 | // check if args length is 4 18 | if (args.length != 4) { 19 | System.out.println("Invalid number of arguments"); 20 | return; 21 | } 22 | 23 | // check if args[0] and args[1] are valid file paths 24 | if (!args[0].matches(".*\\.txt") || !args[1].matches(".*\\.txt")) { 25 | System.out.println("Invalid file path"); 26 | return; 27 | } 28 | 29 | // Create a list of all encodings supported by the JVM, including aliases. 30 | String[] encodings = Charset.availableCharsets().keySet().toArray(new String[0]); 31 | ArrayList charsets = new ArrayList(Arrays.asList(encodings)); 32 | for (String encoding : encodings) { 33 | charsets.addAll(Charset.availableCharsets().get(encoding).aliases()); 34 | } 35 | 36 | // Check if args[2] and args[3] are valid encodings. Use the original 37 | // names for encodings (case-insensitive -> case-sensitive). 38 | for (int i = 2; i < 4; i++) { 39 | final int j = i; 40 | try { 41 | args[j] = charsets.stream() 42 | .filter(charset -> charset.equalsIgnoreCase(args[j])) 43 | .findFirst() 44 | .get(); 45 | } catch (Exception e) { 46 | System.out.println("Invalid encoding"); 47 | return; 48 | } 49 | } 50 | 51 | try { 52 | convert(new File(args[0]), new File(args[1]), args[2], args[3]); 53 | } catch (IOException e) { 54 | System.out.println("Error while converting file"); 55 | } 56 | } 57 | 58 | public static void convert(File source, File target, String fromEncoding, String toEncoding) 59 | throws IOException { 60 | try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(source), fromEncoding)); 61 | BufferedWriter bw = new BufferedWriter( 62 | new OutputStreamWriter(new FileOutputStream(target), toEncoding));) { 63 | char[] buffer = new char[1024]; 64 | int read; 65 | while ((read = br.read(buffer)) != -1) { 66 | bw.write(buffer, 0, read); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /labs/sem1/lab6/task2/input.txt: -------------------------------------------------------------------------------- 1 | Just some English text 2 | Немного русского текста 3 | Some more English text 4 | Еще немного русского текста -------------------------------------------------------------------------------- /labs/sem1/lab6/task2/output.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potat-dev/JavaLabs/057fd364ee1d4a95e1530427c24afa630494f671/labs/sem1/lab6/task2/output.txt -------------------------------------------------------------------------------- /labs/sem1/lab7/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab7; 2 | 3 | // Доп: 4 | // Создать класс для хранения данных библиотеки. 5 | // Книга: название, автор, год издания. 6 | // Реализовать методы добавления книги, получения книги по названию, получения книг 7 | // после заданного года. 8 | // Реализовать методы сохранения и загрузки библиотеки в текстовый файл 9 | 10 | import java.io.*; 11 | import java.util.ArrayList; 12 | 13 | public class Dop { 14 | public static void main(String[] args) { 15 | Library library = new Library(); 16 | 17 | library.addBook("The Hitchhiker's Guide to the Galaxy", "Douglas Adams", 1979); 18 | library.addBook("The Lord of the Rings", "J. R. R. Tolkien", 1954); 19 | library.addBook("Harry Potter and the Philosopher's Stone", "J. K. Rowling", 1997); 20 | library.addBook("War and Peace", "Leo Tolstoy", 1869); 21 | library.addBook("The Little Prince", "Antoine de Saint-Exupery", 1943); 22 | 23 | System.out.println("All books:"); 24 | System.out.println(library); 25 | System.out.println(); 26 | 27 | String filePath = "src/labs/sem1/lab7/library.csv"; 28 | library.saveToTextFile(filePath); 29 | 30 | Library library2 = new Library(); 31 | library2.loadFromTextFile(filePath); 32 | 33 | System.out.println("Books after 1970:"); 34 | System.out.println(library2.getBooksAfterYear(1970)); 35 | } 36 | } 37 | 38 | class Library { 39 | private ArrayList books; 40 | 41 | public Library() { 42 | books = new ArrayList(); 43 | } 44 | 45 | public void addBook(Book book) { 46 | books.add(book); 47 | } 48 | 49 | public void addBook(String name, String author, int year) { 50 | books.add(new Book(name, author, year)); 51 | } 52 | 53 | public Book getBook(String name) { 54 | for (Book book : books) { 55 | if (book.name.equals(name)) { 56 | return book; 57 | } 58 | } 59 | 60 | return null; 61 | } 62 | 63 | public Library getBooksAfterYear(int year) { 64 | Library booksAfterYear = new Library(); 65 | 66 | for (Book book : books) { 67 | if (book.year > year) { 68 | booksAfterYear.addBook(book); 69 | } 70 | } 71 | 72 | return booksAfterYear; 73 | } 74 | 75 | public void saveToTextFile(String filename) { 76 | try { 77 | PrintWriter out = new PrintWriter(new FileWriter(filename)); 78 | 79 | for (Book book : books) { 80 | out.println(book.toCSV()); 81 | } 82 | 83 | out.flush(); 84 | out.close(); 85 | } catch (IOException e) { 86 | throw new RuntimeException("Error while saving to text file: " + e.getMessage()); 87 | } 88 | } 89 | 90 | public void loadFromTextFile(String filename) { 91 | try { 92 | BufferedReader in = new BufferedReader(new FileReader(filename)); 93 | books.clear(); 94 | 95 | String line; 96 | while ((line = in.readLine()) != null) { 97 | books.add(new Book(line)); 98 | } 99 | 100 | in.close(); 101 | } catch (IOException e) { 102 | throw new RuntimeException("Error while loading from text file: " + e.getMessage()); 103 | } 104 | } 105 | 106 | @Override 107 | public String toString() { 108 | String str = ""; 109 | 110 | for (Book book : books) { 111 | str += book.toString() + "\n"; 112 | } 113 | 114 | // remove last newline 115 | return str.substring(0, str.length() - 1); 116 | } 117 | } 118 | 119 | class Book { 120 | protected String name, author; 121 | protected int year; 122 | 123 | public Book() { 124 | this(null, null, 0); 125 | } 126 | 127 | public Book(String name, String author, int year) { 128 | // check name and author not contains comma 129 | if (name.contains(",") || author.contains(",")) { 130 | throw new IllegalArgumentException("Name and author must not contain comma"); 131 | } 132 | 133 | this.name = name; 134 | this.author = author; 135 | this.year = year; 136 | } 137 | 138 | public Book(String str) { 139 | fromString(str); 140 | } 141 | 142 | @Override 143 | public String toString() { // for output to console 144 | return "\"" + name + "\" - " + author + ", " + year; 145 | } 146 | 147 | public String toCSV() { // for output to file 148 | return name + "," + author + "," + year; 149 | } 150 | 151 | public void fromString(String str) { 152 | String[] parts = str.split(","); 153 | 154 | if (parts.length != 3) { 155 | throw new IllegalArgumentException("Invalid string format"); 156 | } 157 | 158 | name = parts[0]; 159 | author = parts[1]; 160 | try { 161 | year = Integer.parseInt(parts[2]); 162 | } catch (NumberFormatException e) { 163 | throw new IllegalArgumentException("Invalid year format"); 164 | } 165 | } 166 | } -------------------------------------------------------------------------------- /labs/sem1/lab7/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab7; 2 | 3 | // Реализуйте класс для хранения настроек Settings, в котором хранятся пары 4 | // (имя параметра, значение). Имя параметра задается строкой, а значение - целым числом. 5 | // Реализация должна использовать класс HashMap. 6 | 7 | // В классе Settings должны быть определены: 8 | // equals() 9 | // toString() 10 | // put(String, int) 11 | // int get(String) 12 | // delete(String) 13 | // loadFromBinaryFile(String filename) 14 | // saveToBinaryFile(String filename) 15 | // loadFromTextFile(String filename) 16 | // saveToTextFile(String filename) 17 | 18 | import java.io.*; 19 | 20 | public class Main { 21 | public static void main(String[] args) { 22 | Settings settings = new Settings(); 23 | 24 | settings.put("a", 1); 25 | settings.put("b", 2); 26 | settings.put("c", 3); 27 | settings.put("d", 4); 28 | settings.put("answer", 42); 29 | settings.put("number", 618); 30 | 31 | System.out.println(settings); 32 | 33 | settings.delete("d"); 34 | settings.put("kek", 7); 35 | 36 | System.out.println(settings); 37 | System.out.print("settings.get(\"answer\") = "); 38 | System.out.println(settings.get("answer")); 39 | 40 | String basePath = "src/labs/sem1/lab7/"; 41 | 42 | try { 43 | // save to binary file and load to new object 44 | settings.saveToBinaryFile(basePath + "settings.bin"); 45 | Settings settings2 = new Settings(); 46 | settings2.loadFromBinaryFile(basePath + "settings.bin"); 47 | System.out.print("Read from binary file: "); 48 | System.out.println(settings2); 49 | } catch (IOException e) { 50 | System.out.println(e.getMessage()); 51 | } 52 | 53 | try { 54 | // save to text file and load to new object 55 | settings.saveToTextFile(basePath + "settings.txt"); 56 | Settings settings3 = new Settings(); 57 | settings3.loadFromTextFile(basePath + "settings.txt"); 58 | System.out.print("Read from text file: "); 59 | System.out.println(settings3); 60 | } catch (IOException e) { 61 | System.out.println(e.getMessage()); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /labs/sem1/lab7/Settings.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab7; 2 | 3 | import java.io.*; 4 | import java.util.HashMap; 5 | 6 | public class Settings implements Serializable { 7 | // используем HashMap для хранения настроек 8 | private HashMap settings; 9 | 10 | public Settings() { 11 | settings = new HashMap(); 12 | } 13 | 14 | @Override 15 | public boolean equals(Object obj) { 16 | if (obj == this) { 17 | return true; 18 | } 19 | 20 | if (obj == null || obj.getClass() != this.getClass()) { 21 | return false; 22 | } 23 | 24 | Settings settings = (Settings) obj; 25 | return settings.settings.equals(this.settings); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "Settings " + settings.toString(); 31 | } 32 | 33 | public void put(String name, int value) { 34 | settings.put(name, value); 35 | } 36 | 37 | public int get(String name) { 38 | return settings.get(name); 39 | } 40 | 41 | public void delete(String name) { 42 | settings.remove(name); 43 | } 44 | 45 | public void saveToBinaryFile(String filename) throws IOException { 46 | try { 47 | ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename)); 48 | out.writeObject(this); 49 | out.flush(); 50 | out.close(); 51 | } catch (Exception e) { 52 | throw new IOException("Error while saving to binary file: " + e.getMessage()); 53 | } 54 | } 55 | 56 | public void loadFromBinaryFile(String filename) throws IOException { 57 | try { 58 | ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename)); 59 | Settings settings = (Settings) in.readObject(); 60 | in.close(); 61 | this.settings = settings.settings; 62 | } catch (Exception e) { 63 | throw new IOException("Error while loading from binary file: " + e.getMessage()); 64 | } 65 | } 66 | 67 | public void saveToTextFile(String filename) throws IOException { 68 | try { 69 | PrintWriter out = new PrintWriter(new FileWriter(filename)); 70 | out.println(this); 71 | out.flush(); 72 | out.close(); 73 | } catch (Exception e) { 74 | throw new IOException("Error while saving to text file: " + e.getMessage()); 75 | } 76 | } 77 | 78 | public void loadFromTextFile(String filename) throws IOException { 79 | try { 80 | BufferedReader in = new BufferedReader(new FileReader(filename)); 81 | String line = in.readLine(); 82 | in.close(); 83 | this.settings = new HashMap(); 84 | String[] pairs = line.substring(10, line.length() - 1).split(", "); 85 | for (String pair : pairs) { 86 | String[] keyValue = pair.split("="); 87 | this.settings.put(keyValue[0], Integer.parseInt(keyValue[1])); 88 | } 89 | } catch (Exception e) { 90 | throw new IOException("Error while loading from text file: " + e.getMessage()); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /labs/sem1/lab7/library.csv: -------------------------------------------------------------------------------- 1 | The Hitchhiker's Guide to the Galaxy,Douglas Adams,1979 2 | The Lord of the Rings,J. R. R. Tolkien,1954 3 | Harry Potter and the Philosopher's Stone,J. K. Rowling,1997 4 | War and Peace,Leo Tolstoy,1869 5 | The Little Prince,Antoine de Saint-Exupery,1943 6 | -------------------------------------------------------------------------------- /labs/sem1/lab7/settings.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potat-dev/JavaLabs/057fd364ee1d4a95e1530427c24afa630494f671/labs/sem1/lab7/settings.bin -------------------------------------------------------------------------------- /labs/sem1/lab7/settings.txt: -------------------------------------------------------------------------------- 1 | Settings {kek=7, a=1, number=618, b=2, c=3, answer=42} 2 | -------------------------------------------------------------------------------- /labs/sem1/lab8/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab8; 2 | 3 | // Доп: 4 | // Реализуйте многопоточную версию умножения вектора на матрицу. 5 | // Функция умножения в качестве параметра получает число потоков. 6 | // Подберите этот параметр так, что на длине вектора 1000, 7 | // многопоточная версия выиграла у однопоточной 8 | 9 | import labs.sem1.lab5.UsualMatrix; 10 | 11 | public class Dop { 12 | public static void main(String[] args) { 13 | int iters = 200; 14 | int length = 1000; 15 | 16 | // вектор 17 | UsualMatrix a = new UsualMatrix(1, length); 18 | a.randomize(); 19 | 20 | // матриица на которую умножается вектор 21 | UsualMatrix b = new UsualMatrix(length, length); 22 | b.randomize(); 23 | 24 | // массив для результатов 25 | int max_threads = Runtime.getRuntime().availableProcessors(); 26 | UsualMatrix[] results = new UsualMatrix[max_threads + 1]; 27 | 28 | // measure time of execution of matrix multiplication 29 | MeasureTime.measureTime("Standard multiplication", () -> { 30 | results[0] = a.product(b); 31 | }, iters); 32 | 33 | for (int i = 0; i < max_threads; i++) { 34 | final int t = i + 1; 35 | System.out.println("Threads: " + t); 36 | 37 | // create parallel matrix multiplication object 38 | // ParallelMatrixProduct pmp = new ParallelMatrixProduct(t); 39 | ParallelVectorMatrixProduct pvmp = new ParallelVectorMatrixProduct(t); 40 | 41 | // measure time of execution of parallel matrix multiplication 42 | MeasureTime.measureTime( 43 | "Parallel multiplication", () -> { 44 | results[t] = pvmp.product(a, b); 45 | }, iters); 46 | } 47 | 48 | // check if matrices are equal 49 | boolean equal = true; 50 | for (int i = 0; i < max_threads; i++) { 51 | if (!results[0].equals(results[i + 1])) { 52 | equal = false; 53 | break; 54 | } 55 | } 56 | 57 | System.out.println(); 58 | System.out.println("Matrices are equal: " + equal); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /labs/sem1/lab8/Main.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab8; 2 | 3 | // Реализовать класс ParallelMatrixProduct для многопоточного умножения матриц UsualMatrix. В 4 | // конструкторе класс получает число потоков, которые будут использованы для перемножения (число 5 | // потоков может быть меньше, чем число строк у первой матрицы) 6 | 7 | // В функции main сравнить время перемножения больших случайных матриц обычным и многопоточным 8 | // способом. Получить текущее время можно с помощью методов класса System 9 | 10 | import labs.sem1.lab5.UsualMatrix; 11 | 12 | public class Main { 13 | public static void main(String[] args) { 14 | // create matrices 15 | UsualMatrix[] matrices = new UsualMatrix[4]; 16 | for (int i = 0; i < matrices.length; i++) { 17 | matrices[i] = new UsualMatrix(1000); 18 | } 19 | 20 | matrices[0].randomize(); 21 | matrices[1].randomize(); 22 | 23 | // measure time of execution of matrix multiplication 24 | MeasureTime.measureTime( 25 | "Standard multiplication", () -> { 26 | matrices[2] = matrices[0].product(matrices[1]); 27 | }, 10); 28 | 29 | // create parallel matrix multiplication object 30 | // with number of threads equal to number of available processors 31 | ParallelMatrixProduct pmp = new ParallelMatrixProduct(); 32 | 33 | // measure time of execution of parallel matrix multiplication 34 | MeasureTime.measureTime("Parallel multiplication", 35 | () -> { 36 | matrices[3] = pmp.product(matrices[0], matrices[1]); 37 | }, 10); 38 | 39 | // check if matrices are equal 40 | System.out.println("Matrices are equal: " + matrices[2].equals(matrices[3])); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /labs/sem1/lab8/MeasureTime.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab8; 2 | 3 | // class for measuring time of execution of a function 4 | class MeasureTime { 5 | public static void measureTime(String message, Runnable runnable, int times) { 6 | System.out.print("Measuring " + message + " " + times + " times... "); 7 | 8 | long start = System.currentTimeMillis(); 9 | for (int i = 0; i < times; i++) { 10 | runnable.run(); 11 | } 12 | long end = System.currentTimeMillis(); 13 | long time = (end - start) / times; 14 | 15 | System.out.println("done"); 16 | System.out.println(message + " time: " + time + " ms"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /labs/sem1/lab8/ParallelMatrixProduct.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab8; 2 | 3 | import labs.sem1.lab5.UsualMatrix; 4 | 5 | public class ParallelMatrixProduct { 6 | private Thread[] threads; 7 | 8 | public ParallelMatrixProduct(int threadsCount) { 9 | threads = new Thread[threadsCount]; 10 | } 11 | 12 | public ParallelMatrixProduct() { 13 | // get number of available processors 14 | int threadsCount = Runtime.getRuntime().availableProcessors(); 15 | threads = new Thread[threadsCount]; 16 | } 17 | 18 | // method for parallel matrix multiplication 19 | public UsualMatrix product(UsualMatrix m1, UsualMatrix m2) { 20 | if (m1.getColumns() != m2.getRows()) { 21 | throw new IllegalArgumentException("Matrix sizes are not equal"); 22 | } 23 | 24 | UsualMatrix result = new UsualMatrix(m1.getRows(), m2.getColumns()); 25 | 26 | // create threads 27 | for (int i = 0; i < threads.length; i++) { 28 | int startRow = i * m1.getRows() / threads.length; 29 | int endRow = (i + 1) * m1.getRows() / threads.length; 30 | threads[i] = new Thread(new MatrixProductJob(i, m1, m2, result, startRow, endRow)); 31 | threads[i].start(); 32 | } 33 | 34 | // wait for threads to finish 35 | for (int i = 0; i < threads.length; i++) { 36 | try { 37 | threads[i].join(); 38 | } catch (InterruptedException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | 43 | return result; 44 | } 45 | } 46 | 47 | class MatrixProductJob implements Runnable { 48 | UsualMatrix m1; 49 | UsualMatrix m2; 50 | UsualMatrix result; 51 | int startRow; 52 | int endRow; 53 | 54 | public MatrixProductJob( 55 | int id, UsualMatrix m1, UsualMatrix m2, UsualMatrix result, int startRow, int endRow) { 56 | this.m1 = m1; 57 | this.m2 = m2; 58 | this.result = result; 59 | this.startRow = startRow; 60 | this.endRow = endRow; 61 | } 62 | 63 | public void run() { 64 | for (int i = startRow; i < endRow; i++) { 65 | for (int j = 0; j < m2.getColumns(); j++) { 66 | double sum = 0; 67 | for (int k = 0; k < m1.getColumns(); k++) { 68 | sum += m1.getElement(i, k) * m2.getElement(k, j); 69 | } 70 | result.setElement(i, j, sum); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /labs/sem1/lab8/ParallelVectorMatrixProduct.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab8; 2 | 3 | import labs.sem1.lab5.UsualMatrix; 4 | 5 | // класс для умножения вектора на матрицу. 6 | // в нем, в отличие от класса ParallelMatrixProduct, 7 | // распараллеливание происходит не по строкам матрицы, а по столбцам 8 | // вектор представляется в виде матрицы, у которой одна строка 9 | 10 | class ParallelVectorMatrixProduct { 11 | private Thread[] threads; 12 | 13 | public ParallelVectorMatrixProduct(int threadsCount) { 14 | threads = new Thread[threadsCount]; 15 | } 16 | 17 | public ParallelVectorMatrixProduct() { 18 | // get number of available processors 19 | int threadsCount = Runtime.getRuntime().availableProcessors(); 20 | threads = new Thread[threadsCount]; 21 | } 22 | 23 | // method for parallel matrix multiplication 24 | // вектор представляется в виде матрицы, у которой один столбец 25 | public UsualMatrix product(UsualMatrix m1, UsualMatrix m2) { 26 | if (m1.getColumns() != m2.getRows()) { 27 | throw new IllegalArgumentException("Matrix sizes are not equal"); 28 | } 29 | 30 | UsualMatrix result = new UsualMatrix(m1.getRows(), m2.getColumns()); 31 | 32 | // create threads 33 | for (int i = 0; i < threads.length; i++) { 34 | int startColumn = i * m2.getColumns() / threads.length; 35 | int endColumn = (i + 1) * m2.getColumns() / threads.length; 36 | threads[i] = new Thread(new VectorMatrixProductJob(i, m1, m2, result, startColumn, endColumn)); 37 | threads[i].start(); 38 | } 39 | 40 | // wait for threads to finish 41 | for (int i = 0; i < threads.length; i++) { 42 | try { 43 | threads[i].join(); 44 | } catch (InterruptedException e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | 49 | return result; 50 | } 51 | } 52 | 53 | class VectorMatrixProductJob implements Runnable { 54 | UsualMatrix m1; 55 | UsualMatrix m2; 56 | UsualMatrix result; 57 | int startColumn; 58 | int endColumn; 59 | 60 | public VectorMatrixProductJob( 61 | int id, UsualMatrix m1, UsualMatrix m2, UsualMatrix result, int startColumn, int endColumn) { 62 | this.m1 = m1; 63 | this.m2 = m2; 64 | this.result = result; 65 | this.startColumn = startColumn; 66 | this.endColumn = endColumn; 67 | } 68 | 69 | public void run() { 70 | for (int i = 0; i < m1.getRows(); i++) { 71 | for (int j = startColumn; j < endColumn; j++) { 72 | double sum = 0; 73 | for (int k = 0; k < m1.getColumns(); k++) { 74 | sum += m1.getElement(i, k) * m2.getElement(k, j); 75 | } 76 | result.setElement(i, j, sum); 77 | } 78 | } 79 | } 80 | } 81 | 82 | // TODO: 83 | // можно создать класс MatrixProduct, который будет автоматически выбирать 84 | // какой метод распараллеливания использовать: по строкам или по столбцам, в 85 | // зависимости от размера матрицы -------------------------------------------------------------------------------- /labs/sem1/lab9/Deadlock.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab9; 2 | 3 | // Написать программу, приводящую к ситуации взаимной блокировки (deadlock) 4 | 5 | public class Deadlock { 6 | private static Object lock1 = new Object(); 7 | private static Object lock2 = new Object(); 8 | 9 | public static void main(String[] args) { 10 | Thread1 t1 = new Thread1(); 11 | Thread2 t2 = new Thread2(); 12 | 13 | t1.start(); 14 | t2.start(); 15 | 16 | try { 17 | t1.join(); 18 | t2.join(); 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | 23 | System.out.println("Main thread finished"); // never reached 24 | } 25 | 26 | static class Thread1 extends Thread { 27 | public void run() { 28 | synchronized (lock1) { 29 | System.out.println("Thread 1: Holding lock 1"); 30 | try { 31 | Thread.sleep(10); 32 | } catch (InterruptedException e) { 33 | System.out.println("Thread 1: Interrupted"); 34 | } 35 | System.out.println("Thread 1: Waiting for lock 2"); 36 | 37 | // deadlock here 38 | synchronized (lock2) { 39 | System.out.println("Thread 1: Holding lock 1 & 2"); // never reached 40 | } 41 | } 42 | System.out.println("Thread 1: Released lock 1 & 2"); // never reached 43 | } 44 | } 45 | 46 | static class Thread2 extends Thread { 47 | public void run() { 48 | synchronized (lock2) { 49 | System.out.println("Thread 2: Holding lock 2"); 50 | try { 51 | Thread.sleep(10); 52 | } catch (InterruptedException e) { 53 | System.out.println("Thread 2: Interrupted"); 54 | } 55 | System.out.println("Thread 2: Waiting for lock 1"); 56 | 57 | // deadlock here 58 | synchronized (lock1) { 59 | System.out.println("Thread 2: Holding lock 1 & 2"); // never reached 60 | } 61 | } 62 | System.out.println("Thread 2: Released lock 1 & 2"); // never reached 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /labs/sem1/lab9/Dop.java: -------------------------------------------------------------------------------- 1 | package labs.sem1.lab9; 2 | 3 | // Доп: 4 | // Реализовать программу, которая подсчитывает статистику употребления слов в заданных текстовых 5 | // файлах. Программа получает список текстовых файлов в качестве параметров командной строки. Каждый 6 | // файл должен обрабатываться в отдельном потоке. Для подсчета числа уникальных слов используется 7 | // общий для всех потоков HashMaр (ключ - слово, значение - количество употреблений) 8 | 9 | import java.io.BufferedReader; 10 | import java.io.File; 11 | import java.io.FileReader; 12 | import java.util.Collections; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | import java.util.Map.Entry; 16 | import java.util.stream.Stream; 17 | 18 | public class Dop { 19 | public static void main(String[] args) { 20 | if (args.length < 1) { 21 | System.out.println("No files to process"); 22 | return; 23 | } 24 | 25 | // try to open all files 26 | WordCounter counter = new WordCounter(); 27 | FileProcessor[] processors = new FileProcessor[args.length]; 28 | 29 | for (int i = 0; i < args.length; i++) { 30 | processors[i] = new FileProcessor(args[i], counter); 31 | processors[i].start(); 32 | } 33 | 34 | // wait for all threads to finish 35 | try { 36 | for (int i = 0; i < args.length; i++) { 37 | processors[i].join(); 38 | } 39 | } catch (Exception e) { 40 | System.out.println("Error while waiting for threads"); 41 | } 42 | 43 | // get top 25 words 44 | counter.descending().limit(25).print(); 45 | System.out.println(); 46 | 47 | // get top 50 words with count > 100 48 | counter.descending().largerThan(100).limit(50).print(); 49 | System.out.println(); 50 | 51 | // get all words with count > 100 (accending) 52 | counter.ascending().largerThan(100).print(); 53 | System.out.println(); 54 | } 55 | } 56 | 57 | class WordCounter { 58 | private HashMap map = new HashMap<>(); 59 | 60 | // settings for pretty print 61 | private int limit = 0; 62 | private int largerThan = 0; 63 | private boolean reverse = true; 64 | 65 | // add word to HashMap 66 | public synchronized void add(String word) { 67 | if (map.containsKey(word)) { 68 | map.put(word, map.get(word) + 1); 69 | } else { 70 | map.put(word, 1); 71 | } 72 | } 73 | 74 | public WordCounter largerThan(int n) { 75 | largerThan = n; 76 | return this; 77 | } 78 | 79 | public WordCounter limit(int n) { 80 | limit = n; 81 | return this; 82 | } 83 | 84 | // по возрастанию 85 | public WordCounter ascending() { 86 | reverse = false; 87 | return this; 88 | } 89 | 90 | // по убыванию 91 | public WordCounter descending() { 92 | reverse = true; 93 | return this; 94 | } 95 | 96 | public void print() { 97 | if (map.size() == 0) { 98 | System.out.println("No words found"); 99 | return; 100 | } 101 | 102 | StringBuilder builder = new StringBuilder(); 103 | if (limit > 0 || largerThan > 0) { 104 | builder.append(String.format("")); 105 | } else { 106 | builder.append("All words"); 107 | } 108 | 109 | Stream> result = map.entrySet().stream(); 110 | 111 | // filter map to get only words with value >= largerThan 112 | result = result.filter(entry -> entry.getValue() >= largerThan); 113 | 114 | // sort by value 115 | result = result.sorted(reverse ? Collections.reverseOrder(Map.Entry.comparingByValue()) 116 | : Map.Entry.comparingByValue()); 117 | 118 | if (limit > 0) 119 | result = result.limit(limit); 120 | 121 | result.forEach( 122 | entry -> builder.append(String.format("(%d) %s\n", entry.getValue(), entry.getKey()))); 123 | 124 | // String info = "Words 125 | 126 | System.out.println(builder.toString()); 127 | } 128 | } 129 | 130 | class FileProcessor extends Thread { 131 | private WordCounter counter; // ссылка на общий счетчик 132 | private BufferedReader reader; 133 | 134 | public FileProcessor(String fileName, WordCounter counter) { 135 | this.counter = counter; 136 | try { 137 | this.reader = new BufferedReader(new FileReader(new File(fileName))); 138 | } catch (Exception e) { 139 | System.out.println("Error while opening file " + fileName); 140 | } 141 | } 142 | 143 | private String[] cleanUp(String[] words) { 144 | for (int i = 0; i < words.length; i++) { 145 | // remove all except letters, dashes and apostrophes 146 | // remove dashes from start and end of word 147 | // remove leading and trailing spaces 148 | words[i] = words[i].toLowerCase().replaceAll("[^a-zа-яё'-]", ""); 149 | words[i] = words[i].replaceAll("^-|-$", "").trim(); 150 | } 151 | // remove empty strings 152 | words = Stream.of(words).filter(word -> !word.isEmpty()).toArray(String[]::new); 153 | return words; 154 | } 155 | 156 | @Override 157 | public void run() { 158 | // read file line by line 159 | String line; 160 | 161 | try { 162 | while ((line = reader.readLine()) != null) { 163 | String[] words = line.split(" "); 164 | for (String word : cleanUp(words)) { 165 | counter.add(word); 166 | } 167 | } 168 | } catch (Exception e) { 169 | System.out.println("Error while reading file"); 170 | } 171 | 172 | // System.out.println("Thread " + this.getId() + " finished"); 173 | } 174 | } -------------------------------------------------------------------------------- /labs/sem2/lab11/Server.java: -------------------------------------------------------------------------------- 1 | package labs.sem2.lab11; 2 | 3 | import java.io.*; 4 | import java.net.*; 5 | 6 | // Better optimized version is in /dop 7 | 8 | public class Server { 9 | private static InetAddress clientAddress; 10 | private static int clientPort; 11 | private static String chatMateName = "Client"; 12 | 13 | public static void main(String args[]) throws Exception { 14 | if (args.length != 1) { 15 | System.out.println("Usage: java Server "); 16 | return; 17 | } 18 | 19 | int port = Integer.parseInt(args[0]); 20 | InetAddress tempAdr = InetAddress.getByName("localhost"); 21 | DatagramSocket serverSocket = new DatagramSocket(port, tempAdr); 22 | byte[] receiveData = new byte[1024]; 23 | 24 | System.out.println("Server is running on port: " + port); 25 | 26 | // Создаем поток для приема сообщений от клиента 27 | Thread receiveThread = new Thread(() -> { 28 | while (true) { 29 | try { 30 | DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 31 | serverSocket.receive(receivePacket); 32 | 33 | String receivedMessage = new String(receivePacket.getData(), 0, receivePacket.getLength()); 34 | if (receivedMessage.startsWith("")) { 35 | clientPort = receivePacket.getPort(); 36 | clientAddress = receivePacket.getAddress(); 37 | } 38 | 39 | else if (receivedMessage.startsWith("")) { 40 | chatMateName = receivedMessage.substring(5); 41 | } 42 | 43 | else if (receivedMessage.startsWith("")) { 44 | String userMessage = receivedMessage.substring(5); 45 | if (chatMateName.isEmpty()) 46 | System.out.println("Received: " + userMessage); 47 | else 48 | System.out.println(chatMateName + ": " + userMessage); 49 | } 50 | 51 | else { 52 | System.out.println("Received unsupported packet"); 53 | } 54 | 55 | } catch (IOException e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | }); 60 | 61 | receiveThread.start(); 62 | 63 | // Создаем поток для отправки сообщений клиенту 64 | Thread sendThread = new Thread(() -> { 65 | try { 66 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 67 | 68 | while (true) { 69 | String message = reader.readLine(); 70 | 71 | if (message.equals("@q")) { 72 | serverSocket.close(); 73 | System.exit(0); 74 | break; 75 | } 76 | 77 | else if (message.startsWith("@name ")) { 78 | // Установка имени пользователя 79 | String username = message.substring(6); 80 | String tempMessage = "" + username; 81 | byte[] sendData = tempMessage.getBytes(); 82 | DatagramPacket sendPacket = new DatagramPacket( 83 | sendData, sendData.length, clientAddress, clientPort); 84 | serverSocket.send(sendPacket); 85 | } 86 | 87 | else { 88 | message = "" + message; 89 | byte[] sendData = message.getBytes(); 90 | DatagramPacket sendPacket = new DatagramPacket( 91 | sendData, sendData.length, clientAddress, clientPort); 92 | serverSocket.send(sendPacket); 93 | } 94 | } 95 | 96 | } catch (IOException e) { 97 | e.printStackTrace(); 98 | } 99 | }); 100 | 101 | sendThread.start(); 102 | } 103 | } -------------------------------------------------------------------------------- /labs/sem2/lab11/dop/Server.java: -------------------------------------------------------------------------------- 1 | package labs.sem2.lab11.dop; 2 | 3 | import java.io.*; 4 | import java.net.*; 5 | 6 | public class Server { 7 | private static InetAddress clientAddress; 8 | private static int clientPort; 9 | private static String chatMateName = "Client"; 10 | public static DatagramSocket serverSocket; 11 | 12 | private static String currentDir = System.getProperty("user.dir"); 13 | 14 | public static void main(String args[]) throws Exception { 15 | if (args.length != 1) { 16 | System.out.println("Usage: java Server "); 17 | return; 18 | } 19 | 20 | int port = Integer.parseInt(args[0]); 21 | InetAddress tempAdr = InetAddress.getByName("localhost"); 22 | serverSocket = new DatagramSocket(port, tempAdr); 23 | System.out.println("Server is running on port: " + port); 24 | 25 | // Создаем поток для приема сообщений от клиента 26 | Thread receiveThread = new ReceiveThread(serverSocket); 27 | receiveThread.start(); 28 | 29 | // Создаем поток для отправки сообщений клиенту 30 | Thread sendThread = new SendThread(serverSocket); 31 | sendThread.start(); 32 | } 33 | 34 | private static void sendPacket(DatagramSocket sock, InetAddress addr, int port, String msg) throws IOException { 35 | byte[] sendData = msg.getBytes(); 36 | DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, addr, port); 37 | sock.send(sendPacket); 38 | } 39 | 40 | private static class ReceiveThread extends Thread { 41 | private DatagramSocket serverSocket; 42 | 43 | public ReceiveThread(DatagramSocket serverSocket) { 44 | this.serverSocket = serverSocket; 45 | } 46 | 47 | @Override 48 | public void run() { 49 | byte[] receiveData = new byte[1024]; 50 | 51 | try { 52 | while (true) { 53 | DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 54 | serverSocket.receive(receivePacket); 55 | 56 | String receivedMessage = new String(receivePacket.getData(), 0, receivePacket.getLength()); 57 | if (receivedMessage.startsWith("")) { 58 | clientPort = receivePacket.getPort(); 59 | clientAddress = receivePacket.getAddress(); 60 | } 61 | 62 | else if (receivedMessage.startsWith("")) { 63 | chatMateName = receivedMessage.substring(6); 64 | } 65 | 66 | else if (receivedMessage.startsWith("")) { 67 | String command = receivedMessage.substring(5); 68 | System.out.println("Command output: " + command); 69 | 70 | String result = ""; 71 | if (command.equals("LS")) { 72 | File dir = new File(currentDir); 73 | File[] files = dir.listFiles(); 74 | 75 | StringBuilder sb = new StringBuilder(); 76 | 77 | if (files != null) { 78 | for (File file : files) { 79 | sb.append(file.getName()).append("\n"); 80 | } 81 | } 82 | 83 | result = sb.toString(); 84 | } 85 | 86 | else if (command.equals("PWD")) { 87 | result = currentDir; 88 | } 89 | 90 | else if (command.startsWith("CD ")) { 91 | String directory = command.substring(3); 92 | currentDir = directory; 93 | result = directory; 94 | } 95 | 96 | String answer = "" + result; 97 | sendPacket(serverSocket, clientAddress, clientPort, answer); 98 | } 99 | 100 | else if (receivedMessage.startsWith("")) { 101 | String userMessage = receivedMessage.substring(5); 102 | System.out.println(chatMateName + ": " + userMessage); 103 | } 104 | 105 | else { 106 | System.out.println("Received unsupported packet"); 107 | } 108 | } 109 | 110 | } catch (IOException e) { 111 | e.printStackTrace(); 112 | } finally { 113 | serverSocket.close(); 114 | } 115 | } 116 | } 117 | 118 | private static class SendThread extends Thread { 119 | private DatagramSocket serverSocket; 120 | 121 | public SendThread(DatagramSocket serverSocket) { 122 | this.serverSocket = serverSocket; 123 | } 124 | 125 | @Override 126 | public void run() { 127 | try { 128 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 129 | 130 | while (true) { 131 | String message = reader.readLine(); 132 | 133 | if (message.equals("@q")) { 134 | serverSocket.close(); 135 | System.exit(0); 136 | break; 137 | } 138 | 139 | else if (message.startsWith("@name ")) { 140 | String username = message.substring(6); 141 | String answer = "" + username; 142 | sendPacket(serverSocket, clientAddress, clientPort, answer); 143 | } 144 | 145 | else if (message.equals("@pwd")) { 146 | String answer = "PWD"; 147 | sendPacket(serverSocket, clientAddress, clientPort, answer); 148 | } 149 | 150 | else if (message.equals("@ls")) { 151 | String answer = "LS"; 152 | sendPacket(serverSocket, clientAddress, clientPort, answer); 153 | } 154 | 155 | else if (message.startsWith("@cd ")) { 156 | String directory = message.substring(4); 157 | String answer = "CD " + directory; 158 | sendPacket(serverSocket, clientAddress, clientPort, answer); 159 | } 160 | 161 | else { 162 | String answer = "" + message; 163 | sendPacket(serverSocket, clientAddress, clientPort, answer); 164 | } 165 | } 166 | 167 | } catch (IOException e) { 168 | e.printStackTrace(); 169 | } finally { 170 | serverSocket.close(); 171 | } 172 | } 173 | } 174 | } -------------------------------------------------------------------------------- /labs/sem2/lab12/Client.java: -------------------------------------------------------------------------------- 1 | package labs.sem2.lab12; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.PrintWriter; 7 | import java.net.Socket; 8 | 9 | public class Client { 10 | public static void main(String[] args) throws IOException { 11 | if (args.length < 1 || args.length > 2) { 12 | System.out.println("Usage: java Client "); 13 | System.out.println("or: java Client (when running locally)"); 14 | return; 15 | } 16 | 17 | if (args.length == 1) { 18 | args = new String[] { "localhost", args[0] }; 19 | } 20 | 21 | String host = args[0]; 22 | int port = Integer.parseInt(args[1]); 23 | 24 | Socket socket = new Socket(host, port); 25 | System.out.println("Connected to server on port " + port); 26 | 27 | BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); 28 | BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 29 | PrintWriter socketOut = new PrintWriter(socket.getOutputStream(), true); 30 | 31 | System.out.println("Enter your name:"); 32 | String name = console.readLine(); 33 | socketOut.println(name); 34 | 35 | Thread receiver = new ReceiveThread(socketIn); 36 | receiver.start(); 37 | 38 | Thread sender = new SendThread(socketOut, console); 39 | sender.start(); 40 | } 41 | 42 | private static class ReceiveThread extends Thread { 43 | private BufferedReader socketIn; 44 | 45 | public ReceiveThread(BufferedReader socketIn) { 46 | this.socketIn = socketIn; 47 | } 48 | 49 | @Override 50 | public void run() { 51 | try { 52 | while (true) { 53 | String message = socketIn.readLine(); 54 | if (message == null) { 55 | System.out.println("Server closed connection"); 56 | socketIn.close(); 57 | System.exit(0); 58 | } else { 59 | System.out.println(message); 60 | } 61 | } 62 | } catch (IOException e) { 63 | e.printStackTrace(); 64 | } 65 | } 66 | } 67 | 68 | private static class SendThread extends Thread { 69 | private PrintWriter socketOut; 70 | private BufferedReader console; 71 | 72 | public SendThread(PrintWriter socketOut, BufferedReader console) { 73 | this.socketOut = socketOut; 74 | this.console = console; 75 | } 76 | 77 | @Override 78 | public void run() { 79 | try { 80 | while (true) { 81 | String message = console.readLine(); 82 | socketOut.println(message); 83 | if (message.equals("@exit")) { 84 | socketOut.close(); 85 | System.exit(0); 86 | } 87 | } 88 | } catch (IOException e) { 89 | e.printStackTrace(); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /labs/sem2/lab12/Server.java: -------------------------------------------------------------------------------- 1 | package labs.sem2.lab12; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.PrintWriter; 7 | import java.net.Socket; 8 | import java.net.ServerSocket; 9 | import java.util.List; 10 | import java.util.ArrayList; 11 | 12 | public class Server { 13 | private static List connections = new ArrayList<>(); 14 | 15 | public static void main(String[] args) throws IOException { 16 | if (args.length != 1) { 17 | System.out.println("Usage: java Server "); 18 | return; 19 | } 20 | 21 | int port = Integer.parseInt(args[0]); 22 | 23 | ServerSocket serverSocket = new ServerSocket(port); 24 | System.out.println("Server started on port " + port); 25 | 26 | while (true) { 27 | Socket clientSocket = serverSocket.accept(); 28 | Connection connection = new Connection(clientSocket); 29 | connections.add(connection); 30 | connection.start(); 31 | } 32 | } 33 | 34 | private static class Connection extends Thread { 35 | private Socket clientSocket; 36 | private BufferedReader in; 37 | private PrintWriter out; 38 | private String name; 39 | 40 | public Connection(Socket clientSocket) throws IOException { 41 | this.clientSocket = clientSocket; 42 | in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 43 | out = new PrintWriter(clientSocket.getOutputStream(), true); 44 | } 45 | 46 | public void sendToAll(String message) { 47 | for (Connection connection : connections) { 48 | connection.out.println(message); 49 | } 50 | } 51 | 52 | public void sendToUser(String username, String message) { 53 | for (Connection connection : connections) { 54 | if (connection.name.equals(username)) { 55 | connection.out.println(message); 56 | } 57 | } 58 | } 59 | 60 | @Override 61 | public void run() { 62 | try { 63 | name = in.readLine(); 64 | sendToAll(name + " joined the chat!"); 65 | 66 | while (true) { 67 | String message = in.readLine(); 68 | 69 | if (message.equals("@exit")) { 70 | break; 71 | } 72 | 73 | else if (message.startsWith("@senduser ")) { 74 | String username = message.substring(10); 75 | String tempMessage = in.readLine(); 76 | sendToUser(username, name + " [private]: " + tempMessage); 77 | } 78 | 79 | else { 80 | sendToAll(name + ": " + message); 81 | } 82 | } 83 | 84 | sendToAll(name + " left the chat!"); 85 | } 86 | 87 | catch (IOException e) { 88 | e.printStackTrace(); 89 | } 90 | 91 | finally { 92 | try { 93 | clientSocket.close(); 94 | in.close(); 95 | out.close(); 96 | } catch (IOException e) { 97 | e.printStackTrace(); 98 | } finally { 99 | connections.remove(this); 100 | } 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /labs/sem2/lab12/dop/Client.java: -------------------------------------------------------------------------------- 1 | package labs.sem2.lab12.dop; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.PrintWriter; 7 | import java.net.Socket; 8 | 9 | public class Client { 10 | public static void main(String[] args) throws IOException { 11 | if (args.length < 1 || args.length > 2) { 12 | System.out.println("Usage: java Client "); 13 | System.out.println("or: java Client (when running locally)"); 14 | return; 15 | } 16 | 17 | if (args.length == 1) { 18 | args = new String[] { "localhost", args[0] }; 19 | } 20 | 21 | String host = args[0]; 22 | int port = Integer.parseInt(args[1]); 23 | 24 | Socket socket = new Socket(host, port); 25 | System.out.println("Connected to server on port " + port); 26 | 27 | BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); 28 | BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 29 | PrintWriter socketOut = new PrintWriter(socket.getOutputStream(), true); 30 | 31 | System.out.println("Enter your name:"); 32 | String name = console.readLine(); 33 | socketOut.println(name); 34 | 35 | Thread receiver = new ReceiveThread(socketIn); 36 | receiver.start(); 37 | 38 | Thread sender = new SendThread(socketOut, console); 39 | sender.start(); 40 | } 41 | 42 | private static class ReceiveThread extends Thread { 43 | private BufferedReader socketIn; 44 | 45 | public ReceiveThread(BufferedReader socketIn) { 46 | this.socketIn = socketIn; 47 | } 48 | 49 | @Override 50 | public void run() { 51 | try { 52 | while (true) { 53 | String message = socketIn.readLine(); 54 | if (message == null) { 55 | System.out.println("Server closed connection"); 56 | socketIn.close(); 57 | System.exit(0); 58 | } else { 59 | System.out.println(message); 60 | } 61 | } 62 | } catch (IOException e) { 63 | e.printStackTrace(); 64 | } 65 | } 66 | } 67 | 68 | private static class SendThread extends Thread { 69 | private PrintWriter socketOut; 70 | private BufferedReader console; 71 | 72 | public SendThread(PrintWriter socketOut, BufferedReader console) { 73 | this.socketOut = socketOut; 74 | this.console = console; 75 | } 76 | 77 | @Override 78 | public void run() { 79 | try { 80 | while (true) { 81 | String message = console.readLine(); 82 | socketOut.println(message); 83 | if (message.equals("@exit")) { 84 | socketOut.close(); 85 | System.exit(0); 86 | } 87 | } 88 | } catch (IOException e) { 89 | e.printStackTrace(); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /labs/sem2/lab12/dop/Server.java: -------------------------------------------------------------------------------- 1 | package labs.sem2.lab12.dop; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.PrintWriter; 7 | import java.net.Socket; 8 | import java.net.ServerSocket; 9 | import java.util.List; 10 | import java.util.ArrayList; 11 | 12 | // TODO: add @admin and @ban commands 13 | // @admin - gives admin rights to the user 14 | // there can be only one admin at a time 15 | // @ban - bans the user from the chat 16 | // banned users can't send messages to the chat 17 | // only admins can ban users 18 | 19 | public class Server { 20 | private static List connections = new ArrayList<>(); 21 | 22 | // banned users 23 | private static List banned = new ArrayList<>(); 24 | 25 | // current admin 26 | private static String admin = null; 27 | 28 | // admin password 29 | private static final String password = "xxXX1234"; 30 | 31 | public static void main(String[] args) throws IOException { 32 | if (args.length != 1) { 33 | System.out.println("Usage: java Server "); 34 | return; 35 | } 36 | 37 | int port = Integer.parseInt(args[0]); 38 | 39 | ServerSocket serverSocket = new ServerSocket(port); 40 | System.out.println("Server started on port " + port); 41 | 42 | while (true) { 43 | Socket clientSocket = serverSocket.accept(); 44 | Connection connection = new Connection(clientSocket); 45 | connections.add(connection); 46 | connection.start(); 47 | } 48 | } 49 | 50 | private static class Connection extends Thread { 51 | private Socket clientSocket; 52 | private BufferedReader in; 53 | private PrintWriter out; 54 | private String name; 55 | 56 | public Connection(Socket clientSocket) throws IOException { 57 | this.clientSocket = clientSocket; 58 | in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 59 | out = new PrintWriter(clientSocket.getOutputStream(), true); 60 | } 61 | 62 | public void sendToAll(String message) { 63 | for (Connection connection : connections) { 64 | connection.out.println(message); 65 | } 66 | } 67 | 68 | public void sendToUser(String username, String message) { 69 | for (Connection connection : connections) { 70 | if (connection.name.equals(username)) { 71 | connection.out.println(message); 72 | } 73 | } 74 | } 75 | 76 | @Override 77 | public void run() { 78 | try { 79 | name = in.readLine(); 80 | sendToAll(name + " joined the chat!"); 81 | 82 | while (true) { 83 | String message = in.readLine(); 84 | 85 | if (message.equals("@exit")) { 86 | break; 87 | } 88 | 89 | else if (message.startsWith("@senduser ")) { 90 | String username = message.substring(10); 91 | String tempMessage = in.readLine(); 92 | sendToUser(username, name + " [private]: " + tempMessage); 93 | } 94 | 95 | else if (message.startsWith("@admin ")) { 96 | if (admin != null) { 97 | sendToUser(name, "Admin is already exist!"); 98 | continue; 99 | } 100 | 101 | String tempPassword = message.substring(7); 102 | if (tempPassword.equals(password)) { 103 | admin = name; 104 | sendToAll(name + " is now admin!"); 105 | } 106 | 107 | else { 108 | sendToUser(name, "Wrong password!"); 109 | } 110 | } 111 | 112 | else if (message.startsWith("@ban ")) { 113 | String username = message.substring(5); 114 | if (admin == null) { 115 | sendToUser(name, "You are not admin!"); 116 | } else if (admin.equals(name)) { 117 | banned.add(username); 118 | sendToAll(username + " was banned by " + name); 119 | } else { 120 | sendToUser(name, "You are not admin!"); 121 | } 122 | } 123 | 124 | else if (banned.contains(name)) { 125 | sendToUser(name, "You are banned!"); 126 | } 127 | 128 | else { 129 | sendToAll(name + ": " + message); 130 | } 131 | } 132 | 133 | sendToAll(name + " left the chat!"); 134 | } 135 | 136 | catch (IOException e) { 137 | e.printStackTrace(); 138 | } 139 | 140 | finally { 141 | try { 142 | clientSocket.close(); 143 | in.close(); 144 | out.close(); 145 | } catch (IOException e) { 146 | e.printStackTrace(); 147 | } finally { 148 | connections.remove(this); 149 | } 150 | } 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /servlets/lab13/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'war' 4 | id "io.freefair.lombok" version "8.4" 5 | } 6 | 7 | apply from: 'https://raw.github.com/gretty-gradle-plugin/gretty/master/pluginScripts/gretty.plugin' 8 | 9 | group 'dev.potat.servlets' 10 | version '1.0-SNAPSHOT' 11 | 12 | repositories { 13 | mavenCentral() 14 | } 15 | 16 | ext { 17 | junitVersion = '5.10.0' 18 | } 19 | 20 | sourceCompatibility = '11' 21 | targetCompatibility = '11' 22 | 23 | tasks.withType(JavaCompile) { 24 | options.encoding = 'UTF-8' 25 | } 26 | 27 | dependencies { 28 | compileOnly('jakarta.servlet:jakarta.servlet-api:5.0.0') 29 | implementation("com.fasterxml.jackson.core:jackson-databind:2.15.2") 30 | implementation("org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1") 31 | implementation("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0") 32 | 33 | testImplementation('org.junit.jupiter:junit-jupiter:5.8.1') 34 | testImplementation('org.junit.jupiter:junit-jupiter:5.8.1') 35 | 36 | testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}") 37 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}") 38 | } 39 | 40 | test { 41 | useJUnitPlatform() 42 | } -------------------------------------------------------------------------------- /servlets/lab13/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potat-dev/JavaLabs/057fd364ee1d4a95e1530427c24afa630494f671/servlets/lab13/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /servlets/lab13/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /servlets/lab13/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /servlets/lab13/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "lab13" -------------------------------------------------------------------------------- /servlets/lab13/src/main/java/dev/potat/servlets/lab13/AddressBook.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab13; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | import lombok.NonNull; 6 | 7 | import java.util.ArrayList; 8 | import java.util.regex.Pattern; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | public class AddressBook { 13 | private static final Pattern nameRegex = Pattern.compile("^[a-zA-Z]{2,}([-_ .][a-zA-Z]{2,}){0,2}$"); 14 | private static final Pattern phoneRegex = Pattern.compile("^\\+?[(]?[0-9]{3}[)]?[-\\s.]?[0-9]{3}[-\\s.]?[0-9]{4,6}$"); 15 | 16 | private ArrayList contacts = new ArrayList<>(); 17 | 18 | public Contact getContact(@NonNull String name) { 19 | for (Contact contact : contacts) { 20 | if (contact.getName().equals(name)) { 21 | return contact; 22 | } 23 | } 24 | return null; 25 | } 26 | 27 | public void addContact(Contact contact) { 28 | contacts.add(contact); 29 | } 30 | 31 | public UpdateStatus update(String name, String phone) { 32 | if (!safetyCheck(name, phone)) return UpdateStatus.DECLINED; 33 | Contact contact = getContact(name); 34 | if (contact != null) { 35 | contact.addPhone(phone); 36 | return UpdateStatus.UPDATED; 37 | } else { 38 | addContact(new Contact(name, phone)); 39 | return UpdateStatus.CREATED; 40 | } 41 | } 42 | 43 | public UpdateStatus remove(String name, String phone) { 44 | Contact contact = getContact(name); 45 | if (contact == null) return UpdateStatus.NOT_EXIST; 46 | 47 | if (phone.isBlank() || phone.isEmpty()) { 48 | contacts.remove(contact); 49 | return UpdateStatus.CONTACT_REMOVED; 50 | } else { 51 | if (contact.getPhones().contains(phone)) { 52 | contact.removePhone(phone); 53 | return UpdateStatus.PHONE_REMOVED; 54 | } else { 55 | return UpdateStatus.NOT_EXIST; 56 | } 57 | } 58 | } 59 | 60 | private boolean safetyCheck(String name, String phone) { 61 | if (name.isBlank() || name.length() > 50 || phone.isBlank() || phone.length() > 16) return false; 62 | return true; 63 | } 64 | 65 | public enum UpdateStatus { 66 | CREATED, UPDATED, DECLINED, NOT_EXIST, CONTACT_REMOVED, PHONE_REMOVED 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/java/dev/potat/servlets/lab13/AddressBookStore.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab13; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import dev.potat.servlets.lab13.AddressBook.UpdateStatus; 5 | import lombok.Synchronized; 6 | import lombok.ToString; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | 11 | @ToString 12 | public class AddressBookStore { 13 | private static volatile AddressBookStore instance; 14 | 15 | private AddressBook addressBook = new AddressBook(); 16 | 17 | @ToString.Exclude 18 | private final ObjectMapper objectMapper = new ObjectMapper(); 19 | 20 | @ToString.Exclude 21 | private final File database; 22 | 23 | public AddressBookStore(String databasePath) { 24 | this.database = new File(databasePath); 25 | try { 26 | this.database.createNewFile(); 27 | } catch (IOException e) { 28 | throw new RuntimeException(e); 29 | } 30 | } 31 | 32 | public static AddressBookStore getInstance(String databasePath) { 33 | if (instance == null) { 34 | synchronized (AddressBookStore.class) { 35 | if (instance == null) { 36 | instance = new AddressBookStore(databasePath); 37 | } 38 | } 39 | } 40 | return instance; 41 | } 42 | 43 | 44 | @Synchronized 45 | public void load() throws IOException { 46 | if (database.length() == 0) return; 47 | addressBook = objectMapper.readValue(database, AddressBook.class); 48 | } 49 | 50 | @Synchronized 51 | public void save() throws IOException { 52 | objectMapper.writeValue(database, addressBook); 53 | } 54 | 55 | @Synchronized 56 | public AddressBook getAddressBook() { 57 | return addressBook; 58 | } 59 | 60 | @Synchronized 61 | public Contact getContact(String name) { 62 | return addressBook.getContact(name); 63 | } 64 | 65 | @Synchronized 66 | public void addContact(Contact contact) { 67 | addressBook.addContact(contact); 68 | } 69 | 70 | @Synchronized 71 | public UpdateStatus update(String name, String phone) { 72 | return addressBook.update(name, phone); 73 | } 74 | 75 | @Synchronized 76 | public UpdateStatus remove(String name, String phone) { 77 | return addressBook.remove(name, phone); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/java/dev/potat/servlets/lab13/Contact.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab13; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | public class Contact { 12 | private String name; 13 | private List phones = new ArrayList<>(); 14 | 15 | public Contact(String name, String phone) { 16 | setName(name); 17 | addPhone(phone); 18 | } 19 | 20 | public void addPhone(String phone) { 21 | phones.add(phone); 22 | } 23 | 24 | public void removePhone(String phone) { 25 | phones.remove(phone); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/java/dev/potat/servlets/lab13/DeleteServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab13; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.annotation.WebServlet; 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import lombok.SneakyThrows; 9 | 10 | import java.io.IOException; 11 | 12 | @WebServlet(name = "DeleteContact", value = "/contacts/delete") 13 | public class DeleteServlet extends HttpServlet { 14 | private AddressBookStore store; 15 | 16 | @SneakyThrows 17 | public void init() { 18 | store = AddressBookStore.getInstance("db.json"); 19 | store.load(); 20 | } 21 | 22 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 23 | getServletContext().getRequestDispatcher("/form_delete.jsp").forward(request, response); 24 | } 25 | 26 | // Method to handle POST request from the form 27 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 28 | String name = request.getParameter("name"); 29 | String phone = request.getParameter("phone"); 30 | AddressBook.UpdateStatus result = store.remove(name, phone); 31 | 32 | String status, message; 33 | switch (result) { 34 | case PHONE_REMOVED: 35 | status = "Phone removed!"; 36 | message = "Phone was successfully removed"; 37 | break; 38 | case CONTACT_REMOVED: 39 | status = "Contact removed!"; 40 | message = "Contact was successfully removed"; 41 | break; 42 | case NOT_EXIST: 43 | status = "Contact does not exist"; 44 | message = "You have entered the wrong contact info"; 45 | break; 46 | default: 47 | status = "Something goes wrong"; 48 | message = "And I don't know what is going on"; 49 | } 50 | 51 | request.setAttribute("status", status); 52 | request.setAttribute("message", message); 53 | getServletContext().getRequestDispatcher("/info.jsp").forward(request, response); 54 | store.save(); 55 | } 56 | 57 | public void destroy() { 58 | } 59 | } -------------------------------------------------------------------------------- /servlets/lab13/src/main/java/dev/potat/servlets/lab13/UpdateServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab13; 2 | 3 | import dev.potat.servlets.lab13.AddressBook.UpdateStatus; 4 | import jakarta.servlet.ServletException; 5 | import jakarta.servlet.annotation.WebServlet; 6 | import jakarta.servlet.http.HttpServlet; 7 | import jakarta.servlet.http.HttpServletRequest; 8 | import jakarta.servlet.http.HttpServletResponse; 9 | import lombok.SneakyThrows; 10 | 11 | import java.io.IOException; 12 | 13 | @WebServlet(name = "UpdateAddressBook", value = "/contacts/update") 14 | public class UpdateServlet extends HttpServlet { 15 | private AddressBookStore store; 16 | 17 | @SneakyThrows 18 | public void init() { 19 | store = AddressBookStore.getInstance("db.json"); 20 | store.load(); 21 | } 22 | 23 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 24 | getServletContext().getRequestDispatcher("/form_update.jsp").forward(request, response); 25 | } 26 | 27 | // Method to handle POST request from the form 28 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 29 | String name = request.getParameter("name"); 30 | String phone = request.getParameter("phone"); 31 | UpdateStatus result = store.update(name, phone); 32 | 33 | String status, message; 34 | switch (result) { 35 | case CREATED: 36 | status = "Successfully created!"; 37 | message = "Contact was successfully created"; 38 | break; 39 | case UPDATED: 40 | status = "Added new phone!"; 41 | message = "Contact was successfully updated"; 42 | break; 43 | case DECLINED: 44 | status = "Contact was declined"; 45 | message = "Contact was declined for some reason"; 46 | break; 47 | default: 48 | status = "Something goes wrong"; 49 | message = "And I don't know what is going on"; 50 | } 51 | 52 | request.setAttribute("status", status); 53 | request.setAttribute("message", message); 54 | getServletContext().getRequestDispatcher("/info.jsp").forward(request, response); 55 | store.save(); 56 | } 57 | 58 | public void destroy() { 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/java/dev/potat/servlets/lab13/ViewServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab13; 2 | 3 | import java.io.*; 4 | 5 | import jakarta.servlet.ServletException; 6 | import jakarta.servlet.http.*; 7 | import jakarta.servlet.annotation.*; 8 | import lombok.SneakyThrows; 9 | 10 | @WebServlet(name = "ViewAddressBook", value = "/contacts") 11 | public class ViewServlet extends HttpServlet { 12 | private AddressBookStore store; 13 | 14 | @SneakyThrows 15 | public void init() { 16 | store = AddressBookStore.getInstance("db.json"); 17 | store.load(); 18 | } 19 | 20 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 21 | request.setAttribute("contacts", store.getAddressBook().getContacts()); 22 | getServletContext().getRequestDispatcher("/view.jsp").forward(request, response); 23 | } 24 | 25 | public void destroy() { 26 | } 27 | } -------------------------------------------------------------------------------- /servlets/lab13/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/webapp/form_delete.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 6 | Delete Contact 7 | 8 | 9 | 10 |
11 |

Remove Contact or Phone

12 | 13 |
14 |
15 |
16 | 17 | 20 |
21 | 22 |
23 | 24 | 26 |
27 | 28 | 32 | 33 | 37 |
38 |
39 | 40 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/webapp/form_update.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 6 | Update Contact 7 | 8 | 9 | 10 |
11 |

Add or Update Contact

12 | 13 |
14 |
15 |
16 | 17 | 20 |
21 | 22 |
23 | 24 | 27 |
28 | 29 | 33 | 34 | 38 |
39 |
40 | 41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | 3 | 4 | 5 | 6 | Address Book 7 | 8 | 9 | 10 |
11 |

12 | Hello World! 13 |

14 |

15 | This is just a homepage. Please go to the servlet 16 | 18 | Address Book Servlet 19 | 20 |

21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/webapp/info.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | 3 | 4 | 5 | 6 | ${status} 7 | 8 | 9 | 10 |
11 |

${status}

12 |

${message}

13 |

14 | 16 | Go to Address Book 17 | 18 | / 19 | 21 | Add or update contact 22 | 23 |

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /servlets/lab13/src/main/webapp/view.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 3 | 4 | 5 | 6 | 7 | 8 | Address Book 9 | 10 | 11 | 12 |
13 |

14 | Your Address Book 15 |

16 | 17 |
18 | 19 |
20 |

${contact.getName()}

21 |
    22 | 23 |
  • ${phone}
  • 24 |
    25 |
26 |
27 |
28 |
29 | 30 | 36 | 37 | 43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /servlets/lab15/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'war' 4 | id "io.freefair.lombok" version "8.4" 5 | } 6 | 7 | apply from: 'https://raw.github.com/gretty-gradle-plugin/gretty/master/pluginScripts/gretty.plugin' 8 | 9 | group 'dev.potat.servlets' 10 | version '1.0-SNAPSHOT' 11 | 12 | repositories { 13 | mavenCentral() 14 | } 15 | 16 | ext { 17 | junitVersion = '5.10.0' 18 | } 19 | 20 | sourceCompatibility = '11' 21 | targetCompatibility = '11' 22 | 23 | tasks.withType(JavaCompile) { 24 | options.encoding = 'UTF-8' 25 | } 26 | 27 | dependencies { 28 | compileOnly('jakarta.servlet:jakarta.servlet-api:5.0.0') 29 | implementation("com.fasterxml.jackson.core:jackson-databind:2.15.2") 30 | 31 | implementation("org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1") 32 | implementation("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0") 33 | implementation('com.aventrix.jnanoid:jnanoid:2.0.0') 34 | 35 | testImplementation('org.junit.jupiter:junit-jupiter:5.8.1') 36 | testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}") 37 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}") 38 | } 39 | 40 | test { 41 | useJUnitPlatform() 42 | } -------------------------------------------------------------------------------- /servlets/lab15/db.json: -------------------------------------------------------------------------------- 1 | { 2 | "ads": [ 3 | { 4 | "id": "iOI8LszGQcnzq0X-KgC4X", 5 | "title": "ПРОДАМ САМОЛЕТ", 6 | "image": "https://static.mk.ru/upload/entities/2023/05/28/09/articles/detailPicture/b0/96/27/a2/9fcfdc1e3989bf3d786febbd7d690909.jpg", 7 | "desc": "✈ во какой крутой, смотри! Захотелось?? не жди, покупай!!!", 8 | "user": "nastya", 9 | "date": "29 Nov 2023, 16:52", 10 | "score": 4, 11 | "votes": { 12 | "potat": "LIKE", 13 | "maksim": "LIKE", 14 | "user": "LIKE", 15 | "nastya": "LIKE" 16 | } 17 | }, 18 | { 19 | "id": "errxYQdXHh_iS91Rskeds", 20 | "title": "Показываю рыбов", 21 | "image": "https://pasteimg.com/images/2023/12/16/image78f8ce354aab3bbb.jpg", 22 | "desc": "Важно: Я НЕ ПРОДАЮ РЫБОВ, просто показываю! Не пишите в ЛС \"красивое\", я и сам знаю что оно красивое!!!", 23 | "user": "maksim", 24 | "date": "29 Nov 2023, 16:54", 25 | "score": 3, 26 | "votes": { 27 | "potat": "LIKE", 28 | "maksim": "LIKE", 29 | "nastya": "LIKE" 30 | } 31 | }, 32 | { 33 | "id": "xrg0UumcfIoCY66OBZSn7", 34 | "title": "Помогите достать самолет", 35 | "image": "https://www.obninsk.name/UserFiles/Image/202205/99665_7635951231424014467_gmb0hvg_1a02zstia82ibrupqeafzxy1sxgs58zgxbgnkncgjvckiltzbkm3iepk1zhunq_myjoacl8cni7kpvrf-0.jpg", 36 | "desc": "Я уже второй день не могу достать свой самолет. Мне ОЧЕНЬ грустно, я ищу людей кто готов мне помочь. \r\nВсе на альтруизме, без оплаты (ну реально, мне и так грустно, у меня самолет застрял)", 37 | "user": "nastya", 38 | "date": "29 Nov 2023, 17:21", 39 | "score": 2, 40 | "votes": { 41 | "potat": "LIKE", 42 | "maksim": "LIKE" 43 | } 44 | }, 45 | { 46 | "id": "DNiOQR2NohDk7qKqF4Wp_", 47 | "title": "Ищу сыр косичку!", 48 | "image": "https://gcdnb.pbrd.co/images/G3gKS8VzSR6A.webp?o=1", 49 | "desc": "Помогите найти сыр косичку пожалуйста((((( Я не могу найти её никак", 50 | "user": "maksim", 51 | "date": "29 Nov 2023, 17:17", 52 | "score": 2, 53 | "votes": { 54 | "maksim": "LIKE", 55 | "nastya": "LIKE" 56 | } 57 | }, 58 | { 59 | "id": "k6SKQvOqC9rLk9NaFIQqe", 60 | "title": "Продам диплом", 61 | "image": "https://opis-cdn.tinkoffjournal.ru/mercury/diploma-types-08.uwmals..jpg", 62 | "desc": "Продам за ненадобностью. БУ. Использовался как коврик для мыши, и иногда для того чтобы накрывать дошик", 63 | "user": "maksim", 64 | "date": "29 Nov 2023, 17:04", 65 | "score": 1, 66 | "votes": { 67 | "potat": "LIKE" 68 | } 69 | }, 70 | { 71 | "id": "XaOpenCYdhCxrfA5_MiEg", 72 | "title": "Футболка с ВАШИМ принтом!", 73 | "image": "https://storage.vsemayki.ru/images/0/2/2946/2946725/previews/people_4_manshortfull_front_white_500.jpg", 74 | "desc": "Самое лучшее качество, фирменные футболки, ПОКУПАЕМ ПОКУПАЕМ!!", 75 | "user": "user", 76 | "date": "29 Nov 2023, 16:58", 77 | "score": 0, 78 | "votes": {} 79 | }, 80 | { 81 | "id": "Pky_ZMoJlwEU5UkLOR6H9", 82 | "title": "Продам котят", 83 | "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQyB_wXoftQ5Pc-Ychz4Pl_fUUITFMi80XGTcvldPG0CgYCQZ0xm1N3i8kd9B6AhOwSCHI&usqp=CAU", 84 | "desc": "они такие дурачки, просто жесть", 85 | "user": "user", 86 | "date": "29 Nov 2023, 21:24", 87 | "score": 0, 88 | "votes": {} 89 | }, 90 | { 91 | "id": "YoI1EIarzFJo94JsUD-Ql", 92 | "title": "Горячие ЛАБЫ в 300м от тебя \uD83D\uDD25\uD83D\uDD25\uD83D\uDD25", 93 | "image": "https://dosrochnik.ru/img/laba-rabota.jpg", 94 | "desc": "Они очень ХОТЯТ чтобы ты их СДАЛ!!! Сдай их быстрее, Линский ОЧЕНЬ этого ждет!!! \uD83E\uDD75\uD83D\uDCA6\uD83D\uDCA6", 95 | "user": "potat", 96 | "date": "29 Nov 2023, 17:01", 97 | "score": -2, 98 | "votes": { 99 | "maksim": "DISLIKE", 100 | "nastya": "DISLIKE" 101 | } 102 | } 103 | ] 104 | } -------------------------------------------------------------------------------- /servlets/lab15/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potat-dev/JavaLabs/057fd364ee1d4a95e1530427c24afa630494f671/servlets/lab15/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /servlets/lab15/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /servlets/lab15/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /servlets/lab15/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "lab15" -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/AdBoard.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Comparator; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | public class AdBoard { 12 | private ArrayList ads = new ArrayList<>(); 13 | 14 | public void add(Advertisement ad) { 15 | ads.add(ad); 16 | } 17 | 18 | public Advertisement getById(String id) { 19 | for (Advertisement ad : ads) { 20 | if (ad.getId() != null && ad.getId().equals(id)) { 21 | return ad; 22 | } 23 | } 24 | return null; 25 | } 26 | 27 | public void sort() { 28 | ads.sort(Comparator.comparing(Advertisement::getScore).reversed()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/AdBoardStore.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import lombok.Synchronized; 5 | import lombok.ToString; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.util.ArrayList; 10 | 11 | @ToString 12 | public class AdBoardStore { 13 | private static volatile AdBoardStore instance; 14 | 15 | private AdBoard board = new AdBoard(); 16 | 17 | @ToString.Exclude 18 | private final ObjectMapper objectMapper = new ObjectMapper(); 19 | 20 | @ToString.Exclude 21 | private final File database; 22 | 23 | public AdBoardStore(String databasePath) { 24 | this.database = new File(databasePath); 25 | try { 26 | if (this.database.createNewFile()) { 27 | System.out.println("Database created"); 28 | } else { 29 | load(); 30 | System.out.println("Database loaded"); 31 | } 32 | } catch (IOException e) { 33 | throw new RuntimeException(e); 34 | } 35 | } 36 | 37 | public static AdBoardStore getInstance(String dbPath) { 38 | if (instance == null) { 39 | synchronized (AdBoard.class) { 40 | if (instance == null) { 41 | instance = new AdBoardStore(dbPath); 42 | } 43 | } 44 | } 45 | return instance; 46 | } 47 | 48 | @Synchronized 49 | public void load() throws IOException { 50 | if (database.length() == 0) return; 51 | board = objectMapper.readValue(database, AdBoard.class); 52 | } 53 | 54 | @Synchronized 55 | public void save() throws IOException { 56 | board.sort(); 57 | objectMapper.writeValue(database, board); 58 | } 59 | 60 | @Synchronized 61 | public ArrayList getAds() { 62 | return board.getAds(); 63 | } 64 | 65 | @Synchronized 66 | public void add(Advertisement ad) { 67 | board.add(ad); 68 | } 69 | 70 | @Synchronized 71 | public Advertisement getById(String id) { 72 | return board.getById(id); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/AddServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.annotation.WebServlet; 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import jakarta.servlet.http.HttpSession; 9 | import lombok.SneakyThrows; 10 | 11 | import java.io.IOException; 12 | 13 | @WebServlet(name = "AddServlet", value = "/add") 14 | public class AddServlet extends HttpServlet { 15 | private AdBoardStore store; 16 | 17 | @SneakyThrows 18 | public void init() { 19 | store = AdBoardStore.getInstance("db.json"); 20 | } 21 | 22 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 23 | HttpSession session = request.getSession(false); // false = do not create new session 24 | 25 | if (session != null && session.getAttribute("user") == null) { 26 | returnUnauthorized(request, response); 27 | } else { 28 | getServletContext().getRequestDispatcher("/add.jsp").forward(request, response); 29 | } 30 | } 31 | 32 | // Method to handle POST request from the form 33 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 34 | HttpSession session = request.getSession(false); 35 | 36 | if (session != null && session.getAttribute("user") == null) { 37 | returnUnauthorized(request, response); 38 | } else { 39 | String user = (String) session.getAttribute("user"); 40 | String title = request.getParameter("title"); 41 | String image = request.getParameter("image"); 42 | String desc = request.getParameter("desc"); 43 | 44 | store.add(new Advertisement(title, image, desc, user)); 45 | 46 | request.setAttribute("status", "Ad was added successfully!"); 47 | request.setAttribute("message", "Go to main page and check!"); 48 | getServletContext().getRequestDispatcher("/info.jsp").forward(request, response); 49 | store.save(); 50 | } 51 | } 52 | 53 | public void returnUnauthorized(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 54 | request.setAttribute("status", "Access denied!"); 55 | request.setAttribute("message", "Authorization is required to access this page!"); 56 | getServletContext().getRequestDispatcher("/info.jsp").forward(request, response); 57 | } 58 | 59 | public void destroy() { 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/Advertisement.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import com.aventrix.jnanoid.jnanoid.NanoIdUtils; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.ZoneId; 9 | import java.time.ZonedDateTime; 10 | import java.time.format.DateTimeFormatter; 11 | import java.util.HashMap; 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Advertisement { 17 | private String id; 18 | private String title; 19 | private String image; 20 | private String desc; 21 | private String user; 22 | private String date; 23 | 24 | private int score; 25 | private HashMap votes; 26 | 27 | 28 | public Advertisement(String title, String image, String desc, String user) { 29 | this(NanoIdUtils.randomNanoId(), title, image, desc, user, getNow(), 0, new HashMap<>()); 30 | } 31 | 32 | private static String getNow() { 33 | DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MMM yyyy, HH:mm"); 34 | ZonedDateTime now = ZonedDateTime.now(); 35 | ZonedDateTime japanDateTime = now.withZoneSameInstant(ZoneId.of("Europe/Moscow")); 36 | return dtf.format(japanDateTime); 37 | } 38 | 39 | public void vote(String userId, String action) { 40 | switch (action) { 41 | case "like": 42 | votes.put(userId, Vote.LIKE); 43 | break; 44 | case "dislike": 45 | votes.put(userId, Vote.DISLIKE); 46 | break; 47 | case "remove": 48 | votes.remove(userId); 49 | break; 50 | } 51 | score = calcScore(); 52 | } 53 | 54 | public Vote getVoteBy(String user) { 55 | return votes.getOrDefault(user, Vote.NONE); 56 | } 57 | 58 | public boolean likedBy(String user) { 59 | return getVoteBy(user) == Vote.LIKE; 60 | } 61 | 62 | public boolean dislikedBy(String user) { 63 | return getVoteBy(user) == Vote.DISLIKE; 64 | } 65 | 66 | private int calcScore() { 67 | int score = 0; 68 | for (Vote vote : votes.values()) { 69 | score += (vote == Vote.LIKE ? 1 : -1); 70 | } 71 | return score; 72 | } 73 | 74 | public enum Vote { 75 | NONE, LIKE, DISLIKE 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/LoginServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.annotation.WebServlet; 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import jakarta.servlet.http.HttpSession; 9 | 10 | import java.io.IOException; 11 | 12 | @WebServlet(name = "LoginServlet", value = "/login") 13 | public class LoginServlet extends HttpServlet { 14 | private UserStore userStore; 15 | 16 | public void init() { 17 | userStore = UserStore.getInstance("users.json"); 18 | } 19 | 20 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 21 | getServletContext().getRequestDispatcher("/login.jsp").forward(request, response); 22 | } 23 | 24 | // Method to handle POST request from the form 25 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 26 | String username = request.getParameter("username"); 27 | String password = request.getParameter("password"); 28 | 29 | String status, message; 30 | 31 | if (userStore.login(username, password)) { 32 | HttpSession session = request.getSession(); 33 | session.setAttribute("user", username); 34 | // hehe 35 | status = "Login success!"; 36 | message = "Now you can post your ads :)"; 37 | } else { 38 | // not hehe 39 | status = "Login failed!"; 40 | message = "Incorrect username or password :("; 41 | } 42 | 43 | request.setAttribute("status", status); 44 | request.setAttribute("message", message); 45 | getServletContext().getRequestDispatcher("/info.jsp").forward(request, response); 46 | } 47 | 48 | public void destroy() { 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/LogoutServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.annotation.WebServlet; 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import jakarta.servlet.http.HttpSession; 9 | 10 | import java.io.IOException; 11 | 12 | @WebServlet(name = "LogoutServlet", value = "/logout") 13 | public class LogoutServlet extends HttpServlet { 14 | public void init() { 15 | } 16 | 17 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 18 | HttpSession session = request.getSession(false); 19 | if (session != null) { 20 | session.removeAttribute("user"); 21 | session.invalidate(); 22 | } 23 | 24 | request.setAttribute("status", "Logout success!"); 25 | request.setAttribute("message", "You are successfully logged out!"); 26 | getServletContext().getRequestDispatcher("/info.jsp").forward(request, response); 27 | } 28 | 29 | public void destroy() { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/User.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class User { 11 | private String username; 12 | private String password; // хранить пароли в plaintext это круто! 13 | 14 | public User(String name) { 15 | this(name, name); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/UserStore.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.databind.type.CollectionType; 5 | import lombok.Synchronized; 6 | import lombok.ToString; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.util.ArrayList; 11 | 12 | public class UserStore { 13 | private static volatile UserStore instance; 14 | 15 | private ArrayList users = new ArrayList<>(); 16 | 17 | @ToString.Exclude 18 | private final ObjectMapper objectMapper = new ObjectMapper(); 19 | 20 | @ToString.Exclude 21 | private final File database; 22 | 23 | public UserStore(String databasePath) { 24 | this.database = new File(databasePath); 25 | try { 26 | if (this.database.createNewFile()) { 27 | addDummyUsers(); 28 | save(); 29 | System.out.println("Database created"); 30 | } else { 31 | load(); 32 | System.out.println("Database loaded"); 33 | } 34 | } catch (IOException e) { 35 | throw new RuntimeException(e); 36 | } 37 | } 38 | 39 | public static UserStore getInstance(String dbPath) { 40 | if (instance == null) { 41 | synchronized (UserStore.class) { 42 | if (instance == null) { 43 | instance = new UserStore(dbPath); 44 | } 45 | } 46 | } 47 | return instance; 48 | } 49 | 50 | @Synchronized 51 | public void load() throws IOException { 52 | if (database.length() == 0) return; 53 | CollectionType usersType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, User.class); 54 | users = objectMapper.readValue(database, usersType); 55 | } 56 | 57 | @Synchronized 58 | public void save() throws IOException { 59 | objectMapper.writeValue(database, users); 60 | } 61 | 62 | @Synchronized 63 | public boolean login(String user, String pass) { 64 | User u = getByName(user); 65 | if (u == null) return false; 66 | return u.getPassword().equals(pass); 67 | } 68 | 69 | public User getByName(String name) { 70 | for (User user : users) { 71 | if (user.getUsername().equals(name)) return user; 72 | } 73 | return null; 74 | } 75 | 76 | private void addDummyUsers() { 77 | users.add(new User("root")); 78 | users.add(new User("demo")); 79 | users.add(new User("maksim")); 80 | users.add(new User("nastya")); 81 | users.add(new User("user", "abcd")); 82 | users.add(new User("potat", "1234")); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/ViewServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.annotation.WebServlet; 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import jakarta.servlet.http.HttpSession; 9 | import lombok.SneakyThrows; 10 | 11 | import java.io.IOException; 12 | 13 | @WebServlet(name = "ViewServlet", value = "/") 14 | public class ViewServlet extends HttpServlet { 15 | private AdBoardStore store; 16 | 17 | @SneakyThrows 18 | public void init() { 19 | store = AdBoardStore.getInstance("db.json"); 20 | store.load(); 21 | } 22 | 23 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 24 | request.setAttribute("ads", store.getAds()); 25 | HttpSession session = request.getSession(false); // false = do not create new session 26 | boolean loggedIn = session != null && session.getAttribute("user") != null; 27 | request.setAttribute("login", loggedIn); 28 | if (loggedIn) { 29 | String username = (String) session.getAttribute("user"); 30 | request.setAttribute("user", username); 31 | } 32 | getServletContext().getRequestDispatcher("/view.jsp").forward(request, response); 33 | } 34 | 35 | public void destroy() { 36 | } 37 | } -------------------------------------------------------------------------------- /servlets/lab15/src/main/java/dev/potat/servlets/lab15/VoteServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab15; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.annotation.WebServlet; 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | import jakarta.servlet.http.HttpSession; 9 | import lombok.SneakyThrows; 10 | 11 | import java.io.IOException; 12 | 13 | @WebServlet(name = "VoteServlet", value = "/vote") 14 | public class VoteServlet extends HttpServlet { 15 | private AdBoardStore store; 16 | 17 | @SneakyThrows 18 | public void init() { 19 | store = AdBoardStore.getInstance("db.json"); 20 | } 21 | 22 | // Method to handle POST request from the form 23 | public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 24 | HttpSession session = request.getSession(false); 25 | boolean loggedIn = session != null && session.getAttribute("user") != null; 26 | 27 | if (!loggedIn) { 28 | returnUnauthorized(request, response); 29 | } else { 30 | String id = request.getParameter("id"); 31 | String action = request.getParameter("action"); 32 | String userId = (String) session.getAttribute("user"); 33 | 34 | Advertisement ad = store.getById(id); 35 | ad.vote(userId, action); 36 | 37 | response.setContentType("text/plain"); 38 | response.setCharacterEncoding("UTF-8"); 39 | response.getWriter().write(action + ' ' + ad.getScore()); 40 | store.save(); 41 | } 42 | } 43 | 44 | public void returnUnauthorized(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 45 | request.setAttribute("status", "Access denied!"); 46 | request.setAttribute("message", "Authorization is required to access this page!"); 47 | getServletContext().getRequestDispatcher("/info.jsp").forward(request, response); 48 | } 49 | 50 | public void destroy() { 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/webapp/add.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 6 | New advertisement 7 | 8 | 9 | 10 |
11 |

New advertisement

12 | 13 |
14 |
15 |
16 |
17 | 20 | 23 |
24 |
25 | 28 | 31 |
32 |
33 |
34 | 37 | 40 |
41 | 45 |
46 |
47 | 48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/webapp/info.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | 3 | 4 | 5 | 6 | ${status} 7 | 8 | 9 | 10 |
11 |

${status}

12 |

${message}

13 |

14 | Homepage 16 | ${" • "} 17 | New advertisement 19 |

20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/webapp/login.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 6 | Login 7 | 8 | 9 | 10 |
11 |

Login to this awesome site!

12 | 13 |
14 |
15 |
16 |
17 | 20 | 23 |
24 |
25 | 28 | 31 |
32 |
33 | 37 |
38 |
39 | 40 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /servlets/lab15/src/main/webapp/view.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 3 | 4 | 5 | 6 | 7 | 8 | Public Ad Board 9 | 10 | 11 | 12 | 13 |
14 |

15 | Public Ad Board 16 |

17 | 18 |
19 | 20 |
21 | 22 | 23 | image 24 | 25 | 26 |
27 |
${ad.getTitle()}
28 |

${ad.getDesc()}

29 | 30 |
31 |

32 | Posted by ${ad.getUser()} • ${ad.getDate()} 33 |

34 | 35 |
36 | 40 | 44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 52 | 70 |
71 | 72 | 73 | 74 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /servlets/lab15/users.json: -------------------------------------------------------------------------------- 1 | [{"username":"root","password":"root"},{"username":"demo","password":"demo"},{"username":"maksim","password":"maksim"},{"username":"nastya","password":"nastya"},{"username":"user","password":"abcd"},{"username":"potat","password":"1234"}] -------------------------------------------------------------------------------- /servlets/lab16/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'war' 4 | id "io.freefair.lombok" version "8.4" 5 | } 6 | 7 | apply from: 'https://raw.github.com/gretty-gradle-plugin/gretty/master/pluginScripts/gretty.plugin' 8 | 9 | group 'dev.potat.servlets' 10 | version '1.0-SNAPSHOT' 11 | 12 | repositories { 13 | mavenCentral() 14 | } 15 | 16 | ext { 17 | junitVersion = '5.10.0' 18 | } 19 | 20 | sourceCompatibility = '11' 21 | targetCompatibility = '11' 22 | 23 | tasks.withType(JavaCompile) { 24 | options.encoding = 'UTF-8' 25 | } 26 | 27 | dependencies { 28 | compileOnly('jakarta.servlet:jakarta.servlet-api:6.0.0') 29 | 30 | implementation("org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1") 31 | implementation("jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0") 32 | implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.16.0' 33 | 34 | testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}") 35 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}") 36 | } 37 | 38 | test { 39 | useJUnitPlatform()} -------------------------------------------------------------------------------- /servlets/lab16/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potat-dev/JavaLabs/057fd364ee1d4a95e1530427c24afa630494f671/servlets/lab16/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /servlets/lab16/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /servlets/lab16/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /servlets/lab16/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "lab16" -------------------------------------------------------------------------------- /servlets/lab16/src/main/java/dev/potat/servlets/lab16/ListItem.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab16; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class ListItem { 14 | private String name; 15 | private List items = new ArrayList<>(); 16 | } 17 | -------------------------------------------------------------------------------- /servlets/lab16/src/main/java/dev/potat/servlets/lab16/ListServlet.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab16; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.annotation.WebServlet; 5 | import jakarta.servlet.http.HttpServlet; 6 | import jakarta.servlet.http.HttpServletRequest; 7 | import jakarta.servlet.http.HttpServletResponse; 8 | 9 | import java.io.IOException; 10 | 11 | @WebServlet(name = "ListServlet", value = "/") 12 | public class ListServlet extends HttpServlet { 13 | private ListStore store; 14 | 15 | public void init() { 16 | store = ListStore.getInstance("db.yaml"); 17 | } 18 | 19 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 20 | request.setAttribute("list", store.getItems()); 21 | getServletContext().getRequestDispatcher("/view.jsp").forward(request, response); 22 | } 23 | 24 | public void destroy() { 25 | } 26 | } -------------------------------------------------------------------------------- /servlets/lab16/src/main/java/dev/potat/servlets/lab16/ListStore.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab16; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.databind.type.CollectionType; 5 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; 6 | import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; 7 | import lombok.Data; 8 | import lombok.Synchronized; 9 | import lombok.ToString; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | @Data 17 | public class ListStore { 18 | private static volatile ListStore instance; 19 | 20 | private List items = new ArrayList<>(); 21 | 22 | @ToString.Exclude 23 | private final ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)); 24 | 25 | @ToString.Exclude 26 | private final File database; 27 | 28 | public ListStore(String databasePath) { 29 | this.database = new File(databasePath); 30 | try { 31 | if (this.database.createNewFile()) { 32 | addDummyData(); 33 | save(); 34 | System.out.println("Database created"); 35 | } else { 36 | load(); 37 | System.out.println("Database loaded"); 38 | } 39 | } catch (IOException e) { 40 | throw new RuntimeException(e); 41 | } 42 | } 43 | 44 | public static ListStore getInstance(String dbPath) { 45 | if (instance == null) { 46 | synchronized (ListStore.class) { 47 | if (instance == null) { 48 | instance = new ListStore(dbPath); 49 | } 50 | } 51 | } 52 | return instance; 53 | } 54 | 55 | @Synchronized 56 | public void load() throws IOException { 57 | if (database.length() == 0) return; 58 | CollectionType itemsType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, ListItem.class); 59 | items = objectMapper.readValue(database, itemsType); 60 | } 61 | 62 | @Synchronized 63 | public void save() throws IOException { 64 | objectMapper.writeValue(database, items); 65 | } 66 | 67 | private void addDummyData() { 68 | items.add(new ListItem("Animals", List.of("Wolf", "Cow"))); 69 | items.add(new ListItem("Birds", List.of("Chicken", "Eagle", "Parrot"))); 70 | items.add(new ListItem("Fish", List.of("Salmon", "Tuna"))); 71 | items.add(new ListItem("Insects", List.of("Ant", "Butterfly", "Spider"))); 72 | items.add(new ListItem("Getz Family", List.of("Nastya", "Maksim", "Denis"))); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /servlets/lab16/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /servlets/lab16/src/main/webapp/view.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 3 | 4 | 5 | 6 | 7 | 8 | List 9 | 10 | 11 | 12 |
13 |

14 | List of some things 15 |

16 |
17 | 18 | 22 | 23 | 27 | 28 |
    29 | 30 |
  1. ${item.getName()} 31 | 33 | ${"▶"} 34 | 35 | 40 |
  2. 41 |
    42 |
43 | 44 |
45 | 46 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /servlets/lab16/src/test/java/dev/potat/servlets/lab16/TestSaveAndLoad.java: -------------------------------------------------------------------------------- 1 | package dev.potat.servlets.lab16; 2 | 3 | import lombok.SneakyThrows; 4 | 5 | public class TestSaveAndLoad { 6 | @SneakyThrows 7 | public static void main(String[] args) { 8 | ListStore store = ListStore.getInstance("test.yml"); 9 | store.load(); 10 | System.out.println(store); 11 | store.save(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'JavaLabs' 2 | 3 | include 'servlets:lab13' 4 | include 'servlets:lab15' 5 | include 'servlets:lab16' 6 | --------------------------------------------------------------------------------