# Java ## Функция main ```Java package org.example; public class Main { public static void main(String[] args) { System.out.println("Hello world!"); } } ``` ## Сокращения InteliJ * psvm - public static void main * sout - Sytem.out.println() * serr - System.err.println() * I - for(Object object: ){} * fori - for (int i = 0; i< ; i++) {} * shift + shift - поиск по проекту * ctrl + alt + t - сниппеты для блоков кода (циклы, if, switch, try-catch) * alt + insert - сниппеты для класса ## Строки Строки неизменяемые (immutable) и не могут иметь наследников (final). Для изменения копии ```Java // foo и bar - 1 объект в Pool (аля static) String foo = "foo"; String bar = "foo"; // baz - объект в куче String baz = new String("baz"); ``` ### StringBuffer и StringBuilder Данные типы - изменяемые строки с изменениями на месте. StringBuffer синхронизирует методы, поэтому медленее, но можно работать в многопотоке. StringBuilder быстрее, но методы не синхронизирует ```Java // Можно передать строку в инициализатор, но не обязательно StringBuffer sb = new StringBuffer(); sb.append("foo"); sb.append(5); ``` #### Методы StringBuffer и StringBuilder * append (смотреть выше) * delete(int start, int end) * insert(int offeset, String str) * replace(int start, int end, String str) * reverse() * substring(int start, int end) - создаст новую строку * toString - перевести в строку ### RegEx RegEx - щаблон для поиска строки в тексте #### Примеры RegEx * "java" - только слово java подойдёт * "\\d{3}" - 3 цифры #### Pattern для RegEx Pattern - скомпилированный RegEx ```Java Pattern p = Pattern.compile("java"); p = Pattern.compile("java", Pattern.CASE_INSENSETIVE); ``` ## Var Var выбирает тип по типу данных, который мы присваеваем. Нужно инициализировать при объявлении ```Java var x = 5; ``` ## Константы В Java константы объявляются словом *final* ```Java final int LIMIT = 5; ``` ## Массивы Объявлять массивы можно разными способами ```Java int nums[] = new int[] {10, 20}; int[] nums = {10, 20, 30}; ``` ### Многомерный массив ```Java int[][] nums = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; ``` ## Параметры переменной длины ```Java static void sum(int ...nums) { int result = 0; for(int n: nums) { result += n; } System.out.println(result); } ``` Все обязательные параметры до параметрвов переменной длины ## Значения по умолчанию для параметров **Их нету!!!** ## Перегрузка методов Перегрузка позволяет определять функции с одинаковым именем, но с разными типами и/или кол-вом параметров. ```Java static int sum(int a, int b) { return a + b; } static double sum(double a, double b) { return a + b; } ``` Если отличается только выходной тип, то останется только последняя имплементация ```Java // Эту версию не получится вызвать static int sum(int a, int b) { return a + b; } // Будет вызываться эта версия static double sum(int a, int b) { return a + b; } ``` ## Обработка ошибок ### try-catch-finally ```Java try { int[] a = new int[3]; a[4] = 5; } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("Will always print this"); } ``` ### *throw* ```Java throw new Exception("Very important exception! Don't you dare not handle it"); ``` ### *throws* Позволяет кинуть ошибку вверх по стаку ```Java public static void main(String[] args) throws Exception {} ``` ## OOP OOP - бяка, Java - OOP => Java - бяка ```Java public class Foo { int bar; string baz; void fooBar() { System.out.println("FooBaz"); } } ``` ### Модификаторы доступа * public - везде * private - только внутри класса * protected - подклассы и сам класс Если не указан, то применяется модификатор по умолчанию. Он делает переменную public в пределах данного пакета ### Конструктор и инициализатор ```Java public class Test { int age; int age2; int age3; // Блок - инициализатор { age = 5 } // Конструктор public Test(int age2, int age3_input) { this.age2 = age2; age3 = age3_input; // Такое не делать, ибо не красиво } } ``` ### Наследование ```Java public class Foo {} public class Bar extends Foo {} ``` Множественное наследование низя. Приватное не наследуется #### *Override* ```Java class Foo { int foo() { return 5; } } class Bar extends Foo { @Override int foo() { return 6; } } ``` Уровень видимости при *Override* не может понижаться. У переопределённого метода должен быть такой же интерфейс, как и у родителя #### *super* *super* позволяет обратиться к методам родительского класса ```Java class Foo { int foo() { return 5; } } class Bar extends Foo { @Override int foo() { return super.foo(); } } ``` #### *final* при наследовании *final* запрещает наследование #### Наследование конструктора ```Java class Foo { int a, b; Foo(int a, int b) { this.a = a; this.b = b; } } class Bar extends Foo { int c; Bar(int a, int b, int c) { // Тут super должен быть сверху, иначе ошибка super(a, b); this.c = c; } } ``` #### *instanceof* Позволяет проверить, создан ли объект на основе какого-то класса ```Java class Foo { int a, b; Foo(int a, int b) { this.a = a; this.b = b; } } class Bar extends Foo { int c; Bar(int a, int b, int c) { // Тут super должен быть сверху, иначе ошибка super(a, b); this.c = c; } } class Main { public static void main() { Bar bar = new Bar(); System.out.println(bar instanceof Foo); } } ``` #### Абстрактные классы Абстрактные классы могут иметь абстрактные методы (без имплементации), но от них низя создать объект. ```Java abstract class Car { int speed; public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } abstract int brake(); } class Sedan extends Car { @Override int brake() { return 5; } } public class Main { public static void main(String[] args) { Car car = new Car(); // Низя. Класс абстрактный Sedan sedan = new Sedan(); } } ``` ### Интерфейсы Абстрактные классы для классов, которые имеют много общего, имеют близкую связть, а интерфейсы используются для тех, которые не имеют связи: * Bird - абстрактный класс * Flyable - интерфейс. Его могут имплементировать и птицы, и самолёты, и Карлсон Отличия от классов: * Нельзя создать экземпляр * Не содержатся конструкторы * Все методы абстрактные * Все поля и *static* и *final* * Интерфейс не расширяется классом, а реализуется * Интерфейс может расширить множество интерфейсов ```Java public interface Swimmable { public void swim(); } class Duck implements Swimmable { public void swim() { System.out.println("A duck is swimming"); } } ``` Могут быть определения по умолчанию ```Java public interface Swimmable { default public void swim() { System.out.println("Something is swimming") } } class Duck implements Swimmable {} ``` Могут быть статические и приватные (доступные только внутри интерфейса) методы и константы ```Java public interface Foo { int VALUE = 5; // Подразумевается public static final т.е. публичная константная static void foo() { System.out.println("Foo"); } private int bar(int a, int b) { return a + b; } } class Bar implements Foo {} ``` Интерфейсы могут расширять друг друга ```Java interface Foo { void foo(); } interface Bar extends Foo { default void bar() { return; } } class Baz implements Bar { public void foo() {} } ``` Интерфейсы могут быть вложены в классы ```Java class Printer { interface Printable { void print(); } } class Journal implements Printer.Printable { public void print() { System.out.println("Priniting journal"); } } ``` ### Классы обёртки *Обёртка* - класс, хранящий внутри значение примитива. Эти классы содержат полезные методы и являются не изменяемыми #### Автораспаковка, автоупаковка ```Java int x = 5; Integer y = x; // Автоупаковка x = y; // Автораспаковка ``` Автоупаковка и автораспаковка не работает для массивов ## Коллекции Основные виды: * *Set* * *HashSet* * *TreeSet* * *SortedSet* * *List* * *ArrayList* * *LinkedList* * *Vector* * *Stack* * *Map* * *HashMap* * *TreeMap* * *SortedMap* * *Hashtable* ### Итераторы Позволяет перебирать значения коллекций. Может использоваться для неупорядоченных коллекций ```Java Set set = new HashSet(); set.add("A"); set.add("B"); Iterator iter = set.iterator(); while (iter.hasNext()) { String text = iter.next(); System.out.println(text); } ``` ```Java Map map = new HashMap(); map.put("first", "A"); Iterator> iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry pair = iter.next(); String key = pair.getKey(); String value = pair.getValue(); System.out.println(key + ":" + value); } ``` Можно использовать *foreach* ```Java Set set = new HashSet(); set.add("A"); set.add("B"); for (String text : set) { System.out.println(text); } ``` ### ArrayList ```Java ArrayList nums = new ArrayList(); nums.add(5); nums.add(5); nums.add(5); nums.add(5); nums.add(5); System.out.println(nums.get(1)); System.out.println(nums.indexOf(5)); System.out.println(nums.contains(3)); nums.add(4, 3); // insert`ит на 4 индекс число 3 nums.set(4, 5); // Меняет число на 4 индексе на 5 System.out.println(nums.toString()); nums.clear(); nums.add(5); nums.add(5); nums.add(5); Integer[] numss = nums.toArray(new Integer[0]); nums = new ArrayList<>(Arrays.asList(numss)); Collections.sort(nums); ``` Ещё методы у Collections: * *min* * *max* * *reverse* * *shuffle* * *swap* * *disjoint* - если есть пересечение коллекций, то false, иначе true #### Неизменяемый список ```Java List = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(1, 2, 3))); ``` ### LinkedList *LinkedList* - двусвязный список ```Java LinkedList nums = new LinkedList(); nums.add(5); nums.add(5); nums.add(5); ``` Особые методы: * *addFirst* * *addLast* * *peekFirst* * *peekLast* * *pollFirst* - получить первый и удалить его (null, если пусто) * *pollLast* ### Vector *Vector* - синхронизированный *ArrayList*, который всё хранит как Object. Синтаксис страшный. ### Stack *Stack* - LIFO Методы: * *empty* - возвращает bool * *peek* * *pop* * *push* * *search* - возвращает offset от вершины стека ### Deque *Deque* - двунаправленный стек с фиксированной длинной Методы: * *addFirst* * *addLast* * *getFirst* - без удаления * *getLast* * *offerFirst* * *offerLast* * *peekFirst* * *peekLast* * *pollFirst* - с удалением * *pollLast* ### ArrayDeque *ArrayDeque* - двунаправленный стек с динамической длиной Методы: * *addFirst* * *addLast* * *getFirst* - без удаления * *getLast* * *pollFirst* - с удалением * *pollLast* ### HashSet Аля Rust. Использует метод hashCode() для получения хеша значений Методы: * add * remove * contains * size * clear * isEmpty * iterator ## Enum ```Java enum Country { CANADA, NETHERLANDS } enum Country2 { CANADA("CAN"), NETHER("NTH"), ENGLAND } ``` ## Работа с файлами * FileWriter * FileReader В конце их нужно закрывать ```Java import java.io.FileReader; import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { FileReader fr = new FileReader("Foo.txt"); Scanner scanner = new Scanner(fr); ArrayList words = new ArrayList<>(); while (scanner.hasNext()) { words.add(scanner.next()); } Collections.sort(words); System.out.println(words); } } ``` ## Generic ```Java class Account { // Account account = new Account("FooBar"); private T id; public int sum; public Account(T id, int sum) { this.id = id; this.sum = sum; } public T getId() { return id; } } class Printer { public static void print(T[] items) { // Вызывать так: Printer.print(new String[]{"a", "b"}); for(T item: items) { System.out.println(item); } } } interface Acountable { String getId(); } class Account2 implements Acountable { String id; public Account2(T id) { // Account account = new Account(5); this.id = id.toString(); } public String getId() { return id; } } class Transaction { // T может быть только наследником Account T account; } class Transaction2 { // T имплементирует Acountable T account; } class Transaction3 { // T имплементирует Accountable и наследует Account T account; } ``` ## Records > Записи или Records позволяют быстро содздавать классы, уменьшая количесво бойлерплейта. Записи автоматически определяют инициализатор, методы hashCode, toString и equals. Поля являются *private* и *final* и имеют одноимённые геттеры ```Java record Person(String name, int age) { } ``` Можно добавить дополнительную логику в созданный конструктор ```Java record Person(String name, int age) { Person { if(age < 1 || age > 110) { age = 18; } } } ``` Можно полностью переписать изначальный конструктор ```Java record Person(String name, int age) { Person(String name, int age) { this.name = name; if(age < 1 || age > 110) { age = 18; } this.age = age; } } ``` Мы можем определять какие-то другие конструкторы, но они вызывать канонический конструктор ```Java record Person(String name, int age) { Person(String firstName, String lastName, int age) { this(firstName + " " + lastName, age); } } ``` Можно также переопределить остальные методы ```Java record Person(String name, int age) { public String name() { return "Mister " + name; } public String toString() { return "What a fine gentleman we have here" } } ``` ### Ограничения record Классы *record* не могут наследовать, быть наследованными и абстрактными, но могут имплементировать интерфейсы. Нельзя добавлять дополнительные нестатические пора и инициализаторы ```Java record Person(String name, int age) { static int minAge; static { // Это статический инициализатор minAge = 18; } } ``` ## Upcasting & Downcasting ```Java class Person {} class Employee {} class Main { public static void main(String[] args) { Object bob = new Person(); // Upcasting Person tom = new Employee(); // тоже upcasting Person bob2 = (Person)bob; } } ``` ## Comparator & Comparable ```Java import java.util.Comparator; import java.util.TreeSet; class Person implements Comparable { private String name; private int age; Person(String name, int age) { this.name = name; this.age = age; } String getName() { return name; } int getAge() { return age; } // Отриц число, если меньше, 0, если равно, и полож число, если больше public int compareTo(Person p) { return name.compareTo(p.getName()); } } class PersonNameComparator implements Comparator { public int compare(Person a, Person b) { return a.getName().compareTo(b.getName()); } } class PersonAgeComparator implements Comparator { public int compare(Person a, Person b) { return a.getAge() - b.getAge(); } } class Main { public static void main(String[] args) { Comparator pcomp = (new PersonNameComparator()).thenComparing(new PersonAgeComparator()); TreeSet people = new TreeSet(pcomp); people.add(new Person("Tom", 10)); people.add(new Person("Tam", 12)); people.add(new Person("Tim", 13)); people.add(new Person("Bill", 40)); people.add(new Person("Bob", 15)); for(Person p : people) { System.out.println(p.getName()); } } } ``` ## Лямбда > Лямбда представляет набор инструкций,которые можно выделить в отдельную переменную ```Java public class Main { public static void main(String[] args) { Operation op = (x, y) -> x + y; Operation op2 = (int x, int y) -> x - y; int result = op.calculate(10, 20); System.out.println(result); System.out.println(op.calculate(10, 20)); } } interface Operation { int calculate(int x, int y); } ``` Альтернативные формы: * () -> 30 + 30 * n -> n * n Лямбда функции могут возвращать void ```Java interface Printer { void print(String s); } class Main { public static void main(String[] args) { Printer p = (s) -> System.out.println(s); } } ``` Переменные, которые используются в лямбде нельзя менять ### Блоки кода в лямбда-функциях ```Java public class Main { public static void main(String[] args) { Operation op = (int x, int y) -> { if(x < 0) { x = -x; } return x + y; }; } } interface Operation { int calculate(int x, int y); } ``` ### Обобщённые лямбды ```Java public class Main { public static void main(String[] args) { Operation op = (x, y) -> { if(x < 0) { x = -x; } return x + y; }; } } interface Operation { T calculate(T x, T y); } ``` ## Ссылки на метод, как параметр методов ```Java interface Operation { int calculate(int x, int y); } class Operations { static int Add(int x, int y) { return x + y; } } class Main { public static void main(String[] args) { Operation op = Operations::Add; } } ``` Также можно ссылаться на методы объекта, через *переменная::метод*, и на конструктор, через *класс::new*. Лямбды также можно возврощать ## Встроенные функцианальные интерфейсы * *Predicate\* - *boolean test(T t)* * *BinaryOperator\* - *T apply(T t1, T t2)* * *UnaryOperator\* - *T apply(T t)* * *Function\* - *R apply(T t)* * *Consumer\* - *void accept(T t)* * *Supplier\* - *T get()* ## *Java.Util* ### Класс *Locale* > Локали - боль... страдания... *C++* *Locale.getDefault()* чтобы получить текущую ### *Date* > *Date* - штука для работы с датами. Можно использовать для форматирования с помощью *Locale* ### *Calendar* & *GregorianCalendar* > *Calendar* - абстрактный класс, а *GregorianCalendar* - имплементация. Он также держит часы, минуты, секунды. Класс *DateFormat* для красивого вывода ### *TimeZone* & *SimpleTimeZone* > *Calendar* - абстрактный класс, а *GregorianCalendar* - имплементация. Он также держит часы, минуты, секунды. Нужны для работы с часовыми поясами ### *UUID* > *UUID* - класс для работы с UUID ```Java UUID id = UUID.randomUUID(); ``` ### *StringTokenizer* > *StringTokenizer* нужен для разделения строк на токены, используя данный разделитель (по умолчанию пробел) ## Android Studio ### Устройство платформы Android * Базовый уровень (Linux Kernel) - firmware * Библиотеки и среда исполнения (Libraries & Android Runtime) * Каркас приложений (Application Framework) * Уровень приложений (Applications) ### Комплекты разработчика * JDK (Java Development Kit) - комплект разработчика на Java. Включает компилятор, библиотеки, примеры, документацию, утилиты и исполнительную среду * SDK (Software Development Kit) - утилиты для создания и тестирования приложений * SDK Manager - инструмент для заргузки компонентов Android SDK * Android Emulator - эмулирует телефон на компьютере * AVD Manager - графический интерфейс для создания виртуальных Android устройст * Android Debig Bridge - управление состоянием эмулятора или реального устройства, подключённого к компьютеру ### Структура Android приложения * *Gen* файлы генерируются Java. Являются обязательным компонентом * *AndroidManifest.xml* - файл манифеста предоставляет системе лсновную информацию о программе * *Src* - каталог с исходным компонентом * *Assets* - произвольное собрание каталогов и файлов * *Res* - катагол с ресурсами прилодения. Там подкапки drawable, anum, layout, menu, values, xml и raw ### Инициализация объектов Activity ```Java package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.graphics.Color; import android.os.Bundle; import android.view.View; import com.example.myapplication.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; int counter = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); binding.textView.setText("0"); binding.textView.setTextSize(33); binding.textView.setTextColor(Color.RED); binding.button.setOnClickListener((foo) -> { counter += 1; binding.textView.setText(String.valueOf(counter)); }); } } ``` ### Переключение Activity ```Java Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); ``` ### Fragments *Fragment* - подобие *activity*, но одно *activity* может содержать несколько фрагментов. Для взаимодействия фрагментов используется *FragmentManager*, а для удаления, добавления и замены *FragmentTransaction* Основные методы *FragmentManager*: * *findFragmentById(int id)* * *findFragmentByTag(String tag)* Методы *FragmentTransaction*: * *add* * *remove* * *replace* * *hide* * *show* * *detach* - открепляет от GUI, но экземпляр сохраняется * *attach* - обратный метод *detach* Для получения экземляра *FragmentTransaction* нужно вызвать *FragmentManager.beginTransaction*. После транзакции вызывается *commit* ## Адаптеры * *ArrayAdapter\* * *ListAdapter* * *SpinnerAdapter* * *SimpleAdapter* ## LayoutInflater > Позволяет из содержимого layout файла создать *View* элемент ## Spring ### Аннотации * *@Component* - помечает класс как bean (зависимость, которую можно использовать в проекте) * *@Autowired* - автоматически ещет зависимости метода, конструктора и поля * *@Primary* - помечает приорететный bean для *@Autowired* * *@Scope*("singleton" | "prototype") * *@PostConstruct* * *@PreDestroy* ### Qualifier Позволяет указатать какой класс использовать для интерфейса, когда Primary не подходит. Все qualifier с маленькой буквы ```Java public MusicPlauer(@Qualifier("rockMusic") Music music) { music.playMusic(); } ```