Вопросы с собеседования 👩💻
Что такое Vector?
Что такое Vector?
Anonymous Quiz
21%
Массив фиксированного размера
13%
Коллекция уникальных элементов
64%
Устаревшая синхронизированная реализация списка
3%
Класс для работы с файлами
Collectors в Java
Collectors.collectingAndThen
Collectors.collectingAndThen – это особый коллектор, который добавляет финальное преобразование к результату другого коллектора. Это мощный инструмент для пост-обработки данных после сбора.
1. Базовая концепция
Сигнатура:
Где:
downstream – основной коллектор (например, toList, groupingBy)
finisher – функция, применяемая к результату коллектора
RR – новый тип возвращаемого значения
2. Простые примеры
2.1. Создание неизменяемого списка
2.2. Получение первого элемента
3. Комбинация с другими коллекторами
3.1. Группировка с неизменяемыми значениями
3.2. Подсчет с дополнительной проверкой
4. Внутренняя реализация
Принцип работы:
Сначала выполняется основной коллектор (downstream)
Затем к его результату применяется finisher
Возвращается преобразованное значение
Псевдокод:
5. Практические применения
5.1. Безопасное извлечение Optional
5.2. Нормализация данных после группировки
6. Особенности и ограничения
Порядок выполнения:
Сначала полностью выполняется downstream-коллектор
Затем применяется finisher
Параллельные стримы:
Работает корректно, если finisher – thread-safe
Null-обработка:
Finisher должен сам обрабатывать null-значения
7. Производительность
Обычно добавляет незначительные накладные расходы:
5-10% к времени выполнения базового коллектора
В HotSpot часто инлайнится JIT-компилятором
#Java #Training #Medium #Collectors #partitioningBy
Collectors.collectingAndThen
Collectors.collectingAndThen – это особый коллектор, который добавляет финальное преобразование к результату другого коллектора. Это мощный инструмент для пост-обработки данных после сбора.
1. Базовая концепция
Сигнатура:
public static <T, A, R, RR> Collector<T, A, RR> collectingAndThen(
Collector<T, A, R> downstream,
Function<R, RR> finisher
)
Где:
downstream – основной коллектор (например, toList, groupingBy)
finisher – функция, применяемая к результату коллектора
RR – новый тип возвращаемого значения
2. Простые примеры
2.1. Создание неизменяемого списка
List<String> immutableList = stream
.collect(Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList
));
2.2. Получение первого элемента
String firstItem = stream
.collect(Collectors.collectingAndThen(
Collectors.toList(),
list -> list.isEmpty() ? null : list.get(0)
);
3. Комбинация с другими коллекторами
3.1. Группировка с неизменяемыми значениями
Map<String, List<Integer>> unmodifiableGroups = numbers.stream()
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(
n -> n % 2 == 0 ? "even" : "odd"
),
Collections::unmodifiableMap
));
3.2. Подсчет с дополнительной проверкой
Long countOrZero = stream
.collect(Collectors.collectingAndThen(
Collectors.counting(),
c -> c > 100 ? c : 0L
));
4. Внутренняя реализация
Принцип работы:
Сначала выполняется основной коллектор (downstream)
Затем к его результату применяется finisher
Возвращается преобразованное значение
Псевдокод:
R intermediateResult = downstream.collect(stream);
RR finalResult = finisher.apply(intermediateResult);
return finalResult;
5. Практические применения
5.1. Безопасное извлечение Optional
Optional<String> lastElement = stream
.collect(Collectors.collectingAndThen(
Collectors.toList(),
list -> list.isEmpty()
? Optional.empty()
: Optional.of(list.get(list.size()-1))
);
5.2. Нормализация данных после группировки
Map<String, Set<String>> caseInsensitiveGroups = words.stream()
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(
String::toLowerCase,
Collectors.toSet()
),
Collections::unmodifiableMap
));
6. Особенности и ограничения
Порядок выполнения:
Сначала полностью выполняется downstream-коллектор
Затем применяется finisher
Параллельные стримы:
Работает корректно, если finisher – thread-safe
Null-обработка:
Finisher должен сам обрабатывать null-значения
7. Производительность
Обычно добавляет незначительные накладные расходы:
5-10% к времени выполнения базового коллектора
В HotSpot часто инлайнится JIT-компилятором
#Java #Training #Medium #Collectors #partitioningBy
Collectors в Java
Collectors.reducing
Collectors.reducing – это универсальный коллектор для выполнения операций свертки (reduction) над элементами потока. Он предоставляет более гибкую альтернативу встроенным операциям типа sum(), max() и min(), позволяя задавать собственную логику агрегации.
1. Три формы reducing
1.1. Базовая форма (с identity, mapper и операцией)
Параметры:
identity – начальное значение (аналог "нейтрального элемента")
mapper – функция преобразования элемента перед обработкой
op – операция для объединения двух значений
Пример (сумма длин строк):
1.2. Упрощенная форма (с identity и операцией)
Пример (конкатенация строк):
1.3. Минималистичная форма (только операция)
Пример (поиск максимального числа):
2. Внутренняя реализация
Принцип работы:
Для каждого элемента применяет mapper (если указан)
Накопление результата через op:
3. Практические примеры
3.1. Сложная агрегация объектов
3.2. Комбинация с groupingBy
3.3. Кастомная агрегация
4. Ограничения и нюансы
Параллельные стримы:
Требует ассоциативности операции ((a op b) op c == a op (b op c))
Пример ассоциативных операций: сложение, умножение, min/max
Неассоциативные: вычитание, деление
Null-значения:
identity не может быть null
Операция должна обрабатывать null, если mapper может его вернуть
Производительность:
Чуть медленнее специализированных коллекторов (summingInt и др.)
На 10-15% медленнее прямого reduce для примитивов
5. Альтернативы
Когда лучше использовать другие методы:
Для примитивов:
Для стандартных операций:
Для неизменяемых коллекций:
#Java #Training #Medium #Collectors #reducing
Collectors.reducing
Collectors.reducing – это универсальный коллектор для выполнения операций свертки (reduction) над элементами потока. Он предоставляет более гибкую альтернативу встроенным операциям типа sum(), max() и min(), позволяя задавать собственную логику агрегации.
1. Три формы reducing
1.1. Базовая форма (с identity, mapper и операцией)
public static <T, U> Collector<T, ?, U> reducing(
U identity,
Function<? super T, ? extends U> mapper,
BinaryOperator<U> op
)
Параметры:
identity – начальное значение (аналог "нейтрального элемента")
mapper – функция преобразования элемента перед обработкой
op – операция для объединения двух значений
Пример (сумма длин строк):
List<String> words = List.of("Java", "Stream", "API");
int totalLength = words.stream()
.collect(Collectors.reducing(
0, // identity
String::length, // mapper
Integer::sum // op
));
// Результат: 11 (4 + 6 + 1)
1.2. Упрощенная форма (с identity и операцией)
public static <T> Collector<T, ?, T> reducing(
T identity,
BinaryOperator<T> op
)
Пример (конкатенация строк):
String concatenated = words.stream()
.collect(Collectors.reducing(
"", // identity
String::concat
));
// Результат: "JavaStreamAPI"
1.3. Минималистичная форма (только операция)
public static <T> Collector<T, ?, Optional<T>> reducing(
BinaryOperator<T> op
)
Пример (поиск максимального числа):
Optional<Integer> max = Stream.of(3, 1, 4)
.collect(Collectors.reducing(
Integer::max
));
// Результат: Optional[4]
2. Внутренняя реализация
Принцип работы:
Для каждого элемента применяет mapper (если указан)
Накопление результата через op:
// Псевдокод реализации
U result = identity;
for (T element : stream) {
result = op.apply(result, mapper.apply(element));
}
return result;
Для формы без identity использует Optional для обработки пустых потоков
3. Практические примеры
3.1. Сложная агрегация объектов
record Product(String name, double price) {}
List<Product> products = List.of(
new Product("Laptop", 999.99),
new Product("Phone", 599.99)
);
// Сумма цен продуктов с названием длиннее 4 символов
double total = products.stream()
.collect(Collectors.reducing(
0.0,
p -> p.name().length() > 4 ? p.price() : 0,
Double::sum
));
3.2. Комбинация с groupingBy
// Максимальная цена в каждой категории
Map<String, Optional<Product>> byCategory = products.stream()
.collect(Collectors.groupingBy(
Product::category,
Collectors.reducing((p1, p2) ->
p1.price() > p2.price() ? p1 : p2
));
3.3. Кастомная агрегация
// Пользовательская свертка для статистики
class Stats {
int count;
double sum;
// + конструкторы/методы
}
Stats stats = stream.collect(Collectors.reducing(
new Stats(0, 0.0),
num -> new Stats(1, num),
(s1, s2) -> new Stats(
s1.count + s2.count,
s1.sum + s2.sum
)
));
4. Ограничения и нюансы
Параллельные стримы:
Требует ассоциативности операции ((a op b) op c == a op (b op c))
Пример ассоциативных операций: сложение, умножение, min/max
Неассоциативные: вычитание, деление
Null-значения:
identity не может быть null
Операция должна обрабатывать null, если mapper может его вернуть
Производительность:
Чуть медленнее специализированных коллекторов (summingInt и др.)
На 10-15% медленнее прямого reduce для примитивов
5. Альтернативы
Когда лучше использовать другие методы:
Для примитивов:
// Вместо:
.collect(reducing(0, Integer::sum))
// Лучше:
.mapToInt().sum()
Для стандартных операций:
// Вместо:
.collect(reducing(Integer::max))
// Лучше:
.max(Comparator.naturalOrder())
Для неизменяемых коллекций:
// Вместо:
.collect(reducing(Collections.emptyList(), customMerge))
// Лучше:
.collect(toUnmodifiableList())
#Java #Training #Medium #Collectors #reducing
Что выведет код?
#Tasks
import java.util.*;
public class Task010525 {
public static void main(String[] args) {
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Iterator<String> it = list.iterator();
list.add("D");
System.out.println(it.next());
}
}
#Tasks
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопросы с собеседования 👩💻
Какой метод возвращает длину массива byte?
Какой метод возвращает длину массива byte?
Anonymous Quiz
15%
getLength()
12%
count()
24%
size()
49%
length
Collectors в Java
Кастомные коллекторы и неизменяемые коллекции
1. Создание кастомных коллекторов
Коллектор реализует интерфейс Collector<T, A, R>, где:
T – тип элементов потока
A – тип аккумулятора (промежуточное хранилище)
R – тип результата
Компоненты коллектора:
Supplier<A> – создает контейнер для накопления
BiConsumer<A, T> – добавляет элемент в контейнер
BinaryOperator<A> – объединяет частичные результаты (для параллельных стримов)
Function<A, R> – преобразует аккумулятор в результат
Characteristics (опционально) – набор характеристик (CONCURRENT, UNORDERED, IDENTITY_FINISH)
Пример: Кастомный коллектор для объединения строк с разделителем
2. Неизменяемые коллекции
Java 10+ предоставляет встроенные коллекторы для неизменяемых коллекций:
2.1. Стандартные неизменяемые коллекторы
2.2. Создание через collectingAndThen
3. Комбинирование подходов
3.1. Неизменяемый кастомный коллектор
3.2. Группировка с неизменяемыми значениями
4. Особенности реализации
4.1. Параллельная обработка
Кастомные коллекторы должны иметь thread-safe аккумулятор или характеристику CONCURRENT
Combiner должен корректно объединять частичные результаты
4.2. Оптимизации
Для примитивов используйте специализированные коллекторы (summingInt, averagingDouble)
Избегайте boxing/unboxing в кастомных коллекторах
4.3. Обработка null
Встроенные неизменяемые коллекторы бросают NullPointerException при null-элементах
Решение:
Когда создавать кастомные коллекторы:
✔️ Для сложной логики агрегации
✔️ Когда встроенные коллекторы не подходят
✔️ Для оптимизации производительности в специфичных сценариях
Когда использовать неизменяемые коллекции:
✔️ Для безопасного возврата результатов из методов
✔️ В многопоточных сценариях
✔️ Для защиты данных от модификации
#Java #Training #Medium #Collectors
Кастомные коллекторы и неизменяемые коллекции
1. Создание кастомных коллекторов
Коллектор реализует интерфейс Collector<T, A, R>, где:
T – тип элементов потока
A – тип аккумулятора (промежуточное хранилище)
R – тип результата
Компоненты коллектора:
Supplier<A> – создает контейнер для накопления
BiConsumer<A, T> – добавляет элемент в контейнер
BinaryOperator<A> – объединяет частичные результаты (для параллельных стримов)
Function<A, R> – преобразует аккумулятор в результат
Characteristics (опционально) – набор характеристик (CONCURRENT, UNORDERED, IDENTITY_FINISH)
Пример: Кастомный коллектор для объединения строк с разделителем
Collector<String, StringBuilder, String> joinStrings = Collector.of(
StringBuilder::new, // supplier
(sb, str) -> { // accumulator
if (!sb.isEmpty()) sb.append(", ");
sb.append(str);
},
(sb1, sb2) -> { // combiner (для параллельных стримов)
if (sb1.length() > 0 && sb2.length() > 0) {
sb1.append(", ");
}
return sb1.append(sb2);
},
StringBuilder::toString // finisher
);
String result = Stream.of("Java", "Kotlin", "Scala")
.collect(joinStrings);
// Результат: "Java, Kotlin, Scala"
2. Неизменяемые коллекции
Java 10+ предоставляет встроенные коллекторы для неизменяемых коллекций:
2.1. Стандартные неизменяемые коллекторы
List<String> unmodifiableList = stream.collect(Collectors.toUnmodifiableList());
Set<String> unmodifiableSet = stream.collect(Collectors.toUnmodifiableSet());
Map<String, Integer> unmodifiableMap = stream.collect(
Collectors.toUnmodifiableMap(
keyMapper,
valueMapper,
mergeFunction // для обработки дубликатов
)
);
2.2. Создание через collectingAndThen
List<String> immutable = stream
.collect(Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList
));
3. Комбинирование подходов
3.1. Неизменяемый кастомный коллектор
Collector<String, List<String>, List<String>> toImmutableList = Collector.of(
ArrayList::new, // supplier
List::add, // accumulator
(left, right) -> { // combiner
left.addAll(right);
return left;
},
Collections::unmodifiableList // finisher
);
3.2. Группировка с неизменяемыми значениями
Map<String, List<Integer>> immutableGroups = numbers.stream()
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(
n -> n % 2 == 0 ? "even" : "odd"
),
Collections::unmodifiableMap
));
4. Особенности реализации
4.1. Параллельная обработка
Кастомные коллекторы должны иметь thread-safe аккумулятор или характеристику CONCURRENT
Combiner должен корректно объединять частичные результаты
4.2. Оптимизации
Для примитивов используйте специализированные коллекторы (summingInt, averagingDouble)
Избегайте boxing/unboxing в кастомных коллекторах
4.3. Обработка null
Встроенные неизменяемые коллекторы бросают NullPointerException при null-элементах
Решение:
.filter(Objects::nonNull)
.collect(toUnmodifiableList())
Когда создавать кастомные коллекторы:
✔️ Для сложной логики агрегации
✔️ Когда встроенные коллекторы не подходят
✔️ Для оптимизации производительности в специфичных сценариях
Когда использовать неизменяемые коллекции:
✔️ Для безопасного возврата результатов из методов
✔️ В многопоточных сценариях
✔️ Для защиты данных от модификации
#Java #Training #Medium #Collectors
Reflection API (оглавление)
Reflection API — Определение, назначение, преимущества и недостатки
Базовые понятия и практическое применение Reflection API
Класс Class и его методы
Класс Class и его методы. Часть 2
Получение информации о полях
Получение информации о полях. Часть 2
Получение информации о методах
Получение информации о методах. Часть 2
Конструктор и как его получить
Работа с параметрами конструкторов
Создание объектов через Reflection
Вызов методов через Reflection
#Content
Reflection API — Определение, назначение, преимущества и недостатки
Базовые понятия и практическое применение Reflection API
Класс Class и его методы
Класс Class и его методы. Часть 2
Получение информации о полях
Получение информации о полях. Часть 2
Получение информации о методах
Получение информации о методах. Часть 2
Конструктор и как его получить
Работа с параметрами конструкторов
Создание объектов через Reflection
Вызов методов через Reflection
#Content
Multithreads in Java (оглавление)
Процессы и потоки (Process API). Класс ProcessBuilder
Запуск внешних процессов и чтение вывода
#Content
Процессы и потоки (Process API). Класс ProcessBuilder
Запуск внешних процессов и чтение вывода
#Content
Основы криптографии в Java (оглавление)
Основы криптографии в Java
Симметричная криптография: алгоритм AES
Асимметричная криптография
Асимметричная криптография. Часть 2
Хэш-функции (SHA-256, MD5)
Соль (Salt) и вектор инициализации (IV)
Классы Cipher и KeyGenerator
Классы SecretKey и IvParameterSpec
Классы KeyPairGenerator и KeyPair
Класс Signature (цифровые подписи)
Base64 в Java Crypto API
Криптографические протоколы (TLS/SSL, HMAC)
#Content
Основы криптографии в Java
Симметричная криптография: алгоритм AES
Асимметричная криптография
Асимметричная криптография. Часть 2
Хэш-функции (SHA-256, MD5)
Соль (Salt) и вектор инициализации (IV)
Классы Cipher и KeyGenerator
Классы SecretKey и IvParameterSpec
Классы KeyPairGenerator и KeyPair
Класс Signature (цифровые подписи)
Base64 в Java Crypto API
Криптографические протоколы (TLS/SSL, HMAC)
#Content
Объектно-реляционное отображение (ORM - Object-Relational Mapping) (оглавление)
Объектно-реляционное отображение (ORM - Object-Relational Mapping)
EntityManager
Аннотация @Entity
Аннотация @Table
Аннотация @Id
Аннотация @GeneratedValue
Аннотация @Column
Аннотация @Transient
Аннотация @Enumerated
Аннотация @Temporal
Аннотация @Lob
Аннотация @Version
Аннотация @Access Аннотации @AttributeOverride и @AttributeOverrides
Аннотация @Embeddable
Аннотация @Embedded
Аннотация @Inheritance
Аннотации @DiscriminatorColumn и @DiscriminatorValue
Аннотация @MappedSuperclass
Аннотация @OneToOne
Аннотации @OneToMany и @ManyToOne
Аннотация @ManyToMany
Аннотация @JoinColumn
Аннотация @JoinTable
Аннотация @ElementCollection
Аннотация @OrderColumn
Аннотация @PrimaryKeyJoinColumn
Аннотация @SecondaryTable
Аннотации @NamedQuery и @NamedQueries
Аннотации @NamedNativeQuery и @NamedNativeQueries
Аннотации @Convert и @Converter
Аннотации @PrePersist и @PostPersist
Аннотации @PreUpdate и @PostUpdate
Аннотации @PreRemove и @PostRemove
Аннотации Spring Data JPA
Аннотация @Query
Аннотация @Modifying
Аннотация @Param
Аннотация @Transactional
Аннотация @EnableJpaRepositories
Аннотация @EntityGraph
Аннотация @Lock
Аннотация @Procedure
Аннотация @IdClass
Аннотация @MapsId
Аннотация @CreatedBy
Аннотация @CreatedDate
Аннотации @LastModifiedBy и @LastModifiedDate
Аннотация @Version
Аннотация @PersistenceContext
Аннотация @EnableJpaAuditing
Аннотация @EntityListeners
Аннотация @Projection
Hibernate
Аннотация @Any
Аннотация @BatchSize
Аннотации @Cache и @Cacheable
Аннотация @Cascade
Аннотация @ColumnTransformer
Аннотация @DynamicInsert
Аннотация @DynamicUpdate
Аннотация @Filter
Аннотация @Formula
Аннотация @Generated
Аннотация @Immutable
Аннотация @Index
Аннотация @LazyCollection
Аннотация @LazyToOne
Аннотация @Loader
Аннотация @ManyToAny
Аннотация @MetaValue
Аннотация @NaturalId
Аннотация @NotFound
Аннотация @OnDelete
Аннотация @TableGenerator
Аннотация @OptimisticLock
#Content
Объектно-реляционное отображение (ORM - Object-Relational Mapping)
EntityManager
Аннотация @Entity
Аннотация @Table
Аннотация @Id
Аннотация @GeneratedValue
Аннотация @Column
Аннотация @Transient
Аннотация @Enumerated
Аннотация @Temporal
Аннотация @Lob
Аннотация @Version
Аннотация @Access Аннотации @AttributeOverride и @AttributeOverrides
Аннотация @Embeddable
Аннотация @Embedded
Аннотация @Inheritance
Аннотации @DiscriminatorColumn и @DiscriminatorValue
Аннотация @MappedSuperclass
Аннотация @OneToOne
Аннотации @OneToMany и @ManyToOne
Аннотация @ManyToMany
Аннотация @JoinColumn
Аннотация @JoinTable
Аннотация @ElementCollection
Аннотация @OrderColumn
Аннотация @PrimaryKeyJoinColumn
Аннотация @SecondaryTable
Аннотации @NamedQuery и @NamedQueries
Аннотации @NamedNativeQuery и @NamedNativeQueries
Аннотации @Convert и @Converter
Аннотации @PrePersist и @PostPersist
Аннотации @PreUpdate и @PostUpdate
Аннотации @PreRemove и @PostRemove
Аннотации Spring Data JPA
Аннотация @Query
Аннотация @Modifying
Аннотация @Param
Аннотация @Transactional
Аннотация @EnableJpaRepositories
Аннотация @EntityGraph
Аннотация @Lock
Аннотация @Procedure
Аннотация @IdClass
Аннотация @MapsId
Аннотация @CreatedBy
Аннотация @CreatedDate
Аннотации @LastModifiedBy и @LastModifiedDate
Аннотация @Version
Аннотация @PersistenceContext
Аннотация @EnableJpaAuditing
Аннотация @EntityListeners
Аннотация @Projection
Hibernate
Аннотация @Any
Аннотация @BatchSize
Аннотации @Cache и @Cacheable
Аннотация @Cascade
Аннотация @ColumnTransformer
Аннотация @DynamicInsert
Аннотация @DynamicUpdate
Аннотация @Filter
Аннотация @Formula
Аннотация @Generated
Аннотация @Immutable
Аннотация @Index
Аннотация @LazyCollection
Аннотация @LazyToOne
Аннотация @Loader
Аннотация @ManyToAny
Аннотация @MetaValue
Аннотация @NaturalId
Аннотация @NotFound
Аннотация @OnDelete
Аннотация @TableGenerator
Аннотация @OptimisticLock
#Content