<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Dinis Khakimov</title><author><name>Dinis Khakimov</name></author><id>https://teletype.in/atom/khakimovdinis</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/khakimovdinis?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@khakimovdinis?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=khakimovdinis"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/khakimovdinis?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-05-31T12:10:39.207Z</updated><entry><id>khakimovdinis:JavaWhiteRabbit0004</id><link rel="alternate" type="text/html" href="https://teletype.in/@khakimovdinis/JavaWhiteRabbit0004?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=khakimovdinis"></link><title>SAX and DOM parsing in Java</title><published>2023-09-18T14:58:11.992Z</published><updated>2023-09-18T14:59:20.776Z</updated><category term="java-input-output-operations" label="Java | InputOutputOperations"></category><summary type="html">Для начала разберемся, что такое XML файл и для чего он нужен. 

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

Также, XML файл достаточно удобен для передачи какой либо информации между разными системами (например между сервером и телефоном). Представляет собой текстовый файл, содержащий информацию в структурированном виде, который понятен для большинства языков программирования, и как раз в этом и есть основное назначение XML файла.</summary><content type="html">
  &lt;p id=&quot;pojI&quot;&gt;Для начала разберемся, что такое XML файл и для чего он нужен. &lt;br /&gt;&lt;br /&gt;Для Java-приложений XML-файлы могут также служить в качестве конфигурационных файлов (например, для сохранения параметров приложения, конфигурации сервисов и других настроек).&lt;br /&gt;&lt;br /&gt;Также, XML файл достаточно удобен для передачи какой либо информации между разными системами (например между сервером и телефоном). Представляет собой текстовый файл, содержащий информацию в структурированном виде, который понятен для большинства языков программирования, и как раз в этом и есть основное назначение XML файла.  &lt;/p&gt;
  &lt;p id=&quot;E9ar&quot;&gt;XML(eXtensible Markup Language) - расширяемый язык разметки документов. В отличие от HTML, который направлен на визуальное представление документа в браузере, XML используется для обмена данными между компьютером и приложением. &lt;br /&gt;&lt;br /&gt;Внутри, файл выглядит, как набор тегов с информацией(открывающие и закрывающие) в виде древовидной структуры. &lt;br /&gt;Рассмотрим пример ниже. В каждом файле существует корневой тег - в нашем случае &amp;lt;voters&amp;gt; (он может иметь любое имя, в зависимости от выполняемой задачи). Далее, идут ветви, их может быть несколько, в нашем случае они одного типа с тегом voter и visit. И внутри мы имеем атрибуты {name, birthDay, station, time} с их значениями.&lt;/p&gt;
  &lt;pre id=&quot;iLZm&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;voters&amp;gt;
&amp;lt;voter name=&amp;quot;Тиронов Мартьян&amp;quot; birthDay=&amp;quot;1932.11.08&amp;quot;&amp;gt;   
&amp;lt;visit station=&amp;quot;120&amp;quot; time=&amp;quot;2015.09.17 15:51:40&amp;quot; /&amp;gt;
&amp;lt;/voter&amp;gt;
&amp;lt;voter name=&amp;quot;Варик Макар&amp;quot; birthDay=&amp;quot;1924.12.31&amp;quot;&amp;gt;   
&amp;lt;visit station=&amp;quot;48&amp;quot; time=&amp;quot;2015.09.21 22:24:28&amp;quot; /&amp;gt;
&amp;lt;/voter&amp;gt;
&amp;lt;voter name=&amp;quot;Погребной Миронег&amp;quot; birthDay=&amp;quot;1948.05.23&amp;quot;&amp;gt;   
&amp;lt;visit station=&amp;quot;170&amp;quot; time=&amp;quot;2015.09.19 14:59:01&amp;quot; /&amp;gt;
&amp;lt;/voter&amp;gt;
...
...
&amp;lt;/voters&amp;gt;&lt;/pre&gt;
  &lt;p id=&quot;9KPr&quot;&gt;&lt;br /&gt;Далее, на основе XML нам нужно создать объектную модель. Для этого создается пакет model и в нем создается класс, с таким именем, как и в XML файле. &lt;br /&gt;Класс создается для добавления и дальнейшей работы с элементами, которые находятся в XML файле. &lt;/p&gt;
  &lt;p id=&quot;OCmb&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;MVAO&quot;&gt;Существуют несколько стратегий обработки XML документов. Мы &lt;br /&gt;рассмотрим -  DOM (Document Object Model) и SAX (Simple API for XML). Основное их отличие связано с тем, что использование DOM позволяет читать и вносить изменения в существующий XML-документ, а также создавать новый. Стратегия использования SAX основывается на том, что содержимое XML-документа только анализируется. XML-текст может быть больших размеров: DOM должен весь документ «заглотить» и проанализировать, а SAX-парсер обрабатывает XML-документ последовательно и не требует дополнительной памяти.&lt;/p&gt;
  &lt;p id=&quot;ojyU&quot;&gt;&lt;strong&gt;&lt;u&gt;DOM API&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;DOM (Document Object Model) - это стандартный способ представления и взаимодействия с содержимым XML-документов в программах на Java. Предоставляет процесс обработки по факту, загружая файл полностью в память.  Хорошо работает с небольшими файлами. &lt;/p&gt;
  &lt;p id=&quot;iS2M&quot;&gt;Для парсинга, нам следует открыть файл, используя объекты типа - File, DocumentBuilderFactory, DocumentBuilder, Document.&lt;br /&gt;В DOM есть три важных объекта - Node(каждый элемент(отступы, строки и тд) в XML), NodeList(получаем лист наших Node), Element(конкретный объект, заключаемый в тег).&lt;/p&gt;
  &lt;p id=&quot;CHqv&quot;&gt;&lt;u&gt;&lt;strong&gt;SAX API&lt;/strong&gt;&lt;/u&gt;&lt;br /&gt;SAX(Simple API for XML) - это API, который используется для чтения и обработки XML-документов в Java. Он очень быстр и мало зависит от объема данных, за счет этого имеет большую популярность. &lt;br /&gt;Чтение XML документа с помощью SAX является событийном процессом, то есть SAX предоставляет набор обработчиков событий, которые вызываются автоматически при обработке каждого элемента документа. Файл в память подгружается частями. &lt;br /&gt;&lt;br /&gt;Для парсинга мы используем объекты типа - SAXParserFactory(&lt;em&gt;Определяет API фабрики, который позволяет приложениям сконфигурировать и получить SAX базируемый синтаксический анализатор, чтобы проанализировать XML-документы&lt;/em&gt;), SAXParser. И для успешной работы парсера нам необходимо переопределить нужные нам методы класса DefaultHandler.&lt;br /&gt;&lt;/p&gt;
  &lt;p id=&quot;e1Zh&quot;&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;29Rr&quot;&gt;Полезные ссылки:&lt;br /&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=wXupOedG6vU&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/watch?v=wXupOedG6vU&lt;br /&gt;&lt;/a&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=T0nRDi0k4fU&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/watch?v=T0nRDi0k4fU&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://java-online.ru/java-xml.xhtml&quot; target=&quot;_blank&quot;&gt;https://java-online.ru/java-xml.xhtml&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://habr.com/ru/articles/62757/&quot; target=&quot;_blank&quot;&gt;https://habr.com/ru/articles/62757/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;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&quot; target=&quot;_blank&quot;&gt;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&lt;/a&gt;.&lt;/p&gt;

</content></entry><entry><id>khakimovdinis:JavaWhiteRabbit0003</id><link rel="alternate" type="text/html" href="https://teletype.in/@khakimovdinis/JavaWhiteRabbit0003?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=khakimovdinis"></link><title>Serialization and deserialization</title><published>2023-09-17T17:44:44.983Z</published><updated>2023-09-17T17:44:44.983Z</updated><category term="java-input-output-operations" label="Java | InputOutputOperations"></category><summary type="html">Используя сериализацию объектов, мы сможем разложить свои объекты на последовательность байтов и затем использовать их наиболее эффективным образом (обычно используется в Hibernate, JMS, JPA и EJB). Для чего? Чтобы создаваемые нами объекты могли существовать за пределами жизненного цикла виртуальной машины.</summary><content type="html">
  &lt;p id=&quot;b1CK&quot;&gt;Используя &lt;u&gt;сериализацию &lt;/u&gt;объектов, мы сможем разложить свои объекты на последовательность байтов и затем использовать их наиболее эффективным образом (обычно используется в Hibernate, JMS, JPA и EJB). Для чего? Чтобы создаваемые нами объекты могли существовать за пределами жизненного цикла виртуальной машины. &lt;/p&gt;
  &lt;p id=&quot;MxS0&quot;&gt;&lt;u&gt;Десериализация&lt;/u&gt; - это процесс обратного преобразования потока данных байтового типа в объект в памяти. &lt;br /&gt;&lt;br /&gt;Существует три способа выполнения сериализации {Используя протокол по умолчанию, Изменяя протокол по умолчанию, Создавая собственный протокол}.&lt;br /&gt;В данной статье рассмотрим первый способ.&lt;/p&gt;
  &lt;p id=&quot;F8qf&quot;&gt;Для того, чтобы отметить наш объект, как сериализумый, мы должны реализовать  интерфейс java.io.Serializable, что и будет являться для API знаком того, что объект может быть разложен на байты и затем вновь восстановлен. &lt;br /&gt;Интерфейс Serializable является лишь маркерным интерфейсом и позволяет механизму сериализации определить возможность сохранения данного класса.&lt;br /&gt;&lt;br /&gt;Класс, на котором будем демонстрировать примеры, выглядит следующим образом:&lt;/p&gt;
  &lt;pre id=&quot;CeJB&quot; data-lang=&quot;java&quot;&gt;

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();    }}&lt;/pre&gt;
  &lt;p id=&quot;K44Y&quot;&gt;&lt;br /&gt;&lt;u&gt;Механизм используемый по умолчанию:&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Далее, что нужно для сохранения объекта? Сохранения выполняется при помощи класса java.io.ObjectOutputStream. Этот класс является фильтрующим потоком, он окружает низкоуровневый поток байтов(называемый узловым потоком(node stream))(?) и предоставляет нам поток сериализации. Узловые потоки могут быть использованы для записи в файловую систему или в сокеты. Это позволяет нам передавать разложенные на байты объекты по сети и затем восстанавливать их на других устройствах. &lt;br /&gt;&lt;br /&gt;Посмотрим код, который демонстрирует процесс сериализации:&lt;/p&gt;
  &lt;pre id=&quot;YWY3&quot; data-lang=&quot;java&quot;&gt;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

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

if(args.length &amp;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();        }    }}

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

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

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

</content></entry><entry><id>khakimovdinis:JavawhiteRabbit0001</id><link rel="alternate" type="text/html" href="https://teletype.in/@khakimovdinis/JavawhiteRabbit0001?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=khakimovdinis"></link><title>The hashCode and equals methods</title><published>2023-09-17T15:15:00.784Z</published><updated>2023-09-17T15:15:00.784Z</updated><summary type="html">Какие бывают ассоциативные массивы (Map)? Какие из них быстрее? Что нужно сделать, чтобы они заработали быстрее? Для чего нужны ф-ии hashCode и equals?</summary><content type="html">
  &lt;p id=&quot;UXrW&quot;&gt;&lt;strong&gt;Какие бывают ассоциативные массивы (Map)? Какие из них быстрее? Что нужно сделать, чтобы они заработали быстрее? Для чего нужны ф-ии hashCode и equals?&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;YGNf&quot;&gt;Рассмотрим основные моменты, для понимания потребности в методах. Разделим ассоциативные массивы на три различных типа мапов:&lt;/p&gt;
  &lt;p id=&quot;1j37&quot;&gt;&lt;strong&gt;HashMap&lt;/strong&gt;(выводит элементы без порядка)(Для хранения элементов используются бакеты(Backet/Slot))&lt;/p&gt;
  &lt;p id=&quot;mIso&quot;&gt;&lt;strong&gt;LinkedHashMap&lt;/strong&gt;(вывел элементы в том порядке, в каком и добавляли)(Для хранения элементов используются бакеты(Backet/Slot))&lt;/p&gt;
  &lt;p id=&quot;MPTt&quot;&gt;&lt;strong&gt;TreeMap&lt;/strong&gt;(выводит элементы в порядке отсортированном по ключу)(является самым медленным, по той причине, что когда мы добавляем элемент, он сравнивает его ключ с ключами присутствующих элементов, и основываясь на результате сравнения, в процессе добавления, сортирует порядок)&lt;/p&gt;
  &lt;p id=&quot;UYXm&quot;&gt;Основная логика ассоциативных массивов, что вы можете добавить в них большое кол-во данных с ключами и дальше по ключу их оттуда доставать. При этом, каждый ключ имеет одно уникальное значение.&lt;/p&gt;
  &lt;p id=&quot;rWqr&quot;&gt;В &lt;strong&gt;TreeMap&lt;/strong&gt; ключи должны соответствовать интерфейсу Comparable. Для этого достаточно имплементировать интерфейс &lt;strong&gt;Comparable&lt;/strong&gt; и реализовать ф-ю &lt;strong&gt;compareTo()&lt;/strong&gt; которая возвращает значение Integer. (TreeMap не использует ф-ю equals).&lt;/p&gt;
  &lt;p id=&quot;Hne2&quot;&gt;В &lt;strong&gt;HashMap, LinkedHashMap,&lt;/strong&gt; нам нужно переопределить ф-ии &lt;strong&gt;hashCode&lt;/strong&gt; и &lt;strong&gt;equals&lt;/strong&gt;, таким образом, чтобы сравнить все внутренние элементы нашего класса.&lt;/p&gt;
  &lt;p id=&quot;8tw1&quot;&gt;&lt;strong&gt;Контракт метода equals&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;jbIL&quot;&gt;
    &lt;li id=&quot;5nf7&quot;&gt;Рефлексивность (reflexive): Объект должен быть равен самому себе, т.е. для каждого нулевого x, x.equals(x) должно возвращать true.&lt;/li&gt;
    &lt;li id=&quot;GsIa&quot;&gt;Симметричность (symmetric): Объекты должны быть равны друг другу, т.е. для ненулевых x и y, x.equals(y) должно возвращать true только если y.equals(x) возвращает true.&lt;/li&gt;
    &lt;li id=&quot;xB9c&quot;&gt;Транзитивность (transitive): Для ненулевых x, y, z (три объекта), если x.equals(y) возвращает true, и y.equals(z) возвращает true, то x.equals(z) должно возвращать true.&lt;/li&gt;
    &lt;li id=&quot;tmU4&quot;&gt;Повторяемость (consistent): Для ненулевых x и y последовательные вызовы x.equals(y) должны постоянно возвращать true или постоянно возвращать false при условии, что x и y не меняются.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Rt6f&quot;&gt;&lt;strong&gt;Контракт метода HashCode&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;Ti8s&quot;&gt;
    &lt;li id=&quot;THnu&quot;&gt;У двух одинаковых объектов должен быть одинаковый хеш-код.&lt;/li&gt;
    &lt;li id=&quot;yiI1&quot;&gt;У двух разных объектов могут быть одинаковые хеш-коды. (Как написать функцию, чтобы избежать возникновение коллизии?)&lt;/li&gt;
    &lt;li id=&quot;PDD1&quot;&gt;Нельзя возвращать константу или рандомное число.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;y292&quot;&gt;Работая со множеством, мы проверяем, не имеют ли наши объекты одинаковый hashCode. И использование hashCode и equals интересно тогда, когда мы работаем с группой объектов одного типа, и для их быстрого различия, мы и используем ф-ию hashCode. &lt;br /&gt;Сначала мы обращаемся к методу hashCode(проверяем уникальность), и если хеш-коды одинаковые (напомню, что это значит произошла коллизия), переходим в метод equals.&lt;/p&gt;
  &lt;p id=&quot;bckq&quot;&gt;Соответственно, при проектирования какого либо класса, если мы понимаем, что будем сравнивать объекты этого класса, то необходимо реализовать метод hashCode.&lt;/p&gt;
  &lt;p id=&quot;2IHD&quot;&gt;&lt;strong&gt;Переопределение методов (@Override)&lt;/strong&gt;&lt;br /&gt;При переопределении методов, в большинстве случаев, мы выбираем все поля нашего класса. Методы hashCode и equals переопределяются всегда вместе, так как связаны одним контрактом.&lt;/p&gt;
  &lt;pre id=&quot;Vrt7&quot;&gt;@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;&amp;amp; Objects.equals(firstName, human.firstName) &amp;amp;&amp;amp; Objects.equals(lastName, human.lastName);}&lt;/pre&gt;
  &lt;p id=&quot;nSeb&quot;&gt;&lt;strong&gt;if (this == o) return true;&lt;/strong&gt; - говорит нам о том, что наши ссылки равны друг другу.&lt;/p&gt;
  &lt;p id=&quot;u0E9&quot;&gt;&lt;strong&gt;if (o == null || getClass() != o.getClass()) return false;&lt;/strong&gt; - если объект равен нулю и объект не принадлежит одному и тому же классу(т.е. классы не равны), то возвращаем false.&lt;/p&gt;
  &lt;pre id=&quot;85Qa&quot;&gt;@Override
public int hashCode() { 
return Objects.hash(id, firstName, lastName);}&lt;/pre&gt;
  &lt;p id=&quot;hi5i&quot;&gt;&lt;strong&gt;return Objects.hash(id, firstName, lastName);&lt;/strong&gt; - возвращаем хэш код нашего объекта.&lt;/p&gt;
  &lt;p id=&quot;P3qf&quot;&gt;В нашем примере, мы можем сами устанавливать критерии сравнения наших объектов. Например, сравнивать только по id. Или сравнивать по всем параметрам типа, как указано выше.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;XBUT&quot;&gt;&lt;strong&gt;Что такое бакеты(bucket(-ведро))?&lt;/strong&gt; Набор элементов хеш-таблицы с совпадающими/близкими значением хеш-функции. &lt;br /&gt;У каждого объекта в JVM, есть функция HashCode, когда мы что то добавляем в HashMap или LinkedHashMap, коллекция высчитывает хеш-код элемента и основываясь на результате, кладет его в структуру данных. При добавлении нового элемента, операция повторяется и вычисляется новый хеш, после чего определяется место для элемента. &lt;br /&gt;Когда мы будем искать по ключу определенное значение из нашей коллекции, сначала для ключа просчитается хеш-код, по хещ-коду будет найден &lt;strong&gt;бакет&lt;/strong&gt;, в котором лежит наш объект и дальше будет доставаться значение для этого &lt;strong&gt;объекта&lt;/strong&gt;, предварительно сравнив с конкретным ключом, который лежит в этом бакете.&lt;/p&gt;
  &lt;p id=&quot;dZ5G&quot;&gt;&lt;strong&gt;Что возвращает ф-я compareTo()? &lt;/strong&gt;Функция возвращает целочисленное значение Integer. &amp;quot;-1&amp;quot; если левый объект, меньше чем правый. &amp;quot;1&amp;quot; если левый больше чем правый. &amp;quot;0&amp;quot; если они равны&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;M1rF&quot;&gt;Полезные ссылки:&lt;/p&gt;
  &lt;p id=&quot;ihDI&quot;&gt;(&lt;a href=&quot;https://www.youtube.com/watch?v=6qVRci8gG-M&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/watch?v=6qVRci8gG-M&lt;/a&gt;)&lt;/p&gt;
  &lt;p id=&quot;Iwij&quot;&gt;(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)&lt;/p&gt;
  &lt;p id=&quot;CjrF&quot;&gt;(https://medium.com/@vaibhav0109/https-medium-com-vaibhav0109-java-hashcode-collision-how-uniform-is-its-distribution-ee4e5e8dc894)&lt;/p&gt;
  &lt;p id=&quot;Un2S&quot;&gt;(&lt;a href=&quot;https://itsobes.ru/JavaSobes/equals-hashcode/&quot; target=&quot;_blank&quot;&gt;https://itsobes.ru/JavaSobes/equals-hashcode/&lt;/a&gt;)&lt;/p&gt;

</content></entry></feed>