🔥1
В Java лямбда-выражения используются с функциональными интерфейсами, которые имеют ровно один абстрактный метод. Например, стандартный функциональный интерфейс
Function из пакета java.util.function представляет собой типичный пример.Для нашего примера используем встроенный функциональный интерфейс
IntUnaryOperator. Он выглядит вот так:
@FunctionalInterface
public interface IntUnaryOperator {
int applyAsInt(int operand);
}
Этот интерфейс представляет функцию, которая принимает один аргумент типа
int и возвращает значение типа int.
import java.util.function.IntUnaryOperator;
public class Main {
public static int applyOperation(int number, IntUnaryOperator operator) {
return operator.applyAsInt(number);
}
public static void main(String[] args) {
int number = 5;
// Лямбда-выражение для удвоения значения
IntUnaryOperator doubleOperation = x -> x * 2;
System.out.println("Double: " + applyOperation(number, doubleOperation)); // Double: 10
// Лямбда-выражение для увеличения значения на 10
IntUnaryOperator addTenOperation = x -> x + 10;
System.out.println("Add Ten: " + applyOperation(number, addTenOperation)); // Add Ten: 15
}
}
В нашем примере метод
applyOperation принимает два параметра: число и функциональный интерфейс IntUnaryOperator. Лямбда-выражение используется для определения конкретной функции.#java #lambda #IntUnaryOperator
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤2🔥2
Что выведет код?
Anonymous Quiz
23%
x = 16, y = 10
64%
x = 16, y = 11
7%
x = 15, y = 11
5%
x = 15, y = 10
🎉4👍3❤1
Метод
hashCode() необходим для вычисления хэш кода переданного в качестве входного параметра объекта. В Java это целое число, в более широком смысле - битовая строка фиксированной длины, полученная из массива произвольной длины. Этот метод реализован таким образом, что для одного и того же входного объекта, хэш код всегда будет одинаковым. Следует понимать, что в Java множество возможных хэш кодов ограничено типом int, а множество объектов ничем не ограничено. Из-за этого, вполне возможна ситуация, что хэш коды разных объектов могут совпасть:✔️ если хэш коды разные, то и объекты гарантированно разные;
✔️ если хэш коды равны, то объекты не обязательно равны(могут быть разные).
#java #hashCode
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍3
Для того что бы определить лямбда-выражение, нам нужен функциональный интерфейс. Изобретём свой:
@FunctionalInterface
interface MathOperation {
int operate(int a, int b);
}
Функциональный интерфейс
MathOperation содержит один абстрактный метод operate, который принимает два значения типа int и возвращает int. Аннотация @FunctionalInterface указывает на то, что интерфейс предназначен для использования в функциональном программировании и должен содержать только один абстрактный метод. Но аннотация не обязательна.Использование лямбда-выражения:
public class LambdaExample {
public static void main(String[] args) {
// Реализация интерфейса с помощью лямбда-выражения
MathOperation addition = (a, b) -> a + b;
MathOperation subtraction = (a, b) -> a - b;
MathOperation multiplication = (a, b) -> a * b;
MathOperation division = (a, b) -> a / b;
int x = 10;
int y = 5;
System.out.println("Addition: " + operate(x, y, addition)); // 15
System.out.println("Subtraction: " + operate(x, y, subtraction)); // 5
System.out.println("Multiplication: " + operate(x, y, multiplication)); // 50
System.out.println("Division: " + operate(x, y, division)); // 2
}
// Метод, принимающий MathOperation и применяющий его к данным
private static int operate(int a, int b, MathOperation operation) {
return operation.operate(a, b);
}
}
В нашем примере лямбда-выражения используются для создания экземпляров интерфейса
MathOperation для выполнения различных математических операций (сложение, вычитание и т.д.).Метод
operate принимает два целых числа и функциональный интерфейс MathOperation, затем выполняет переданную операцию. В метод в третьем параметре можно передать непосредственно лямбда-выражение, не используя промежуточную переменную.#java #lambda #FunctionalInterface
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍19❤🔥2❤1
Что произойдет, если попытаться вызвать метод start() для потока, который уже был запущен (например, при повторном вызове thread.start())?
Anonymous Quiz
6%
Поток просто запустится заново
10%
Поток завершит свою текущую работу и начнет выполнение заново
45%
Будет выброшено исключение IllegalThreadStateException
39%
Ничего не произойдет, так как повторный вызов start() игнорируется
🤯3😱1
Общий совет: выбирать поля, которые с большой долью вероятности будут различаться. Для этого необходимо использовать уникальные, лучше всего примитивные поля, например, такие как id, uuid. При этом нужно следовать правилу, если поля задействованы при вычислении
hashCode(), то они должны быть задействованы и при выполнении equals().#java #hashCode #equals
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤2
Да, могут. Метод
hashCode() не гарантирует уникальность возвращаемого значения. Ситуация, когда у разных объектов одинаковые хэш коды называется коллизией. Вероятность возникновения коллизии зависит от используемого алгоритма генерации хэш кода.#java #hashCode
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍6❤3
public interface Adder {
int add(int a, int b);
}
public interface SmartAdder extends Adder {
int add(double a, double b);
}
public interface Nothing {
}
👍5❤1
Какой из интерфейсов является функциональным?
Anonymous Quiz
48%
Adder
12%
SmartAdder
9%
Nothing
31%
Ни один из них
❤3👍1
Лямбда-выражения на первый взгляд могут показаться чем-то сложным и загадочным, но на самом деле они просты и интуитивно понятны.
Лямбда-выражение — это лаконичный способ описания анонимной функции, которую можно передать в качестве параметра или сохранить в переменной для последующего использования.
Если говорить ещё проще, лямбда-выражение — это просто другой способ создания и реализации объекта определённого типа. Рассмотрим это на примере создания нового потока.
У класса
Thread есть конструктор:
public Thread(Runnable target) {
...
}
То есть в конструктор нужно передать объект типа
Runnable. До лямбда-выражений мы сделали бы так:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello World");
}
}).start();
Здесь мы создаём анонимный класс, реализующий интерфейс
Runnable, с определённым методом run.Если использовать лямбда-выражение, тот же код будет выглядеть следующим образом:
Runnable r = () -> System.out.println("Hello World");
new Thread(r).start();
Или проще:
new Thread(() -> System.out.println("Hello World")).start();
Лямбда-выражение заменяет собой анонимный класс, который раньше был бы необходим для реализации
Runnable. Лямбда-выражение может использоваться только там, где ожидается реализация функционального интерфейса — интерфейса с единственным абстрактным методом. А интерфейс
Runnable именно такой:
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Функциональный интерфейс должен содержать только один абстрактный метод, чтобы компилятор мог точно определить, какой метод реализует лямбда-выражение. В противном случае возникли бы неоднозначности и ошибки.
#java #lambda #Runnable
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥15👍7❤4👎1
Какой интерфейс нужно реализовать в классе, чтобы объект этого класса можно было использовать в выражении "for-each" справа?
Anonymous Quiz
81%
Iterable
9%
Comparable
6%
Serializable
4%
Runnable
👍2🎉1
class Person {
Long id;
String name;
public Person(Long id, String name) {
this.id = id;
this.name = name;
}
public boolean equals(Person other) {
if (other == this) {
return true;
}
return id != null && id.equals(other.id);
}
}
public class Quest {
public static void main(String[] args) {
Person person1 = new Person(1L, "John");
Person person2 = new Person(1L, "Jane");
System.out.print(person1.equals(person2));
System.out.print("-");
System.out.print(Objects.equals(person1, person2));
}
}
#java #quest
1👍5🔥1🎉1
Использование оператора присваивания не создает нового объекта, а лишь копирует ссылку на объект. Таким образом, две ссылки указывают на одну и ту же область памяти, на один и тот же объект. Для создания нового объекта с таким же состоянием используется клонирование объекта.
Класс
Object содержит protected метод clone(), осуществляющий побитовое копирование объекта производного класса. Однако сначала необходимо переопределить метод clone() как public для обеспечения возможности его вызова. В переопределенном методе следует вызвать базовую версию метода super.clone(), которая и выполняет собственно клонирование.Чтобы окончательно сделать объект клонируемым, класс должен реализовать интерфейс
Cloneable. Интерфейс Cloneable не содержит методов относится к маркерным интерфейсам, а его реализация гарантирует, что метод clone() класса Object возвратит точную копию вызвавшего его объекта с воспроизведением значений всех его полей. В противном случае метод генерирует исключение CloneNotSupportedException. Следует отметить, что при использовании этого механизма объект создается без вызова конструктора.
public class MyClass implements Cloneable {
private int value;
// Конструкторы и методы класса
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Это решение эффективно только в случае, если поля клонируемого объекта представляют собой значения базовых типов и их обёрток или неизменяемых (immutable) объектных типов. Если же поле клонируемого типа является изменяемым ссылочным типом, то для корректного клонирования требуется другой подход. Причина заключается в том, что при создании копии поля оригинал и копия представляют собой ссылку на один и тот же объект. В этой ситуации следует также клонировать и сам объект поля класса.
Такое клонирование возможно только в случае, если тип атрибута класса также реализует интерфейс
Cloneable и переопределяет метод clone(). Так как, если это будет иначе вызов метода невозможен из-за его недоступности. Отсюда следует, что если класс имеет суперкласс, то для реализации механизма клонирования текущего класса-потомка необходимо наличие корректной реализации такого механизма в суперклассе. При этом следует отказаться от использования объявлений final для полей объектных типов по причине невозможности изменения их значений при реализации клонирования.Помимо встроенного механизма клонирования в Java для клонирования объекта можно использовать:
✔️ Специализированный конструктор копирования - в классе описывается конструктор, который принимает объект этого же класса и инициализирует поля создаваемого объекта значениями полей переданного.
✔️ Фабричный метод - (Factory method), который представляет собой статический метод, возвращающий экземпляр своего класса.
✔️ Механизм сериализации - сохранение и последующее восстановление объекта в/из потока байтов.
#java #clone
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍5🔥1