← Назад к вопросам
С каким функциональным интерфейсом взаимодействует map
1.6 Junior🔥 291 комментариев
#Коллекции
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Функциональный интерфейс для метода map
Метод map() в Stream API взаимодействует с функциональным интерфейсом Function<T, R>, который определён в пакете java.util.function.
Определение Function
@FunctionalInterface
public interface Function<T, R> {
// Основной метод
R apply(T t);
// Дополнительные методы (default)
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
T - тип входных данных (input type) R - тип результата (return type)
Использование map с Function
Stream<String> stream = Stream.of("apple", "banana", "cherry");
// map принимает Function<String, Integer>
Stream<Integer> lengths = stream.map(str -> str.length());
lengths.forEach(System.out::println);
// Вывод: 5 6 6
Примеры различных трансформаций
List<String> fruits = Arrays.asList("apple", "banana", "cherry");
// 1. Преобразование String в Integer
List<Integer> lengths = fruits.stream()
.map(fruit -> fruit.length()) // Function<String, Integer>
.collect(Collectors.toList());
// Результат: [5, 6, 6]
// 2. Преобразование Integer в String
List<Integer> numbers = Arrays.asList(1, 2, 3);
List<String> stringNumbers = numbers.stream()
.map(num -> String.valueOf(num)) // Function<Integer, String>
.collect(Collectors.toList());
// Результат: ["1", "2", "3"]
// 3. Преобразование объекта в его свойство
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35)
);
List<String> names = people.stream()
.map(Person::getName) // Function<Person, String>
.collect(Collectors.toList());
// Результат: ["Alice", "Bob", "Charlie"]
Различные способы использования Function
1. Лямбда выражение
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> doubled = numbers.map(n -> n * 2);
// Результат: 2, 4, 6, 8, 10
2. Method Reference
List<String> words = Arrays.asList("hello", "world");
List<String> upper = words.stream()
.map(String::toUpperCase) // Function<String, String>
.collect(Collectors.toList());
// Результат: ["HELLO", "WORLD"]
3. Анонимный класс
Stream<Integer> numbers = Stream.of(1, 2, 3);
Stream<Integer> squared = numbers.map(new Function<Integer, Integer>() {
@Override
public Integer apply(Integer n) {
return n * n;
}
});
4. Ссылка на конструктор
List<String> names = Arrays.asList("Alice", "Bob");
List<Integer> ages = Arrays.asList(30, 25);
Stream<Person> people = Stream.of(
new Person("Alice", 30),
new Person("Bob", 25)
);
List<String> personNames = people.stream()
.map(Person::getName) // Function<Person, String>
.collect(Collectors.toList());
Сравнение map с другими методами Stream
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// map - преобразует тип (Function<T, R>)
List<Integer> doubled = numbers.stream()
.map(n -> n * 2) // Function<Integer, Integer>
.collect(Collectors.toList());
// Результат: [2, 4, 6, 8, 10]
// filter - оставляет элементы (Predicate<T>)
List<Integer> evens = numbers.stream()
.filter(n -> n % 2 == 0) // Predicate<Integer>
.collect(Collectors.toList());
// Результат: [2, 4]
// forEach - выполняет действие (Consumer<T>)
numbers.stream()
.forEach(n -> System.out.println(n)); // Consumer<Integer>
// reduce - комбинирует элементы (BinaryOperator<T>)
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b); // BinaryOperator<Integer>
// Результат: 15
Цепочка map операций
List<String> words = Arrays.asList("hello", "world", "java");
List<Integer> result = words.stream()
.map(String::toUpperCase) // Function<String, String>
.map(String::length) // Function<String, Integer>
.map(len -> len * 2) // Function<Integer, Integer>
.collect(Collectors.toList());
// Результат: [10, 10, 8]
flatMap - специальный вариант
// map для вложенных структур
List<List<Integer>> lists = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4),
Arrays.asList(5, 6)
);
// map преобразует List<Integer> -> Stream<Integer>
// но остаёт Stream<Stream<Integer>>
Stream<Stream<Integer>> streamOfStreams = lists.stream()
.map(List::stream); // Function<List<Integer>, Stream<Integer>>
// flatMap - развёртывает (распрямляет) результат
List<Integer> flat = lists.stream()
.flatMap(List::stream) // Function<List<Integer>, Stream<Integer>>
.collect(Collectors.toList());
// Результат: [1, 2, 3, 4, 5, 6]
Практический пример: обработка JSON
class User {
private String name;
private String email;
public User(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() { return name; }
public String getEmail() { return email; }
}
List<User> users = Arrays.asList(
new User("Alice", "alice@example.com"),
new User("Bob", "bob@example.com")
);
// Преобразование User в JSON-подобную строку
List<String> json = users.stream()
.map(user -> "{\"name\":\"" + user.getName() +
"\",\"email\":\"" + user.getEmail() + "\"}")
.collect(Collectors.toList());
// Результат: [{"name":"Alice","email":"alice@example.com"}, ...]
Другие функциональные интерфейсы для Stream
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// map -> Function<T, R>
numbers.stream().map(n -> n * 2);
// filter -> Predicate<T>
numbers.stream().filter(n -> n > 2);
// forEach -> Consumer<T>
numbers.stream().forEach(System.out::println);
// reduce -> BinaryOperator<T> (функция от двух T к T)
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
// sorted -> Comparator<T>
numbers.stream().sorted((a, b) -> b - a);
// collect -> Collector<T, A, R>
numbers.stream().collect(Collectors.toList());
Вывод
map() использует Function<T, R>, где:
- T - исходный тип элементов потока
- R - тип результата после трансформации
Это позволяет преобразовывать элементы потока в элементы нового потока с другим типом данных. Function - это один из основных функциональных интерфейсов в Java, предоставляющий простой способ определить трансформацию данных.