Функція: Трансформація Даних
У той час як Predicate допомагає оцінювати булеві вирази, Function дозволяє трансформувати дані, застосовуючи операції, які повертають результати на основі вхідних даних.
Function зазвичай використовується для трансформації даних, наприклад, для перетворення типів, обчислень або обробки значень.
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Інтерфейс Function<T, R> у Java представляє функціональний інтерфейс, який приймає аргумент типу T і повертає результат типу R.
Метод apply(T t) виконує трансформацію даних, приймаючи вхідне значення та повертаючи результат. Це дозволяє створювати гнучкі функції для обробки даних різних типів.
Практичне застосування
Припустимо, у вас є список імен користувачів, і потрібно обчислити довжину кожного імені для подальшого аналізу або обробки даних.
Main.java
1234567891011121314151617package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> users = Arrays.asList("Alice", "Bob", "Charlie", "David"); Function<String, Integer> nameLength = name -> name.length(); users.forEach(user -> { System.out.println(user + " has " + nameLength.apply(user) + " characters."); }); } }
У цьому прикладі наведено список імен користувачів. Для кожного імені використовується функція nameLength, яка обчислює кількість символів у імені за допомогою методу length(). За допомогою методу forEach здійснюється ітерація по кожному елементу списку та виводиться повідомлення із зазначенням, скільки символів містить кожне ім’я.
Комбінування функцій
Інтерфейс Function надає кілька методів для комбінування функцій, що дозволяє створювати ланцюжки операцій.
Метод andThen()
Метод andThen() дозволяє комбінувати дві функції, спочатку застосовуючи одну функцію, а потім передаючи результат другій функції. Це корисно, коли потрібно виконати декілька операцій послідовно.
Приклад
Є список імен користувачів, і потрібно зробити великою першу літеру кожного імені, а потім перевірити, чи містить ім'я більше ніж 5 символів.
Main.java
1234567891011121314151617181920212223package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("john", "alice", "bob", "charlie", "david"); // Capitalize first letter Function<String, String> capitalizeFirstLetter = name -> name.substring(0, 1).toUpperCase() + name.substring(1); // Check if the username has more than 5 characters Function<String, Boolean> isLongerThanFive = name -> name.length() > 5; // Combine functions using `andThen()` Function<String, Boolean> formattedNameThenCheckLength = capitalizeFirstLetter.andThen(isLongerThanFive); usernames.forEach(user -> { System.out.println(user + " -> " + formattedNameThenCheckLength.apply(user)); }); } }
Спочатку змінюється на велику перша літера кожного імені користувача за допомогою capitalizeFirstLetter. Далі перевіряється, чи має відформатоване ім'я більше ніж 5 символів за допомогою isLongerThanFive. Обидві функції поєднуються через andThen() для послідовної обробки.
Метод compose()
Метод compose() дозволяє комбінувати функції, але у зворотному порядку: спочатку застосовується друга функція, а результат передається у першу функцію.
Приклад
Є рядок, і потрібно спочатку обчислити його довжину, а потім додати префікс до результату.
Main.java
123456789101112131415161718package com.example; import java.util.function.Function; public class Main { public static void main(String[] args) { String phrase = "Hello World"; // First, calculate the length, then add a prefix Function<String, Integer> stringLength = String::length; Function<Integer, String> addPrefix = length -> "Length: " + length; // Combine functions using compose Function<String, String> lengthThenPrefix = addPrefix.compose(stringLength); System.out.println(lengthThenPrefix.apply(phrase)); // Output: Length: 11 } }
У цьому прикладі спочатку обчислюється довжина рядка за допомогою stringLength, а потім результат передається у функцію addPrefix, яка додає префікс. Ви використовуєте compose(), щоб застосувати функції у потрібному порядку.
Метод identity()
Метод identity() повертає функцію, яка просто повертає свій аргумент без жодних змін. Це корисно, коли потрібно передати функцію, яка не змінює вхідне значення, але потрібна для відповідності інтерфейсу.
Приклад
Уявіть, що потрібно обробити список імен користувачів, застосовуючи кілька перетворень: одне для перетворення імен у верхній регістр, інше для додавання суфікса "User", і третє — з використанням функції identity(), щоб залишити ім'я без змін. Завдання — застосувати ці функції до кожного імені у списку, зберігаючи інтерфейс програми незмінним для кожного перетворення.
Main.java
1234567891011121314151617181920212223242526272829303132package com.example; import java.util.List; import java.util.Arrays; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("alice", "bob", "charlie", "david", "eve"); // `Function` to convert the username to uppercase Function<String, String> uppercaseFunction = name -> name.toUpperCase(); // `Function` to add the "User" suffix Function<String, String> suffixFunction = name -> name + "User"; // Identity `Function`, which does nothing Function<String, String> identityFunction = Function.identity(); // Applying a combination of functions List<Function<String, ?>> transformations = Arrays.asList(uppercaseFunction, suffixFunction, identityFunction); // Applying each `Function` from the list for (Function<String, ?> transformation : transformations) { System.out.println("--------------------"); usernames.stream() .map(name -> transformation.apply(name)) .forEach(System.out::println); } } }
Як видно, вивід складається з трьох відформатованих списків імен користувачів. Останній список містить оригінальні імена, і саме тут стає у пригоді метод identity(), оскільки він дозволяє повертати імена без додаткової логіки для обробки незмінних значень. Це робить код чистішим і більш ефективним завдяки прямому використанню identity(), коли трансформація не потрібна.
1. Що робить метод andThen() у інтерфейсі Function?
2. Яким буде результат застосування методу identity()?
3. Що виконує метод compose()?
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат
Can you give an example of how to use the Function interface in Java?
What is the difference between andThen() and compose() methods?
When should I use the identity() method in practice?
Awesome!
Completion rate improved to 2.33
Функція: Трансформація Даних
Свайпніть щоб показати меню
У той час як Predicate допомагає оцінювати булеві вирази, Function дозволяє трансформувати дані, застосовуючи операції, які повертають результати на основі вхідних даних.
Function зазвичай використовується для трансформації даних, наприклад, для перетворення типів, обчислень або обробки значень.
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Інтерфейс Function<T, R> у Java представляє функціональний інтерфейс, який приймає аргумент типу T і повертає результат типу R.
Метод apply(T t) виконує трансформацію даних, приймаючи вхідне значення та повертаючи результат. Це дозволяє створювати гнучкі функції для обробки даних різних типів.
Практичне застосування
Припустимо, у вас є список імен користувачів, і потрібно обчислити довжину кожного імені для подальшого аналізу або обробки даних.
Main.java
1234567891011121314151617package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> users = Arrays.asList("Alice", "Bob", "Charlie", "David"); Function<String, Integer> nameLength = name -> name.length(); users.forEach(user -> { System.out.println(user + " has " + nameLength.apply(user) + " characters."); }); } }
У цьому прикладі наведено список імен користувачів. Для кожного імені використовується функція nameLength, яка обчислює кількість символів у імені за допомогою методу length(). За допомогою методу forEach здійснюється ітерація по кожному елементу списку та виводиться повідомлення із зазначенням, скільки символів містить кожне ім’я.
Комбінування функцій
Інтерфейс Function надає кілька методів для комбінування функцій, що дозволяє створювати ланцюжки операцій.
Метод andThen()
Метод andThen() дозволяє комбінувати дві функції, спочатку застосовуючи одну функцію, а потім передаючи результат другій функції. Це корисно, коли потрібно виконати декілька операцій послідовно.
Приклад
Є список імен користувачів, і потрібно зробити великою першу літеру кожного імені, а потім перевірити, чи містить ім'я більше ніж 5 символів.
Main.java
1234567891011121314151617181920212223package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("john", "alice", "bob", "charlie", "david"); // Capitalize first letter Function<String, String> capitalizeFirstLetter = name -> name.substring(0, 1).toUpperCase() + name.substring(1); // Check if the username has more than 5 characters Function<String, Boolean> isLongerThanFive = name -> name.length() > 5; // Combine functions using `andThen()` Function<String, Boolean> formattedNameThenCheckLength = capitalizeFirstLetter.andThen(isLongerThanFive); usernames.forEach(user -> { System.out.println(user + " -> " + formattedNameThenCheckLength.apply(user)); }); } }
Спочатку змінюється на велику перша літера кожного імені користувача за допомогою capitalizeFirstLetter. Далі перевіряється, чи має відформатоване ім'я більше ніж 5 символів за допомогою isLongerThanFive. Обидві функції поєднуються через andThen() для послідовної обробки.
Метод compose()
Метод compose() дозволяє комбінувати функції, але у зворотному порядку: спочатку застосовується друга функція, а результат передається у першу функцію.
Приклад
Є рядок, і потрібно спочатку обчислити його довжину, а потім додати префікс до результату.
Main.java
123456789101112131415161718package com.example; import java.util.function.Function; public class Main { public static void main(String[] args) { String phrase = "Hello World"; // First, calculate the length, then add a prefix Function<String, Integer> stringLength = String::length; Function<Integer, String> addPrefix = length -> "Length: " + length; // Combine functions using compose Function<String, String> lengthThenPrefix = addPrefix.compose(stringLength); System.out.println(lengthThenPrefix.apply(phrase)); // Output: Length: 11 } }
У цьому прикладі спочатку обчислюється довжина рядка за допомогою stringLength, а потім результат передається у функцію addPrefix, яка додає префікс. Ви використовуєте compose(), щоб застосувати функції у потрібному порядку.
Метод identity()
Метод identity() повертає функцію, яка просто повертає свій аргумент без жодних змін. Це корисно, коли потрібно передати функцію, яка не змінює вхідне значення, але потрібна для відповідності інтерфейсу.
Приклад
Уявіть, що потрібно обробити список імен користувачів, застосовуючи кілька перетворень: одне для перетворення імен у верхній регістр, інше для додавання суфікса "User", і третє — з використанням функції identity(), щоб залишити ім'я без змін. Завдання — застосувати ці функції до кожного імені у списку, зберігаючи інтерфейс програми незмінним для кожного перетворення.
Main.java
1234567891011121314151617181920212223242526272829303132package com.example; import java.util.List; import java.util.Arrays; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("alice", "bob", "charlie", "david", "eve"); // `Function` to convert the username to uppercase Function<String, String> uppercaseFunction = name -> name.toUpperCase(); // `Function` to add the "User" suffix Function<String, String> suffixFunction = name -> name + "User"; // Identity `Function`, which does nothing Function<String, String> identityFunction = Function.identity(); // Applying a combination of functions List<Function<String, ?>> transformations = Arrays.asList(uppercaseFunction, suffixFunction, identityFunction); // Applying each `Function` from the list for (Function<String, ?> transformation : transformations) { System.out.println("--------------------"); usernames.stream() .map(name -> transformation.apply(name)) .forEach(System.out::println); } } }
Як видно, вивід складається з трьох відформатованих списків імен користувачів. Останній список містить оригінальні імена, і саме тут стає у пригоді метод identity(), оскільки він дозволяє повертати імена без додаткової логіки для обробки незмінних значень. Це робить код чистішим і більш ефективним завдяки прямому використанню identity(), коли трансформація не потрібна.
1. Що робить метод andThen() у інтерфейсі Function?
2. Яким буде результат застосування методу identity()?
3. Що виконує метод compose()?
Дякуємо за ваш відгук!