<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Dinis Khakimov</title><generator>teletype.in</generator><description><![CDATA[Dinis Khakimov]]></description><image><url>https://img3.teletype.in/files/6c/b9/6cb9072f-bc7e-42e3-a100-631096db385e.png</url><title>Dinis Khakimov</title><link>https://teletype.in/@khakimovdinis</link></image><link>https://teletype.in/@khakimovdinis?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/khakimovdinis?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/khakimovdinis?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sun, 31 May 2026 12:10:46 GMT</pubDate><lastBuildDate>Sun, 31 May 2026 12:10:46 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@khakimovdinis/JavaWhiteRabbit0004</guid><link>https://teletype.in/@khakimovdinis/JavaWhiteRabbit0004?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis</link><comments>https://teletype.in/@khakimovdinis/JavaWhiteRabbit0004?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis#comments</comments><dc:creator>khakimovdinis</dc:creator><title>SAX and DOM parsing in Java</title><pubDate>Mon, 18 Sep 2023 14:58:11 GMT</pubDate><category>Java | InputOutputOperations</category><description><![CDATA[Для начала разберемся, что такое XML файл и для чего он нужен. 

Для Java-приложений XML-файлы могут также служить в качестве конфигурационных файлов (например, для сохранения параметров приложения, конфигурации сервисов и других настроек).

Также, XML файл достаточно удобен для передачи какой либо информации между разными системами (например между сервером и телефоном). Представляет собой текстовый файл, содержащий информацию в структурированном виде, который понятен для большинства языков программирования, и как раз в этом и есть основное назначение XML файла.]]></description><content:encoded><![CDATA[
  <p id="pojI">Для начала разберемся, что такое XML файл и для чего он нужен. <br /><br />Для Java-приложений XML-файлы могут также служить в качестве конфигурационных файлов (например, для сохранения параметров приложения, конфигурации сервисов и других настроек).<br /><br />Также, XML файл достаточно удобен для передачи какой либо информации между разными системами (например между сервером и телефоном). Представляет собой текстовый файл, содержащий информацию в структурированном виде, который понятен для большинства языков программирования, и как раз в этом и есть основное назначение XML файла.  </p>
  <p id="E9ar">XML(eXtensible Markup Language) - расширяемый язык разметки документов. В отличие от HTML, который направлен на визуальное представление документа в браузере, XML используется для обмена данными между компьютером и приложением. <br /><br />Внутри, файл выглядит, как набор тегов с информацией(открывающие и закрывающие) в виде древовидной структуры. <br />Рассмотрим пример ниже. В каждом файле существует корневой тег - в нашем случае &lt;voters&gt; (он может иметь любое имя, в зависимости от выполняемой задачи). Далее, идут ветви, их может быть несколько, в нашем случае они одного типа с тегом voter и visit. И внутри мы имеем атрибуты {name, birthDay, station, time} с их значениями.</p>
  <pre id="iLZm" data-lang="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;voters&gt;
&lt;voter name=&quot;Тиронов Мартьян&quot; birthDay=&quot;1932.11.08&quot;&gt;   
&lt;visit station=&quot;120&quot; time=&quot;2015.09.17 15:51:40&quot; /&gt;
&lt;/voter&gt;
&lt;voter name=&quot;Варик Макар&quot; birthDay=&quot;1924.12.31&quot;&gt;   
&lt;visit station=&quot;48&quot; time=&quot;2015.09.21 22:24:28&quot; /&gt;
&lt;/voter&gt;
&lt;voter name=&quot;Погребной Миронег&quot; birthDay=&quot;1948.05.23&quot;&gt;   
&lt;visit station=&quot;170&quot; time=&quot;2015.09.19 14:59:01&quot; /&gt;
&lt;/voter&gt;
...
...
&lt;/voters&gt;</pre>
  <p id="9KPr"><br />Далее, на основе XML нам нужно создать объектную модель. Для этого создается пакет model и в нем создается класс, с таким именем, как и в XML файле. <br />Класс создается для добавления и дальнейшей работы с элементами, которые находятся в XML файле. </p>
  <p id="OCmb"></p>
  <p id="MVAO">Существуют несколько стратегий обработки XML документов. Мы <br />рассмотрим -  DOM (Document Object Model) и SAX (Simple API for XML). Основное их отличие связано с тем, что использование DOM позволяет читать и вносить изменения в существующий XML-документ, а также создавать новый. Стратегия использования SAX основывается на том, что содержимое XML-документа только анализируется. XML-текст может быть больших размеров: DOM должен весь документ «заглотить» и проанализировать, а SAX-парсер обрабатывает XML-документ последовательно и не требует дополнительной памяти.</p>
  <p id="ojyU"><strong><u>DOM API</u></strong><br />DOM (Document Object Model) - это стандартный способ представления и взаимодействия с содержимым XML-документов в программах на Java. Предоставляет процесс обработки по факту, загружая файл полностью в память.  Хорошо работает с небольшими файлами. </p>
  <p id="iS2M">Для парсинга, нам следует открыть файл, используя объекты типа - File, DocumentBuilderFactory, DocumentBuilder, Document.<br />В DOM есть три важных объекта - Node(каждый элемент(отступы, строки и тд) в XML), NodeList(получаем лист наших Node), Element(конкретный объект, заключаемый в тег).</p>
  <p id="CHqv"><u><strong>SAX API</strong></u><br />SAX(Simple API for XML) - это API, который используется для чтения и обработки XML-документов в Java. Он очень быстр и мало зависит от объема данных, за счет этого имеет большую популярность. <br />Чтение XML документа с помощью SAX является событийном процессом, то есть SAX предоставляет набор обработчиков событий, которые вызываются автоматически при обработке каждого элемента документа. Файл в память подгружается частями. <br /><br />Для парсинга мы используем объекты типа - SAXParserFactory(<em>Определяет API фабрики, который позволяет приложениям сконфигурировать и получить SAX базируемый синтаксический анализатор, чтобы проанализировать XML-документы</em>), SAXParser. И для успешной работы парсера нам необходимо переопределить нужные нам методы класса DefaultHandler.<br /></p>
  <p id="e1Zh"></p>
  <hr />
  <p id="29Rr">Полезные ссылки:<br /><a href="https://www.youtube.com/watch?v=wXupOedG6vU" target="_blank">https://www.youtube.com/watch?v=wXupOedG6vU<br /></a><a href="https://www.youtube.com/watch?v=T0nRDi0k4fU" target="_blank">https://www.youtube.com/watch?v=T0nRDi0k4fU</a><br /><a href="https://java-online.ru/java-xml.xhtml" target="_blank">https://java-online.ru/java-xml.xhtml</a><br /><a href="https://habr.com/ru/articles/62757/" target="_blank">https://habr.com/ru/articles/62757/</a><br /><a href="https://mou43-samara.ru/education/kak-prochitat-xml-fajl-v-java-prostye-shagi-i#:~:text=i%20%3C%20attributes.getLength-,%D0%A7%D1%82%D0%BE%20%D1%82%D0%B0%D0%BA%D0%BE%D0%B5%20xml%20%D1%84%D0%B0%D0%B9%D0%BB%20%D0%B8%20%D0%B7%D0%B0%D1%87%D0%B5%D0%BC%20%D0%BE%D0%BD%20%D0%BD%D1%83%D0%B6%D0%B5%D0%BD%20%D0%B2%20Java,%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%BC%D0%B8%20%D0%BC%D0%B5%D0%B6%D0%B4%D1%83%20%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0%D0%BC%D0%B8%20%D0%B8%20%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8" target="_blank">https://mou43-samara.ru/education/kak-prochitat-xml-fajl-v-java-prostye-shagi-i#:~:text=i%20%3C%20attributes.getLength-,%D0%A7%D1%82%D0%BE%20%D1%82%D0%B0%D0%BA%D0%BE%D0%B5%20xml%20%D1%84%D0%B0%D0%B9%D0%BB%20%D0%B8%20%D0%B7%D0%B0%D1%87%D0%B5%D0%BC%20%D0%BE%D0%BD%20%D0%BD%D1%83%D0%B6%D0%B5%D0%BD%20%D0%B2%20Java,%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%BC%D0%B8%20%D0%BC%D0%B5%D0%B6%D0%B4%D1%83%20%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0%D0%BC%D0%B8%20%D0%B8%20%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@khakimovdinis/JavaWhiteRabbit0003</guid><link>https://teletype.in/@khakimovdinis/JavaWhiteRabbit0003?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis</link><comments>https://teletype.in/@khakimovdinis/JavaWhiteRabbit0003?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis#comments</comments><dc:creator>khakimovdinis</dc:creator><title>Serialization and deserialization</title><pubDate>Sun, 17 Sep 2023 17:44:44 GMT</pubDate><category>Java | InputOutputOperations</category><description><![CDATA[Используя сериализацию объектов, мы сможем разложить свои объекты на последовательность байтов и затем использовать их наиболее эффективным образом (обычно используется в Hibernate, JMS, JPA и EJB). Для чего? Чтобы создаваемые нами объекты могли существовать за пределами жизненного цикла виртуальной машины.]]></description><content:encoded><![CDATA[
  <p id="b1CK">Используя <u>сериализацию </u>объектов, мы сможем разложить свои объекты на последовательность байтов и затем использовать их наиболее эффективным образом (обычно используется в Hibernate, JMS, JPA и EJB). Для чего? Чтобы создаваемые нами объекты могли существовать за пределами жизненного цикла виртуальной машины. </p>
  <p id="MxS0"><u>Десериализация</u> - это процесс обратного преобразования потока данных байтового типа в объект в памяти. <br /><br />Существует три способа выполнения сериализации {Используя протокол по умолчанию, Изменяя протокол по умолчанию, Создавая собственный протокол}.<br />В данной статье рассмотрим первый способ.</p>
  <p id="F8qf">Для того, чтобы отметить наш объект, как сериализумый, мы должны реализовать  интерфейс java.io.Serializable, что и будет являться для API знаком того, что объект может быть разложен на байты и затем вновь восстановлен. <br />Интерфейс Serializable является лишь маркерным интерфейсом и позволяет механизму сериализации определить возможность сохранения данного класса.<br /><br />Класс, на котором будем демонстрировать примеры, выглядит следующим образом:</p>
  <pre id="CeJB" data-lang="java">

import lombok.Getter;
import java.util.Calendar;
import java.util.Date;
import java.io.Serializable;
@Getter
public class PersistentTime implements Serializable {    
private Date time;    
public PersistentTime() {        
     time = Calendar.getInstance().getTime();    }}</pre>
  <p id="K44Y"><br /><u>Механизм используемый по умолчанию:</u><br /><br />Далее, что нужно для сохранения объекта? Сохранения выполняется при помощи класса java.io.ObjectOutputStream. Этот класс является фильтрующим потоком, он окружает низкоуровневый поток байтов(называемый узловым потоком(node stream))(?) и предоставляет нам поток сериализации. Узловые потоки могут быть использованы для записи в файловую систему или в сокеты. Это позволяет нам передавать разложенные на байты объекты по сети и затем восстанавливать их на других устройствах. <br /><br />Посмотрим код, который демонстрирует процесс сериализации:</p>
  <pre id="YWY3" data-lang="java">
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializationProcess {    
public static void main(String[] args) {        
String fileName = &quot;time.ser&quot;;        

if(args.length &gt; 0){            
fileName = args[0];        }       

PersistentTime time = new PersistentTime();        
FileOutputStream fileOutputStream = null;        
ObjectOutputStream objectOutputStream = null;        

try {            
fileOutputStream = new FileOutputStream(fileName);            
objectOutputStream = new ObjectOutputStream(fileOutputStream);            
objectOutputStream.writeObject(time);            
objectOutputStream.close();        
} catch (IOException e) {            
e.printStackTrace();        }    }}

</pre>
  <p id="diC3">Метод <strong>writeObject()</strong> -  запускает механизм сериализации и объект разлагается на байты (в данном случай файл).<br /><br />Теперь стоит посмотреть, на код, выполняющий процесс десириализации:</p>
  <pre id="V34i" data-lang="java">public class DeserializationProcess {    
public static void main(String[] args) {        
String fileName = &quot;time.ser&quot;;        
if(args.length &gt; 0){            
      fileName = args[0];        
}        

PersistentTime time = null;        
FileInputStream fileInputStream = null;        
ObjectInputStream objectInputStream = null;        
try {            
fileInputStream = new FileInputStream(fileName);            
objectInputStream = new ObjectInputStream(fileInputStream);            
time = (PersistentTime) objectInputStream.readObject();            
objectInputStream.close();        
} catch (IOException | ClassNotFoundException e) {            
       e.printStackTrace();        
}        

System.out.println(&quot;Время разложения: &quot; + time.getTime());        
System.out.println(&quot;Текущее время: &quot; + Calendar.getInstance().getTime()); 
  }}

Консоль:
Время разложения: Sun Sep 17 21:27:42 YEKT 2023
Текущее время: Sun Sep 17 21:39:53 YEKT 2023
</pre>
  <p id="k59U">Метод<strong> readObject()</strong> - восстанавливает объект. Метод считывает последовательность байтов, которую мы перед этим сохранили в файле и создает объект, полностью повторяющий оригинал. Поскольку метод считывает любой сериализуемый объект, необходимо его присвоить соответствующему типу. Из системы, в которой происходит десериализация, должен быть доступен файл класса (при сериализации не сохраняется ни файл класса, ни его методы, сохраняется лишь состояние! объекта).</p>
  <p id="sPtN"><br /><strong><u>Основные правила:</u></strong><br />1. Сохраняемый объект должен реализовать интерфейс Serializable или унаследовать эту реализацию от вышестоящего по иерархии объекта. <br />2. Вы должны помечать как <em>transient</em> все поля, которые либо не могут быть сериализованы, либо те, которые вы не хотите сериализовать. Сериализация не заботится о модификаторах доступа, таких как <em>private</em>. Все резидентные поля рассматриваются как части состояния сохраняемого объекта, предназначенные для сохранения.<br /></p>
  <hr />
  <p id="WvGq"><strong>Что такое Hibernate, JMS, JPA и EJB?</strong> <em>Hibernate</em> — это популярный framework, цель которого связать ООП и реляционную базу данных.<br /><em>JMS</em> (Java Message Service) является стандартом обмена сообщениями между приложениями.<br /><em>Java Persistence API</em> (<em>JPA</em>) — спецификация API Java EE, предоставляет возможность сохранять в удобном виде Java-объекты в базе данных.<br /><em>Enterprise JavaBeans</em> (также часто употребляется в виде аббревиатуры EJB) — спецификация технологии написания и поддержки серверных компонентов, содержащих бизнес-логику. Является частью Java EE.<br /><br /><strong>Что такое маркерный интерфейс?</strong> Маркерный интерфейс — это интерфейс , внутри которого нет методов или констант . Он предоставляет информацию о типах объектов во время выполнения, поэтому компилятор и JVM имеют дополнительную информацию об объекте.<br /><br /><strong>Что такое сокеты? </strong><a href="https://thecode.media/socket/" target="_blank">Сокет — это виртуальная конструкция</a> из IP-адреса и номера порта. Её придумали для того, чтобы разработчикам было проще писать код, а программы могли передавать данные друг другу даже в пределах одного компьютера. <u>Сокеты используют для двух вещей:</u> для передачи данных по сети и для связи между приложениями.</p>
  <p id="XhIV"><strong>Что такое файловая система? </strong><a href="https://gb.ru/blog/fajlovaya-sistema-kompjutera/" target="_blank">Благодаря файловой системе</a> мы сохраняем всю необходимую нам информацию на своих устройствах. Есть различные типы подобных накопителей. От особенностей того или иного вида зависят способ шифрования данных, объем их сжатия, а также качество самого хранения. Наиболее распространенные файловые системы – это FAT32 и NTFS.</p>
  <p id="bh9S"><br /></p>
  <p id="T84Q"></p>
  <p id="30Pc">Полезные ссылки:<br /><a href="http://www.ccfit.nsu.ru/~deviv/courses/oop/java_ser_rus.html" target="_blank">http://www.ccfit.nsu.ru/~deviv/courses/oop/java_ser_rus.html<br />https://www.simplilearn.com/tutorials/java-tutorial/serialization-in-java<br />https://metanit.com/java/tutorial/6.10.php</a><br /></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@khakimovdinis/JavaWhiteRabbit0002</guid><link>https://teletype.in/@khakimovdinis/JavaWhiteRabbit0002?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis</link><comments>https://teletype.in/@khakimovdinis/JavaWhiteRabbit0002?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis#comments</comments><dc:creator>khakimovdinis</dc:creator><title>Inversion of Control(Ioc), Dependecy Injection(DI), Spring Container.</title><pubDate>Sun, 17 Sep 2023 15:27:18 GMT</pubDate><category>Java | SpringFramework</category><description><![CDATA[Перед определением IoC и DI, стоит кратко рассмотреть, что такое Spring Container. Данный контейнер является ответственным за создание и управление объектов (это контейнер, в котором будут находиться созданные объекты(бины), откуда мы их сможем извлекать, запустив приложение). Контейнер будет читать наш configuration file и внутри контейнера будет создаваться бин, который мы опишем в конфигурационном файле.]]></description><content:encoded><![CDATA[
  <p id="PgjY">Перед определением IoC и DI, стоит кратко рассмотреть, что такое <strong>Spring Container</strong>. Данный контейнер является ответственным за создание и управление объектов (это контейнер, в котором будут находиться созданные объекты(бины), откуда мы их сможем извлекать, запустив приложение). Контейнер будет читать наш <strong>configuration file</strong> и внутри контейнера будет создаваться бин, который мы опишем в конфигурационном файле. </p>
  <p id="z2pj"><strong><u>Основные ф-ии, которые выполняет Spring Container:</u></strong><br />-<strong>IoC</strong> - инверсия управления. Создание и управление объектами (аутсорсинг создания и управления объектами. Т.е. передача программистом прав на создание и управление объектами Spring-y.).<br />-<strong>DI (Dependency Injection)</strong> - внедрение зависимостей (стоит вспомнить, что в сложной программе, множество объектов зависят друг от друга). (Аутсорсинг добавления/внедрения зависимостей. DI делает объекты нашего приложения слабо зависимым друг от друга).</p>
  <p id="bcm6"><strong><u>Способы конфигурации Spring Container</u></strong> (способ дать понимание того, какие объекты нужно создавать, с помощью IoC):</p>
  <p id="Cb6x">-<strong>XML file(устаревший способ)</strong>;<br />При создании файла, по стандарту, он имеет название applicationContext.xml. Внутри файла, помимо стандартной настройки, мы создаем необходимый для нас объект(бин):<br /><strong>&lt;bean id = &quot;myPet&quot; </strong> //идентификатор бина<br /><strong>class = &quot;spring_introduction.Dog&quot;&gt;</strong> //полное имя класса<br /><strong>&lt;\bean&gt;</strong></p>
  <p id="658T">Таким образом, при запуске нашего приложения, будет создаваться объект Dog и помещаться в Spring Container. Далее, с помощью id мы сможем получить объект из контейнера. <br />Для получения бина из SpringContainer нам нужно создать Application Context, в аргумент мы можем передать несколько файлов xml, если это необходимо (context всегда нужно закрывать!).<br /><strong>ClassPathXmlApplicationContext context = newClassPathXmlApplicationContext(&quot;applicationContext.xml&quot;)</strong>;</p>
  <p id="XmX1"><strong>Pet pet = context.getBean(&quot;myPet&quot;, Pet.class);</strong> //обращаемся к объекту<br /><strong>pet.say(); </strong> //вызываем его метод<br /><strong>context.close;</strong> //закрываем контекст</p>
  <p id="d3MS">-<strong>Annotations + XML file (современный способ)</strong>;<br />Аннотации – это специальные комментарии/метки/метаданные, которые нужны для передачи определенной информации.<br />Конфигурация с помощью аннотаций более короткий и быстрый способ, чем конфигурация с помощью XML файла.<br />Порядок действий состоит из двух этапов:<br />-происходит сканирование классов и поиск аннотации @Component;<br />-далее, создание(регистрация) бина в Spring Container.<br />В конфиг файле необходимо обозначить пакет, в котором будет проходить сканирование на наличие component (также, скан пройдет и в подпакетах):<br /><strong>&lt;context:component-scan base-package=&quot;spring_introduction&quot;/&gt;</strong><br />Далее, классы, которые имеют аннотацию @Component, будут добавлены в контейнер и ими можно будет пользоваться, через создание Application Context. <br />При добавлении аннотации @Component(“”), -&gt; в скобках указывается id бина. Если к аннотации @Component не прописать bean id, то бину будет назначен дефолтный id (дефолтный id получается из имени класса, заменяя его первую заглавную букву на прописную). (хорошим тоном считается прописать свой id).</p>
  <p id="orQg">-<strong>Java code(современный способ)</strong>;<br />Использование java code в качестве конфигурации Spring Container, обладает двумя способами:</p>
  <p id="KYSp"><strong>1 способ</strong> заключается в создании класса MyConfig (название класса может быть любым):<br /><strong>@Configuration</strong><br /><strong>@ComponentScan(&quot;spring_introduction&quot;)</strong><br /><strong>public class MyConfig {}</strong><br />@Configuration – означает, что данный класс является конфигурацией.<br />С помощью аннотации @ComponentScan мы показываем, какой пакет нужно сканировать на наличие бинов и разных аннотаций.<br />В таком случае, настроить Application Context уже необходимо с помощью другого класса:<br /><strong>AnnotationConfigApplicationContext context = new<br />AnnotationConfigApplicationContext(MyConfig.class);</strong><br />Остальные классы, которые мы определяем в бины, имеют всё те же аннотации по определению в контейнер и по внедрению зависимости.</p>
  <p id="STeG"><strong>2 способ</strong> не использует сканирование пакета и поиск бинов(сокращает кол-во аннотаций в коде).<br /><strong>@Configuration</strong><br /><strong>public class MyConfig {}</strong><br />В следствие этого, мы не нуждаемся в определении бинов с помощью @Component и в определении зависимости с помощью @Autowired.<br />В классе MyConfig, прописываем методы, которые добавляют наши бины, с помощью аннотации @Bean(аннотация перехватывает все обращения к бину и регулирует его создание):<br /><strong>@Bean</strong><br /><strong>public Pet catBean(){return new Cat();}</strong><br />Также, мы можем добавить аннотацию @Scope, для определения состояния бина, выбрав один из двух вариантов, и указав его в скобках (singletone или prototype).<br />Далее, для внедрения зависимости, мы создаем следующий метод, в том же классе MyConfig:<br /><strong>@Bean</strong><br /><strong>public Person personBean(){return new Person(catBean());}</strong><br />Следующий шаг, установим значения для нашего объекта типа Person, и как было описано выше, воспользуемся нашим properties файлом. Но теперь мы пропишем конфигурацию не в XML файле, а в классе MyConfig с помощью аннотации @PropertySource.<br />Для этого мы добавляем аннотацию к описанию класса и в скобках указываем путь до нашего файла:<br /><strong>@Configuration</strong><br /><strong>@PropertySource(&quot;classpath:myApp.properties&quot;)</strong><br /><strong>public class MyConfig {…}<br /><br /></strong></p>
  <p id="41ci"><strong><u>Способы внедрения зависимостей (DI):</u></strong></p>
  <p id="bUZR">-<strong>С помощью конструктора;</strong><br /><strong>&lt;bean id = &quot;myPerson</strong>&quot; //идентификатор бина<br /> <strong>class = &quot;spring_introduction.Person&quot;&gt;</strong> //полное имя класса<br /><strong>&lt;constructor-arg ref=&quot;myPet&quot;/&gt;</strong> //конструктор класса, с указанием аргумента<br /><strong>&lt;/bean&gt;</strong><br />В примере выше, бин myPerson зависит от бина myPet.<br />Далее в приложении:<br /><strong>Person person =</strong> <br /><strong>context.getBean(&quot;myPerson&quot;, Person.class);</strong> //объявляем бин<br /><strong>person.callYourPet();</strong> //вызываем необходимый метод<br /><strong>context.close() </strong> //закрываем контекст</p>
  <p id="7MWw">-<strong>С помощью сеттеров</strong>;<br /><strong>&lt;bean id = &quot;myPerson&quot;<br />class = &quot;spring_introduction.Person&quot;&gt;<br />&lt;property name=&quot;pet&quot; ref=&quot;myPet&quot;/&gt;</strong> //pet это конвертация от setPet<br /><strong>&lt;/bean&gt;</strong></p>
  <p id="sPBJ">-<strong>Autowiring</strong>;<br />…рассмотрим позже.<br /><br /></p>
  <p id="Gm7R"><strong>Внедрение строк и других значений из properties файла:</strong><br />Создаем файл myApp.properties, в нем установим конкретные значения:<br />person.surname = Khakimov<br />person.age = 27<br />Далее, для его чтения, перед созданием бинов, мы прописываем следующую конфигурацию:<br /><strong>&lt;context:property-placeholder</strong><br /><strong>location=&quot;classpath:myApp.properties&quot;/&gt;</strong><br />И в бине прописываем следующие значения:<br />&lt;bean id = &quot;myPerson&quot;<br />class = &quot;spring_introduction.Person&quot;&gt;<br />&lt;property name=&quot;pet&quot; ref=&quot;myPet&quot;/&gt;<br />&lt;property name=&quot;surname&quot; value=&quot;${person.surname}&quot;/&gt; &lt;property name=&quot;age&quot; value=&quot;${person.age}&quot;/&gt;<br />&lt;/bean&gt;</p>
  <hr />
  <p id="MNDK"><strong>Что такое бины? </strong>Sping Bean – это объект, который создается и управляется Spring Container. Например, когда мы сами создаем new объект, то и называем его объектом. В случае, когда объект создает Spring Container, он называется - бин(bean).  <br /><br /><strong>Что такое Bean Scope?</strong>  Scope(область видимости) определяет:  <br />-жизненный цикл бина;  <br />-возможное кол-во создаваемых бинов;   <br />Разновидности bean scope { singletone, prototype, request, session, global-session}    <u>singltone </u><br />– дефолтный scope (можно создать только один объект)  <br />-такой бин создается сразу после прочтения Spring Container конфиг файла;  -является общим для всех, кто запросит у Spring Container;  <br />-подходит для stateless объектов (объекты, которые менять не придется);    <u>prototype </u><br /> -такой бин создается только после обращения к Spring Container с помощью метода getBean;  <br />-для каждого такого обращения создается новый бин в Spring Container;  -подходит для stateful объектов (объекты, которые хранят какое то состояние);</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@khakimovdinis/JavawhiteRabbit0001</guid><link>https://teletype.in/@khakimovdinis/JavawhiteRabbit0001?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis</link><comments>https://teletype.in/@khakimovdinis/JavawhiteRabbit0001?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=khakimovdinis#comments</comments><dc:creator>khakimovdinis</dc:creator><title>The hashCode and equals methods</title><pubDate>Sun, 17 Sep 2023 15:15:00 GMT</pubDate><description><![CDATA[Какие бывают ассоциативные массивы (Map)? Какие из них быстрее? Что нужно сделать, чтобы они заработали быстрее? Для чего нужны ф-ии hashCode и equals?]]></description><content:encoded><![CDATA[
  <p id="UXrW"><strong>Какие бывают ассоциативные массивы (Map)? Какие из них быстрее? Что нужно сделать, чтобы они заработали быстрее? Для чего нужны ф-ии hashCode и equals?</strong></p>
  <p id="YGNf">Рассмотрим основные моменты, для понимания потребности в методах. Разделим ассоциативные массивы на три различных типа мапов:</p>
  <p id="1j37"><strong>HashMap</strong>(выводит элементы без порядка)(Для хранения элементов используются бакеты(Backet/Slot))</p>
  <p id="mIso"><strong>LinkedHashMap</strong>(вывел элементы в том порядке, в каком и добавляли)(Для хранения элементов используются бакеты(Backet/Slot))</p>
  <p id="MPTt"><strong>TreeMap</strong>(выводит элементы в порядке отсортированном по ключу)(является самым медленным, по той причине, что когда мы добавляем элемент, он сравнивает его ключ с ключами присутствующих элементов, и основываясь на результате сравнения, в процессе добавления, сортирует порядок)</p>
  <p id="UYXm">Основная логика ассоциативных массивов, что вы можете добавить в них большое кол-во данных с ключами и дальше по ключу их оттуда доставать. При этом, каждый ключ имеет одно уникальное значение.</p>
  <p id="rWqr">В <strong>TreeMap</strong> ключи должны соответствовать интерфейсу Comparable. Для этого достаточно имплементировать интерфейс <strong>Comparable</strong> и реализовать ф-ю <strong>compareTo()</strong> которая возвращает значение Integer. (TreeMap не использует ф-ю equals).</p>
  <p id="Hne2">В <strong>HashMap, LinkedHashMap,</strong> нам нужно переопределить ф-ии <strong>hashCode</strong> и <strong>equals</strong>, таким образом, чтобы сравнить все внутренние элементы нашего класса.</p>
  <p id="8tw1"><strong>Контракт метода equals</strong></p>
  <ol id="jbIL">
    <li id="5nf7">Рефлексивность (reflexive): Объект должен быть равен самому себе, т.е. для каждого нулевого x, x.equals(x) должно возвращать true.</li>
    <li id="GsIa">Симметричность (symmetric): Объекты должны быть равны друг другу, т.е. для ненулевых x и y, x.equals(y) должно возвращать true только если y.equals(x) возвращает true.</li>
    <li id="xB9c">Транзитивность (transitive): Для ненулевых x, y, z (три объекта), если x.equals(y) возвращает true, и y.equals(z) возвращает true, то x.equals(z) должно возвращать true.</li>
    <li id="tmU4">Повторяемость (consistent): Для ненулевых x и y последовательные вызовы x.equals(y) должны постоянно возвращать true или постоянно возвращать false при условии, что x и y не меняются.</li>
  </ol>
  <p id="Rt6f"><strong>Контракт метода HashCode</strong></p>
  <ol id="Ti8s">
    <li id="THnu">У двух одинаковых объектов должен быть одинаковый хеш-код.</li>
    <li id="yiI1">У двух разных объектов могут быть одинаковые хеш-коды. (Как написать функцию, чтобы избежать возникновение коллизии?)</li>
    <li id="PDD1">Нельзя возвращать константу или рандомное число.</li>
  </ol>
  <p id="y292">Работая со множеством, мы проверяем, не имеют ли наши объекты одинаковый hashCode. И использование hashCode и equals интересно тогда, когда мы работаем с группой объектов одного типа, и для их быстрого различия, мы и используем ф-ию hashCode. <br />Сначала мы обращаемся к методу hashCode(проверяем уникальность), и если хеш-коды одинаковые (напомню, что это значит произошла коллизия), переходим в метод equals.</p>
  <p id="bckq">Соответственно, при проектирования какого либо класса, если мы понимаем, что будем сравнивать объекты этого класса, то необходимо реализовать метод hashCode.</p>
  <p id="2IHD"><strong>Переопределение методов (@Override)</strong><br />При переопределении методов, в большинстве случаев, мы выбираем все поля нашего класса. Методы hashCode и equals переопределяются всегда вместе, так как связаны одним контрактом.</p>
  <pre id="Vrt7">@Override
public boolean equals(Object o) { 
if (this == o) return true; 
if (o == null || getClass() != o.getClass()) return false; 
Human human = (Human) o; 
return id == human.id &amp;&amp; Objects.equals(firstName, human.firstName) &amp;&amp; Objects.equals(lastName, human.lastName);}</pre>
  <p id="nSeb"><strong>if (this == o) return true;</strong> - говорит нам о том, что наши ссылки равны друг другу.</p>
  <p id="u0E9"><strong>if (o == null || getClass() != o.getClass()) return false;</strong> - если объект равен нулю и объект не принадлежит одному и тому же классу(т.е. классы не равны), то возвращаем false.</p>
  <pre id="85Qa">@Override
public int hashCode() { 
return Objects.hash(id, firstName, lastName);}</pre>
  <p id="hi5i"><strong>return Objects.hash(id, firstName, lastName);</strong> - возвращаем хэш код нашего объекта.</p>
  <p id="P3qf">В нашем примере, мы можем сами устанавливать критерии сравнения наших объектов. Например, сравнивать только по id. Или сравнивать по всем параметрам типа, как указано выше.</p>
  <hr />
  <p id="XBUT"><strong>Что такое бакеты(bucket(-ведро))?</strong> Набор элементов хеш-таблицы с совпадающими/близкими значением хеш-функции. <br />У каждого объекта в JVM, есть функция HashCode, когда мы что то добавляем в HashMap или LinkedHashMap, коллекция высчитывает хеш-код элемента и основываясь на результате, кладет его в структуру данных. При добавлении нового элемента, операция повторяется и вычисляется новый хеш, после чего определяется место для элемента. <br />Когда мы будем искать по ключу определенное значение из нашей коллекции, сначала для ключа просчитается хеш-код, по хещ-коду будет найден <strong>бакет</strong>, в котором лежит наш объект и дальше будет доставаться значение для этого <strong>объекта</strong>, предварительно сравнив с конкретным ключом, который лежит в этом бакете.</p>
  <p id="dZ5G"><strong>Что возвращает ф-я compareTo()? </strong>Функция возвращает целочисленное значение Integer. &quot;-1&quot; если левый объект, меньше чем правый. &quot;1&quot; если левый больше чем правый. &quot;0&quot; если они равны</p>
  <hr />
  <p id="M1rF">Полезные ссылки:</p>
  <p id="ihDI">(<a href="https://www.youtube.com/watch?v=6qVRci8gG-M" target="_blank">https://www.youtube.com/watch?v=6qVRci8gG-M</a>)</p>
  <p id="Iwij">(https://ru.stackoverflow.com/questions/988722/%D0%A7%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-buckets-%D0%B8%D0%BB%D0%B8-%D0%B1%D0%B0%D0%BA%D0%B5%D1%82)</p>
  <p id="CjrF">(https://medium.com/@vaibhav0109/https-medium-com-vaibhav0109-java-hashcode-collision-how-uniform-is-its-distribution-ee4e5e8dc894)</p>
  <p id="Un2S">(<a href="https://itsobes.ru/JavaSobes/equals-hashcode/" target="_blank">https://itsobes.ru/JavaSobes/equals-hashcode/</a>)</p>

]]></content:encoded></item></channel></rss>