Repository: CorporationX/god_bless
Pull request #19399: Kashkademan bjs2 71888 Gmail Rich Filters.
Author: login: kashkademan
Created: 2025-04-17T11:30:53Z | Merged: 2025-04-17T14:27:45Z

Kashkademan bjs2 71888 Gmail Rich Filters.


Diff:
diff --git a/.gitignore b/.gitignore
index 2216c8b1639..6b70889768e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,4 +55,7 @@ out/
 ### VS Code ###
 .vscode/
 README
-README.md
\ No newline at end of file
+README.md
+
+### IDX Google ###
+.idx/
\ No newline at end of file
diff --git a/src/main/java/school/faang/bjs2_71888/Email.java b/src/main/java/school/faang/bjs2_71888/Email.java
new file mode 100644
index 00000000000..51df53d4007
--- /dev/null
+++ b/src/main/java/school/faang/bjs2_71888/Email.java
@@ -0,0 +1,16 @@
+package school.faang.bjs2_71888;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@Setter
+@Getter
+@AllArgsConstructor
+@ToString
+public class Email {
+    private String subject;
+    private String body;
+    private boolean isImportant;
+}
diff --git a/src/main/java/school/faang/bjs2_71888/EmailProcessor.java b/src/main/java/school/faang/bjs2_71888/EmailProcessor.java
new file mode 100644
index 00000000000..b9e87389a2e
--- /dev/null
+++ b/src/main/java/school/faang/bjs2_71888/EmailProcessor.java
@@ -0,0 +1,20 @@
+package school.faang.bjs2_71888;
+
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class EmailProcessor {
+    public List<Email> filter(
+        List<Email> emails, 
+        Predicate<Email> isImportant, 
+        Consumer<Email> action, 
+        Function<Email, Email> modifyEmail) {        
+        return emails.stream()
+            .filter(isImportant)
+            .map(modifyEmail)
+            .peek(action)
+            .toList();        
+    }
+}
diff --git a/src/main/java/school/faang/bjs2_71888/Main.java b/src/main/java/school/faang/bjs2_71888/Main.java
new file mode 100644
index 00000000000..f78d291cbf3
--- /dev/null
+++ b/src/main/java/school/faang/bjs2_71888/Main.java
@@ -0,0 +1,31 @@
+package school.faang.bjs2_71888;
+
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class Main {
+    private static final EmailProcessor EMAIL_PROCESSOR = new EmailProcessor();
+    private static final List<Email> EMAILS = List.of(
+        new Email("Important Email", "This is an important email.", true),
+        new Email("Important Email", "Some email text.", true),
+        new Email("Important Email", "Other email sent to us.", true),
+        new Email("Normal Email", "This is a normal email.", false),
+        new Email("Normal Email", "Nothing to say.", false)
+    );
+    private static final Predicate<Email> IS_IMPORTANT = email -> !email.isImportant();
+    private static final Consumer<Email> PRINT_EMAILS = email -> log.info(email.toString());
+    private static final Function<Email, Email> MODIFY_EMAIL = email -> new Email(
+        email.getSubject(), 
+        email.getBody().toUpperCase(), 
+        email.isImportant()
+    );
+
+    public static void main(String[] args) {
+        EMAIL_PROCESSOR.filter(EMAILS, IS_IMPORTANT, PRINT_EMAILS, MODIFY_EMAIL);
+    }
+}


Reviews:
user: login: iBerbasov
state: CHANGES_REQUESTED
author_association: NONE
submitted_at: 2025-04-17T12:32:18Z
user: login: kashkademan
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-17T12:45:05Z
user: login: kashkademan
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-17T13:04:27Z
user: login: iBerbasov
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-17T14:13:05Z
user: login: iBerbasov
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-17T14:25:40Z

Review comments:
diff_hunk: @@ -0,0 +1,28 @@
+package school.faang.bjs2_71888;
+
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class Main {
+    private static final EmailProcessor EMAIL_PROCESSOR = new EmailProcessor();
+    private static final List<Email> EMAILS = List.of(
+        new Email("Important Email", "This is an important email.", true),
+        new Email("Important Email", "Some email text.", true),
+        new Email("Important Email", "Other email sent to us.", true),
+        new Email("Normal Email", "This is a normal email.", false),
+        new Email("Normal Email", "Nothing to say.", false)
+    );
+    // private static final Predicate<Email> IS_IMPORTANT = Email::isImportant;
path: src/main/java/school/faang/bjs2_71888/Main.java
user: login: iBerbasov
body: А чего отказался от ссылки на метод? Хороший способ и более читабельный
В любом случае обычная лямбда так же работает, но закомментированный код оставлять не надо, его следует удалять.
created_at: 2025-04-17T12:18:55Z
author_association: NONE
diff_hunk: @@ -0,0 +1,33 @@
+package school.faang.bjs2_71888;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class EmailProcessor {
+    public List<Email> processEmails(
+        List<Email> emails, 
+        Predicate<Email> isImportant, 
path: src/main/java/school/faang/bjs2_71888/EmailProcessor.java
user: login: iBerbasov
body: Тут лучше дать имя вроде filter 
Ведь мы используем лямбды, чтобы можно было применять разное поведение. А это имя привязывает нас только к одному конкретному полю
created_at: 2025-04-17T12:21:44Z
author_association: NONE
diff_hunk: @@ -0,0 +1,33 @@
+package school.faang.bjs2_71888;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class EmailProcessor {
+    public List<Email> processEmails(
+        List<Email> emails, 
+        Predicate<Email> isImportant, 
+        Consumer<Email> action, 
+        Function<Email, String> modifyEmailFunction) {
path: src/main/java/school/faang/bjs2_71888/EmailProcessor.java
user: login: iBerbasov
body: Субъективно, но такие постфиксы можно и опускать. Отношение к Function закреплено уже в типе аргумента.
Но это на вкус и цвет..
created_at: 2025-04-17T12:25:35Z
author_association: NONE
diff_hunk: @@ -0,0 +1,33 @@
+package school.faang.bjs2_71888;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class EmailProcessor {
+    public List<Email> processEmails(
+        List<Email> emails, 
+        Predicate<Email> isImportant, 
+        Consumer<Email> action, 
+        Function<Email, String> modifyEmailFunction) {
+        List<Email> filteredEmails = new ArrayList<>();
+        
+        for (Email email : emails) {
path: src/main/java/school/faang/bjs2_71888/EmailProcessor.java
user: login: iBerbasov
body: Мне кажется три цикла тут избыточны, можно все действия и за один проход по emails провернуть

Как второй вариант - со Stream API, на мой взгляд выглядит вообще чудесно
```
return emails.stream()
           .filter(isImportant)
           .map(modifyEmailFunction)
           .peek(action)
           .toList();
```
Только по примеру выше 2 нюанса: 

- для конкретно этого стрима нужно будет отклониться от примера и немного изменить modifyEmailFunction
- метод peek() стоит использовать с осторожностью, т.к. при некоторых условиях оптимизатор может самостоятельно решить не исполнять этот код [peek()](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#peek-java.util.function.Consumer-)
created_at: 2025-04-17T12:30:54Z
author_association: NONE
diff_hunk: @@ -0,0 +1,28 @@
+package school.faang.bjs2_71888;
+
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class Main {
+    private static final EmailProcessor EMAIL_PROCESSOR = new EmailProcessor();
+    private static final List<Email> EMAILS = List.of(
+        new Email("Important Email", "This is an important email.", true),
+        new Email("Important Email", "Some email text.", true),
+        new Email("Important Email", "Other email sent to us.", true),
+        new Email("Normal Email", "This is a normal email.", false),
+        new Email("Normal Email", "Nothing to say.", false)
+    );
+    // private static final Predicate<Email> IS_IMPORTANT = Email::isImportant;
path: src/main/java/school/faang/bjs2_71888/Main.java
user: login: kashkademan
body: Да, забыл убрать коммент. Это мне подставил ide но я до конца не разобрался еще как работает такая запись. Закомментил чтоб потом разобраться.
И еще не нашел как через такую запись отфильтровать например неважные письма? как сделал в следующей строке.
created_at: 2025-04-17T12:45:05Z
author_association: NONE
diff_hunk: @@ -0,0 +1,33 @@
+package school.faang.bjs2_71888;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class EmailProcessor {
+    public List<Email> processEmails(
+        List<Email> emails, 
+        Predicate<Email> isImportant, 
+        Consumer<Email> action, 
+        Function<Email, String> modifyEmailFunction) {
+        List<Email> filteredEmails = new ArrayList<>();
+        
+        for (Email email : emails) {
path: src/main/java/school/faang/bjs2_71888/EmailProcessor.java
user: login: kashkademan
body: Спасибо! про peek() почитаю.
Так правда выглядит проще меньше понятнее. Не подумал применить сразу stream().
Изменил.
created_at: 2025-04-17T13:04:27Z
author_association: NONE
diff_hunk: @@ -0,0 +1,33 @@
+package school.faang.bjs2_71888;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class EmailProcessor {
+    public List<Email> processEmails(
+        List<Email> emails, 
+        Predicate<Email> isImportant, 
path: src/main/java/school/faang/bjs2_71888/EmailProcessor.java
user: login: iBerbasov
body: Я имел ввиду имя предиката, а не метода. Метод назвался отлично :)
Гитхаб неудобно подсвечивает строку, которую комментируешь. Строка на которую я ссылаюсь - 12, а в интерфейсе она нижняя
created_at: 2025-04-17T14:13:05Z
author_association: NONE
diff_hunk: @@ -0,0 +1,28 @@
+package school.faang.bjs2_71888;
+
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class Main {
+    private static final EmailProcessor EMAIL_PROCESSOR = new EmailProcessor();
+    private static final List<Email> EMAILS = List.of(
+        new Email("Important Email", "This is an important email.", true),
+        new Email("Important Email", "Some email text.", true),
+        new Email("Important Email", "Other email sent to us.", true),
+        new Email("Normal Email", "This is a normal email.", false),
+        new Email("Normal Email", "Nothing to say.", false)
+    );
+    // private static final Predicate<Email> IS_IMPORTANT = Email::isImportant;
path: src/main/java/school/faang/bjs2_71888/Main.java
user: login: iBerbasov
body: Да собственно она работает ровно так же, как и следующая строка. Это просто укороченная запись

upd Я только проглядел знак ! , у тебя получается обрабатываются только НЕ важные письма ) поэтому да, ссылка на метод так не сможет

Если нужны именно НЕважные и хочется использовать ссылки на методы, можно сделать в классе Email отдельный метод isNotImportant. Он и более читабельный будет, чем `!`

А в остальном подобные ссылки часто используются в стримах
```
List<String> stringifiedNumbers = List.of("1", "2", "3");

List<Integer> ints = stringifiedNumbers.stream()       // стрим из строк
    .map(strNumber -> Integer.parseInt(strNumber)  //конвертим в Integer
    .toList();

List<Integer> ints = stringifiedNumbers.stream()       // стрим из строк
    .map(Integer::parseInt)  // так же конвертим, только другим синтаксисом. Для каждого элемента стрима вызывается Integer.valueOf
    .toList();
```
created_at: 2025-04-17T14:25:40Z
author_association: NONE

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-17T11:31:41Z
body: ⚠️ **ОШЫБКА**: Сборка завалилась: либо ошибки компиляции, либо не прошли тесты, либо возникли ошибки в стиле кода. Пожалуйста, проверь логи и внеси соответствующие изменения в ПР. После этого красная ошибка ниже должна пропасть, но этот комментарий останется - так и должно быть.
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-04-17T13:07:19Z
body: ⚠️ **ОШЫБКА**: Сборка завалилась: либо ошибки компиляции, либо не прошли тесты, либо возникли ошибки в стиле кода. Пожалуйста, проверь логи и внеси соответствующие изменения в ПР. После этого красная ошибка ниже должна пропасть, но этот комментарий останется - так и должно быть.
author_association: NONE