From 961de40080306d112a996c149a7038a5e9e1fe00 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Mon, 3 Mar 2025 17:32:00 +0200 Subject: [PATCH 01/15] a few methods in CrazyGenerics.java --- .../main/java/com/bobocode/basics/Box.java | 10 ++--- .../com/bobocode/basics/CrazyGenerics.java | 45 ++++++++++--------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/1-0-java-basics/1-3-0-hello-generics/src/main/java/com/bobocode/basics/Box.java b/1-0-java-basics/1-3-0-hello-generics/src/main/java/com/bobocode/basics/Box.java index 5a2d860ee..513fc821a 100644 --- a/1-0-java-basics/1-3-0-hello-generics/src/main/java/com/bobocode/basics/Box.java +++ b/1-0-java-basics/1-3-0-hello-generics/src/main/java/com/bobocode/basics/Box.java @@ -7,18 +7,18 @@ *

* todo: refactor this class so it uses generic type "T" and run {@link com.bobocode.basics.BoxTest} to verify it */ -public class Box { - private Object value; +public class Box { + private T value; - public Box(Object value) { + public Box(T value) { this.value = value; } - public Object getValue() { + public T getValue() { return value; } - public void setValue(Object value) { + public void setValue(T value) { this.value = value; } } diff --git a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java index 751d5899f..61c302350 100644 --- a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java +++ b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java @@ -33,8 +33,8 @@ public class CrazyGenerics { * @param – value type */ @Data - public static class Sourced { // todo: refactor class to introduce type parameter and make value generic - private Object value; + public static class Sourced { // todo: refactor class to introduce type parameter and make value generic + private T value; private String source; } @@ -45,11 +45,11 @@ public static class Sourced { // todo: refactor class to introduce type paramete * @param – actual, min and max type */ @Data - public static class Limited { + public static class Limited { // todo: refactor class to introduce type param bounded by number and make fields generic numbers - private final Object actual; - private final Object min; - private final Object max; + private final T actual; + private final T min; + private final T max; } /** @@ -59,7 +59,8 @@ public static class Limited { * @param – source object type * @param - converted result type */ - public interface Converter { // todo: introduce type parameters + public interface Converter { // todo: introduce type parameters + R convert (T object); // todo: add convert method } @@ -70,10 +71,10 @@ public interface Converter { // todo: introduce type parameters * * @param – value type */ - public static class MaxHolder { // todo: refactor class to make it generic - private Object max; + public static class MaxHolder > { // todo: refactor class to make it generic + private T max; - public MaxHolder(Object max) { + public MaxHolder(T max) { this.max = max; } @@ -82,11 +83,13 @@ public MaxHolder(Object max) { * * @param val a new value */ - public void put(Object val) { - throw new ExerciseNotCompletedException(); // todo: update parameter and implement the method + public void put(T val) { + if (val.compareTo(max) > 0) { + max = val; + } // todo: update parameter and implement the method } - public Object getMax() { + public T getMax() { return max; } } @@ -97,8 +100,8 @@ public Object getMax() { * * @param – the type of objects that can be processed */ - interface StrictProcessor { // todo: make it generic - void process(Object obj); + interface StrictProcessor { // todo: make it generic + void process(T obj); } /** @@ -108,10 +111,10 @@ interface StrictProcessor { // todo: make it generic * @param – a type of the entity that should be a subclass of {@link BaseEntity} * @param – a type of any collection */ - interface CollectionRepository { // todo: update interface according to the javadoc - void save(Object entity); + interface CollectionRepository { // todo: update interface according to the javadoc + void save(T entity); - Collection getEntityCollection(); + Collection getEntityCollection(); } /** @@ -120,7 +123,7 @@ interface CollectionRepository { // todo: update interface according to the java * * @param – a type of the entity that should be a subclass of {@link BaseEntity} */ - interface ListRepository { // todo: update interface according to the javadoc + interface ListRepository extends CollectionRepository { // todo: update interface according to the javadoc } /** @@ -133,7 +136,9 @@ interface ListRepository { // todo: update interface according to the javadoc * * @param a type of collection elements */ - interface ComparableCollection { // todo: refactor it to make generic and provide a default impl of compareTo + interface ComparableCollection extends Collection, Comparable { + @Override + int compareTo(Object o); // todo: refactor it to make generic and provide a default impl of compareTo } /** From c8c6bb6223c0836b55f73bf16a07ffa3e0f5db0e Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Thu, 6 Mar 2025 00:32:32 +0200 Subject: [PATCH 02/15] a few methods in CrazyGenerics.java --- .../com/bobocode/basics/CrazyGenerics.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java index 61c302350..9185813b4 100644 --- a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java +++ b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java @@ -9,6 +9,7 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.function.Predicate; /** * {@link CrazyGenerics} is an exercise class. It consists of classes, interfaces and methods that should be updated @@ -111,10 +112,10 @@ interface StrictProcessor { // todo: make i * @param – a type of the entity that should be a subclass of {@link BaseEntity} * @param – a type of any collection */ - interface CollectionRepository { // todo: update interface according to the javadoc + interface CollectionRepository > { // todo: update interface according to the javadoc void save(T entity); - Collection getEntityCollection(); + C getEntityCollection(); } /** @@ -136,9 +137,9 @@ interface ListRepository extends CollectionRepository { / * * @param a type of collection elements */ - interface ComparableCollection extends Collection, Comparable { + interface ComparableCollection extends Comparable, Collection { @Override - int compareTo(Object o); // todo: refactor it to make generic and provide a default impl of compareTo + int compareTo(E o); // todo: refactor it to make generic and provide a default impl of compareTo } /** @@ -152,7 +153,7 @@ static class CollectionUtil { * * @param list */ - public static void print(List list) { + public static void print(List list) { // todo: refactor it so the list of any type can be printed, not only integers list.forEach(element -> System.out.println(" – " + element)); } @@ -165,8 +166,9 @@ public static void print(List list) { * @param entities provided collection of entities * @return true if at least one of the elements has null id */ - public static boolean hasNewEntities(Collection entities) { - throw new ExerciseNotCompletedException(); // todo: refactor parameter and implement method + public static boolean hasNewEntities(Collection entities) { + return entities.stream() + .anyMatch(element -> element.getUuid() == null); // todo: refactor parameter and implement method } /** @@ -178,8 +180,10 @@ public static boolean hasNewEntities(Collection entities) { * @param validationPredicate criteria for validation * @return true if all entities fit validation criteria */ - public static boolean isValidCollection() { - throw new ExerciseNotCompletedException(); // todo: add method parameters and implement the logic + public static boolean isValidCollection(Collection entities, + Predicate validationPredicate) { + return entities.stream() + .allMatch(validationPredicate); // todo: add method parameters and implement the logic } /** @@ -192,8 +196,11 @@ public static boolean isValidCollection() { * @param entity type * @return true if entities list contains target entity more than once */ - public static boolean hasDuplicates() { - throw new ExerciseNotCompletedException(); // todo: update method signature and implement it + public static boolean hasDuplicates (Collection entities, + T targetEntity) { + return entities + .stream() + .anyMatch(element -> element.getUuid().equals(targetEntity)); } /** From 2082b7d521d5083d41ec9c97441096b2a5a27306 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Mon, 10 Mar 2025 15:33:33 +0200 Subject: [PATCH 03/15] crazy generics --- .../main/java/com/bobocode/basics/CrazyGenerics.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java index 9185813b4..234f315fb 100644 --- a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java +++ b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java @@ -101,7 +101,7 @@ public T getMax() { * * @param – the type of objects that can be processed */ - interface StrictProcessor { // todo: make it generic + interface StrictProcessor > { // todo: make it generic void process(T obj); } @@ -124,7 +124,7 @@ interface CollectionRepository > { * * @param – a type of the entity that should be a subclass of {@link BaseEntity} */ - interface ListRepository extends CollectionRepository { // todo: update interface according to the javadoc + interface ListRepository extends CollectionRepository> { // todo: update interface according to the javadoc } /** @@ -137,7 +137,7 @@ interface ListRepository extends CollectionRepository { / * * @param a type of collection elements */ - interface ComparableCollection extends Comparable, Collection { + interface ComparableCollection > extends Comparable, Collection { @Override int compareTo(E o); // todo: refactor it to make generic and provide a default impl of compareTo } @@ -196,11 +196,12 @@ public static boolean isValidCollection(Collection entitie * @param entity type * @return true if entities list contains target entity more than once */ - public static boolean hasDuplicates (Collection entities, + public static boolean hasDuplicates ( + Collection entities, T targetEntity) { return entities .stream() - .anyMatch(element -> element.getUuid().equals(targetEntity)); + .anyMatch(element -> element.getUuid().equals(targetEntity.getUuid())); } /** From a760f92e2b9839379b19594db1bf08fcb542b142 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Mon, 10 Mar 2025 20:14:53 +0200 Subject: [PATCH 04/15] crazy generics done + have changed jdk version to 21 --- .../com/bobocode/basics/CrazyGenerics.java | 62 ++++++++++--------- .../com/bobocode/basics/util/BaseEntity.java | 9 ++- pom.xml | 1 + 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java index 234f315fb..15a23fa43 100644 --- a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java +++ b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java @@ -1,27 +1,22 @@ package com.bobocode.basics; import com.bobocode.basics.util.BaseEntity; -import com.bobocode.util.ExerciseNotCompletedException; import lombok.Data; - import java.io.Serializable; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.function.Predicate; +import java.util.stream.StreamSupport; /** * {@link CrazyGenerics} is an exercise class. It consists of classes, interfaces and methods that should be updated * using generics. *

- * TODO: go step by step from top to bottom. Read the java doc, write code and run CrazyGenericsTest to verify your impl *

* Hint: in some cases you will need to refactor the code, like replace {@link Object} with a generic type. In order * cases you will need to add new fields, create new classes, or add new methods. Always try to read java doc and update * the code according to it. *

- * TODO: to get the most out of your learning, visit our website + * *

* * @author Taras Boychuk @@ -34,7 +29,7 @@ public class CrazyGenerics { * @param – value type */ @Data - public static class Sourced { // todo: refactor class to introduce type parameter and make value generic + public static class Sourced { private T value; private String source; } @@ -47,7 +42,6 @@ public static class Sourced { // todo: refactor class to introduce type para */ @Data public static class Limited { - // todo: refactor class to introduce type param bounded by number and make fields generic numbers private final T actual; private final T min; private final T max; @@ -60,9 +54,8 @@ public static class Limited { * @param – source object type * @param - converted result type */ - public interface Converter { // todo: introduce type parameters + public interface Converter { R convert (T object); - // todo: add convert method } /** @@ -72,7 +65,7 @@ public interface Converter { // todo: introduce type parameters * * @param – value type */ - public static class MaxHolder > { // todo: refactor class to make it generic + public static class MaxHolder > { private T max; public MaxHolder(T max) { @@ -87,7 +80,7 @@ public MaxHolder(T max) { public void put(T val) { if (val.compareTo(max) > 0) { max = val; - } // todo: update parameter and implement the method + } } public T getMax() { @@ -101,7 +94,7 @@ public T getMax() { * * @param – the type of objects that can be processed */ - interface StrictProcessor > { // todo: make it generic + interface StrictProcessor > { void process(T obj); } @@ -112,7 +105,7 @@ interface StrictProcessor > { // * @param – a type of the entity that should be a subclass of {@link BaseEntity} * @param – a type of any collection */ - interface CollectionRepository > { // todo: update interface according to the javadoc + interface CollectionRepository > { void save(T entity); C getEntityCollection(); @@ -124,7 +117,7 @@ interface CollectionRepository > { * * @param – a type of the entity that should be a subclass of {@link BaseEntity} */ - interface ListRepository extends CollectionRepository> { // todo: update interface according to the javadoc + interface ListRepository extends CollectionRepository> { } /** @@ -137,9 +130,11 @@ interface ListRepository extends CollectionRepository a type of collection elements */ - interface ComparableCollection > extends Comparable, Collection { + interface ComparableCollection extends Collection, Comparable> { @Override - int compareTo(E o); // todo: refactor it to make generic and provide a default impl of compareTo + default int compareTo(Collection o) { + return Integer.compare(this.size(), o.size()); + } } /** @@ -154,7 +149,6 @@ static class CollectionUtil { * @param list */ public static void print(List list) { - // todo: refactor it so the list of any type can be printed, not only integers list.forEach(element -> System.out.println(" – " + element)); } @@ -168,7 +162,7 @@ public static void print(List list) { */ public static boolean hasNewEntities(Collection entities) { return entities.stream() - .anyMatch(element -> element.getUuid() == null); // todo: refactor parameter and implement method + .anyMatch(element -> element.getUuid() == null); } /** @@ -183,7 +177,7 @@ public static boolean hasNewEntities(Collection entities) public static boolean isValidCollection(Collection entities, Predicate validationPredicate) { return entities.stream() - .allMatch(validationPredicate); // todo: add method parameters and implement the logic + .allMatch(validationPredicate); } /** @@ -201,7 +195,8 @@ public static boolean hasDuplicates ( T targetEntity) { return entities .stream() - .anyMatch(element -> element.getUuid().equals(targetEntity.getUuid())); + .filter(element -> element.getUuid().equals(targetEntity.getUuid())) + .count() > 1; } /** @@ -213,7 +208,10 @@ public static boolean hasDuplicates ( * @param type of elements * @return optional max value */ - // todo: create a method and implement its logic manually without using util method from JDK + public static Optional findMax(Iterable elements, Comparator comparator) { + return StreamSupport.stream(elements.spliterator(), false) + .max(comparator); + } /** * findMostRecentlyCreatedEntity is a generic util method that accepts a collection of entities and returns the @@ -227,7 +225,11 @@ public static boolean hasDuplicates ( * @param entity type * @return an entity from the given collection that has the max createdOn value */ - // todo: create a method according to JavaDoc and implement it using previous method + + public static T findMostRecentlyCreatedEntity(Collection entities) { + return findMax(entities, Comparator.comparing(BaseEntity::getCreatedOn)) + .orElseThrow(() -> new NoSuchElementException("No present value")); + } /** * An util method that allows to swap two elements of any list. It changes the list so the element with the index @@ -239,9 +241,13 @@ public static boolean hasDuplicates ( * @param j index of the other element to swap */ public static void swap(List elements, int i, int j) { - Objects.checkIndex(i, elements.size()); - Objects.checkIndex(j, elements.size()); - throw new ExerciseNotCompletedException(); // todo: complete method implementation + swapElements(elements, i, j); + } + + private static void swapElements(List elements, int i, int j) { + T temp = elements.get(j); + elements.set(j, elements.get(i)); + elements.set(i, temp); } } diff --git a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/util/BaseEntity.java b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/util/BaseEntity.java index f961ab7a5..6d2804f24 100644 --- a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/util/BaseEntity.java +++ b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/util/BaseEntity.java @@ -3,7 +3,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; - import java.time.LocalDateTime; import java.util.UUID; @@ -18,4 +17,12 @@ public BaseEntity(UUID uuid) { this.uuid = uuid; this.createdOn = LocalDateTime.now(); } + + public UUID getUuid() { + return uuid; + } + + public LocalDateTime getCreatedOn() { + return createdOn; + } } diff --git a/pom.xml b/pom.xml index 2b4e227d8..561e5129f 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,7 @@ org.projectlombok lombok + provided 1.18.30 From d8b5d5181616ea82b5d5b899d75cd98457ef6de7 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Mon, 10 Mar 2025 21:29:32 +0200 Subject: [PATCH 05/15] fix some methods --- .../src/main/java/com/bobocode/basics/CrazyGenerics.java | 4 ++-- .../java/com/bobocode/basics/HeterogeneousMaxHolder.java | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java index 15a23fa43..b2aadaf8b 100644 --- a/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java +++ b/1-0-java-basics/1-3-1-crazy-generics/src/main/java/com/bobocode/basics/CrazyGenerics.java @@ -208,7 +208,7 @@ public static boolean hasDuplicates ( * @param type of elements * @return optional max value */ - public static Optional findMax(Iterable elements, Comparator comparator) { + public static Optional findMax(Iterable elements, Comparator comparator) { return StreamSupport.stream(elements.spliterator(), false) .max(comparator); } @@ -227,7 +227,7 @@ public static Optional findMax(Iterable elements, C */ public static T findMostRecentlyCreatedEntity(Collection entities) { - return findMax(entities, Comparator.comparing(BaseEntity::getCreatedOn)) + return findMax(entities, CREATED_ON_COMPARATOR) .orElseThrow(() -> new NoSuchElementException("No present value")); } diff --git a/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java b/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java index 9ef839910..6b4b16e64 100644 --- a/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java +++ b/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java @@ -9,7 +9,7 @@ * It's based on the {@link Map} and provides an API that allows to put a value by type, and get a max value by type. *

*

- * TODO: to get the most out of your learning, visit our website + * *

* * @author Taras Boychuk @@ -17,7 +17,8 @@ public class HeterogeneousMaxHolder { /** - * A method put stores a provided value by its type, if the value is greater than the current maximum. In other words, the logic + * A method put stores a provided value by its type, if the value is greater than the current maximum. In other words, + * the logic * of this method makes sure that only max value is stored and everything else is ignored. *

* If the current max value is less than a provided one, or if it's null, then a provided value gets stored and the old From 74a80fbbeca4f2d448de53eec7abd90df52fe06e Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Thu, 13 Mar 2025 13:54:10 +0200 Subject: [PATCH 06/15] annotation exercise --- .../main/java/com/bobocode/basics/Exercise.java | 14 ++++++++++++++ .../bobocode/basics/HelloAnnotationsExercise.java | 1 + 2 files changed, 15 insertions(+) create mode 100644 1-0-java-basics/1-5-0-hello-annotations/src/main/java/com/bobocode/basics/Exercise.java diff --git a/1-0-java-basics/1-5-0-hello-annotations/src/main/java/com/bobocode/basics/Exercise.java b/1-0-java-basics/1-5-0-hello-annotations/src/main/java/com/bobocode/basics/Exercise.java new file mode 100644 index 000000000..70066cbff --- /dev/null +++ b/1-0-java-basics/1-5-0-hello-annotations/src/main/java/com/bobocode/basics/Exercise.java @@ -0,0 +1,14 @@ +package com.bobocode.basics; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Exercise { + String value(); + + Level complexityLevel() default Level.BASIC; +} diff --git a/1-0-java-basics/1-5-0-hello-annotations/src/main/java/com/bobocode/basics/HelloAnnotationsExercise.java b/1-0-java-basics/1-5-0-hello-annotations/src/main/java/com/bobocode/basics/HelloAnnotationsExercise.java index 4dc8c4b22..288eda513 100644 --- a/1-0-java-basics/1-5-0-hello-annotations/src/main/java/com/bobocode/basics/HelloAnnotationsExercise.java +++ b/1-0-java-basics/1-5-0-hello-annotations/src/main/java/com/bobocode/basics/HelloAnnotationsExercise.java @@ -13,5 +13,6 @@ * * @author Taras Boychuk */ +@Exercise(value = "hello-annotation-basic") public class HelloAnnotationsExercise { // todo: mark class with the annotation according to the javadoc } From cfef5e8c8a5d38d76ce45c6863908848b7a214e3 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Thu, 13 Mar 2025 17:16:05 +0200 Subject: [PATCH 07/15] HeterogeneousMaxHolder.java --- .../bobocode/basics/HeterogeneousMaxHolder.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java b/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java index 6b4b16e64..42b00db14 100644 --- a/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java +++ b/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java @@ -1,5 +1,7 @@ package com.bobocode.basics; +import java.util.Comparator; +import java.util.HashMap; import java.util.Map; /** @@ -15,10 +17,10 @@ * @author Taras Boychuk */ public class HeterogeneousMaxHolder { - + private Map, Object> maxHolderMap = new HashMap<>(); /** - * A method put stores a provided value by its type, if the value is greater than the current maximum. In other words, - * the logic + * A method put stores a provided value by its type, if the value is greater than the current maximum. + * In other words, the logic * of this method makes sure that only max value is stored and everything else is ignored. *

* If the current max value is less than a provided one, or if it's null, then a provided value gets stored and the old @@ -31,8 +33,14 @@ public class HeterogeneousMaxHolder { * @param value type parameter * @return a smaller value among the provided value and the current maximum */ - // todo: implement a method according to javadoc + public > void put(Class key, + T value) { + T currentMax = key.cast(maxHolderMap.get(key)); + if (maxHolderMap.get(key) == null ) { + maxHolderMap.put(key, value); + } + } /** * An overloaded method put implements the same logic using a custom comparator. A given comparator is wrapped with * a null-safe comparator, considering null smaller than any non-null object. From dc2ee90c8bc3ed293ba9181fd95ba146633ea511 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Thu, 13 Mar 2025 19:33:13 +0200 Subject: [PATCH 08/15] Max Holder --- .../basics/HeterogeneousMaxHolder.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java b/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java index 42b00db14..2a1c315f7 100644 --- a/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java +++ b/1-0-java-basics/1-3-2-heterogeneous-max-holder/src/main/java/com/bobocode/basics/HeterogeneousMaxHolder.java @@ -18,6 +18,7 @@ */ public class HeterogeneousMaxHolder { private Map, Object> maxHolderMap = new HashMap<>(); + /** * A method put stores a provided value by its type, if the value is greater than the current maximum. * In other words, the logic @@ -33,14 +34,11 @@ public class HeterogeneousMaxHolder { * @param value type parameter * @return a smaller value among the provided value and the current maximum */ - public > void put(Class key, - T value) { - T currentMax = key.cast(maxHolderMap.get(key)); - if (maxHolderMap.get(key) == null ) { - maxHolderMap.put(key, value); - } - + public > T put(Class key, + T value) { + return put(key, value, Comparator.naturalOrder()); } + /** * An overloaded method put implements the same logic using a custom comparator. A given comparator is wrapped with * a null-safe comparator, considering null smaller than any non-null object. @@ -53,7 +51,17 @@ public > void put(Class key, * @param value type parameter * @return a smaller value among the provided value and the current maximum */ - // todo: implement a method according to javadoc + public T put(Class key, + T value, + Comparator comparator) { + comparator = Comparator.nullsFirst(comparator); + T currentMax = key.cast(maxHolderMap.get(key)); + if (comparator.compare(currentMax, value) < 0) { + maxHolderMap.put(key, value); + return currentMax; + } + return value; + } /** * A method getMax returns a max value by the given type. If no value is stored by this type, then it returns null. @@ -62,5 +70,8 @@ public > void put(Class key, * @param value type parameter * @return current max value or null */ - // todo: implement a method according to javadoc + public T getMax(Class key) { + T currentMax = key.cast(maxHolderMap.get(key)); + return currentMax; + } } From a5ddfa2f3044f77450fbb3731a965bca29ed3159 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Tue, 25 Mar 2025 20:09:31 +0200 Subject: [PATCH 09/15] FileReaders.java --- .../java/com/bobocode/se/FileReaders.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/3-0-java-core/3-6-1-file-reader/src/main/java/com/bobocode/se/FileReaders.java b/3-0-java-core/3-6-1-file-reader/src/main/java/com/bobocode/se/FileReaders.java index 6370a3638..56ddf6c56 100644 --- a/3-0-java-core/3-6-1-file-reader/src/main/java/com/bobocode/se/FileReaders.java +++ b/3-0-java-core/3-6-1-file-reader/src/main/java/com/bobocode/se/FileReaders.java @@ -1,6 +1,12 @@ package com.bobocode.se; -import com.bobocode.util.ExerciseNotCompletedException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.stream.Collectors; /** * {@link FileReaders} provides an API that allow to read whole file into a {@link String} by file name. @@ -14,6 +20,21 @@ public class FileReaders { * @return string that holds whole file content */ public static String readWholeFile(String fileName) { - throw new ExerciseNotCompletedException(); //todo + try { + URI resource = getResource(fileName); + return Files.lines(Paths.get(resource)) + .collect(Collectors.joining("\n")); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static URI getResource(String fileName) { + URL resource = FileReaders.class.getClassLoader().getResource(fileName); + try { + return resource.toURI(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } } } From dd0fd0ce7ddbe26c9c3b536559799c379ca4fb4f Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Tue, 25 Mar 2025 20:44:12 +0200 Subject: [PATCH 10/15] FileReaders refactor --- .../src/main/java/com/bobocode/se/FileReaders.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/3-0-java-core/3-6-1-file-reader/src/main/java/com/bobocode/se/FileReaders.java b/3-0-java-core/3-6-1-file-reader/src/main/java/com/bobocode/se/FileReaders.java index 56ddf6c56..1a14ac8d1 100644 --- a/3-0-java-core/3-6-1-file-reader/src/main/java/com/bobocode/se/FileReaders.java +++ b/3-0-java-core/3-6-1-file-reader/src/main/java/com/bobocode/se/FileReaders.java @@ -5,13 +5,16 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * {@link FileReaders} provides an API that allow to read whole file into a {@link String} by file name. */ public class FileReaders { + private static final String DELIMITER = "\n"; /** * Returns a {@link String} that contains whole text from the file specified by name. @@ -22,16 +25,17 @@ public class FileReaders { public static String readWholeFile(String fileName) { try { URI resource = getResource(fileName); - return Files.lines(Paths.get(resource)) - .collect(Collectors.joining("\n")); + try (Stream lines = Files.lines(Paths.get(resource))) { + return lines.collect(Collectors.joining(DELIMITER)); + } } catch (IOException e) { - throw new RuntimeException(e); + throw new RuntimeException("Cannot read file: " + fileName, e); } } private static URI getResource(String fileName) { - URL resource = FileReaders.class.getClassLoader().getResource(fileName); try { + URL resource = FileReaders.class.getClassLoader().getResource(fileName); return resource.toURI(); } catch (URISyntaxException e) { throw new RuntimeException(e); From bed5c539a2bddf74a4ed984fd98bd46013761365 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Tue, 25 Mar 2025 23:54:03 +0200 Subject: [PATCH 11/15] FileStats.java solution --- .../main/java/com/bobocode/se/FileStats.java | 61 +++++++++++++++++-- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/3-0-java-core/3-6-2-file-stats/src/main/java/com/bobocode/se/FileStats.java b/3-0-java-core/3-6-2-file-stats/src/main/java/com/bobocode/se/FileStats.java index 56b4aa596..10937fb7a 100644 --- a/3-0-java-core/3-6-2-file-stats/src/main/java/com/bobocode/se/FileStats.java +++ b/3-0-java-core/3-6-2-file-stats/src/main/java/com/bobocode/se/FileStats.java @@ -1,12 +1,25 @@ package com.bobocode.se; -import com.bobocode.util.ExerciseNotCompletedException; +import lombok.SneakyThrows; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Comparator; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.groupingBy; /** * {@link FileStats} provides an API that allow to get character statistic based on text file. All whitespace characters * are ignored. */ public class FileStats { + private final Map characterCountMap; + private final char mostFrequentCharacter; + /** * Creates a new immutable {@link FileStats} objects using data from text file received as a parameter. * @@ -14,7 +27,15 @@ public class FileStats { * @return new FileStats object created from text file */ public static FileStats from(String fileName) { - throw new ExerciseNotCompletedException(); //todo + return new FileStats(fileName); + } + + private FileStats(String filename) { + Path path = findFile(filename); + Stream fileStream = openFileStream(path); + Stream characterStream = transformStringStreamToCharacterStream(fileStream); + characterCountMap = computeCharacterCountMap(characterStream); + mostFrequentCharacter = getMostPopularCharacter(); } /** @@ -24,7 +45,8 @@ public static FileStats from(String fileName) { * @return a number that shows how many times this character appeared in a text file */ public int getCharCount(char character) { - throw new ExerciseNotCompletedException(); //todo + return characterCountMap.get(character) + .intValue(); } /** @@ -33,7 +55,11 @@ public int getCharCount(char character) { * @return the most frequently appeared character */ public char getMostPopularCharacter() { - throw new ExerciseNotCompletedException(); //todo + return characterCountMap.entrySet() + .stream() + .max(Map.Entry.comparingByValue()) + .get() + .getKey(); } /** @@ -43,6 +69,31 @@ public char getMostPopularCharacter() { * @return {@code true} if this character has appeared in the text, and {@code false} otherwise */ public boolean containsCharacter(char character) { - throw new ExerciseNotCompletedException(); //todo + return characterCountMap.containsKey(character); + } + + private Path findFile(String fileName) { + try { + URL resource = FileStats.class.getClassLoader().getResource(fileName); + return Path.of(resource.toURI()); + } catch (Exception e) { + throw new FileStatsException("Cannot find resource: " + fileName); + } + } + + @SneakyThrows + private Stream openFileStream(Path path) { + return Files.lines(path); + } + + private Stream transformStringStreamToCharacterStream(Stream fileStream) { + return fileStream + .flatMap(line -> line.chars().mapToObj(c -> (char) c)); + } + + private Map computeCharacterCountMap(Stream characterStream) { + return characterStream + .filter(character -> character != 32) + .collect(groupingBy(Function.identity(), counting())); } } From bba4aaec8b957f854e59458c69a81b3a6a8f2b66 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Wed, 26 Mar 2025 17:31:07 +0200 Subject: [PATCH 12/15] oop solution --- .../main/java/com/bobocode/oop/data/FlightDao.java | 14 ++++++++------ .../bobocode/oop/factory/FlightServiceFactory.java | 6 ++---- .../com/bobocode/oop/service/FlightService.java | 13 +++++++++++-- .../java/com/bobocode/oop/service/Flights.java | 9 +++++++++ 4 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/Flights.java diff --git a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/data/FlightDao.java b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/data/FlightDao.java index 3e58c3b33..c559261e9 100644 --- a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/data/FlightDao.java +++ b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/data/FlightDao.java @@ -1,6 +1,6 @@ package com.bobocode.oop.data; -import com.bobocode.util.ExerciseNotCompletedException; +import com.bobocode.oop.service.Flights; import java.util.HashSet; import java.util.Set; @@ -9,10 +9,8 @@ * {@link FlightDao} represents a Data Access Object (DAO) for flights. The implementation is simplified, so it just * uses {@link HashSet} to store flight numbers. *

- * todo: 1. Implement a method {@link FlightDao#register(String)} that store new flight number into the set - * todo: 2. Implement a method {@link FlightDao#findAll()} that returns a set of all flight numbers */ -public class FlightDao { +public class FlightDao implements Flights { private Set flights = new HashSet<>(); /** @@ -21,8 +19,11 @@ public class FlightDao { * @param flightNumber a flight number to store * @return {@code true} if a flight number was stored, {@code false} otherwise */ + + + @Override public boolean register(String flightNumber) { - throw new ExerciseNotCompletedException();// todo: implement this method + return flights.add(flightNumber); } /** @@ -30,8 +31,9 @@ public boolean register(String flightNumber) { * * @return a set of flight numbers */ + @Override public Set findAll() { - throw new ExerciseNotCompletedException();// todo: implement this method + return flights; } } diff --git a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/factory/FlightServiceFactory.java b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/factory/FlightServiceFactory.java index 8cd2ed673..6a2ae74c3 100644 --- a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/factory/FlightServiceFactory.java +++ b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/factory/FlightServiceFactory.java @@ -1,21 +1,19 @@ package com.bobocode.oop.factory; +import com.bobocode.oop.data.FlightDao; import com.bobocode.oop.service.FlightService; -import com.bobocode.util.ExerciseNotCompletedException; /** * {@link FlightServiceFactory} is used to create an instance of {@link FlightService} *

- * todo: 1. Implement method {@link FlightServiceFactory#creteFlightService()} */ public class FlightServiceFactory { - /** * Create a new instance of {@link FlightService} * * @return FlightService */ public FlightService creteFlightService() { - throw new ExerciseNotCompletedException(); + return new FlightService(new FlightDao()); } } diff --git a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/FlightService.java b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/FlightService.java index b31cd8f07..fad792e47 100644 --- a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/FlightService.java +++ b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/FlightService.java @@ -1,8 +1,10 @@ package com.bobocode.oop.service; +import com.bobocode.oop.data.FlightDao; import com.bobocode.util.ExerciseNotCompletedException; import java.util.List; +import java.util.stream.Collectors; /** * {@link FlightService} provides an API that allows to manage flight numbers @@ -11,6 +13,11 @@ * todo: 2. Using {@link com.bobocode.oop.data.FlightDao} implement method {@link FlightService#searchFlights(String)} */ public class FlightService { + private final Flights flights; + + public FlightService(Flights flights) { + this.flights = flights; + } /** * Adds a new flight number @@ -19,7 +26,7 @@ public class FlightService { * @return {@code true} if a flight number was added, {@code false} otherwise */ public boolean registerFlight(String flightNumber) { - throw new ExerciseNotCompletedException(); + return flights.register(flightNumber); } /** @@ -29,6 +36,8 @@ public boolean registerFlight(String flightNumber) { * @return a list of found flight numbers */ public List searchFlights(String query) { - throw new ExerciseNotCompletedException(); + return flights.findAll().stream() + .filter(line -> line.contains(query)) + .collect(Collectors.toList()); } } diff --git a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/Flights.java b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/Flights.java new file mode 100644 index 000000000..724ba67c6 --- /dev/null +++ b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/Flights.java @@ -0,0 +1,9 @@ +package com.bobocode.oop.service; + +import java.util.Set; + +public interface Flights { + boolean register(String flight); + + Set findAll(); +} From f0bee2f610d2ab779f5fa22a334a3a100651f1d7 Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Wed, 26 Mar 2025 23:03:43 +0200 Subject: [PATCH 13/15] oop solution + crazy regex --- .../main/java/com/bobocode/se/FileStats.java | 1 - .../main/java/com/bobocode/se/CrazyRegex.java | 53 ++++++++++--------- .../bobocode/oop/service/FlightService.java | 3 +- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/3-0-java-core/3-6-2-file-stats/src/main/java/com/bobocode/se/FileStats.java b/3-0-java-core/3-6-2-file-stats/src/main/java/com/bobocode/se/FileStats.java index 10937fb7a..e79ed550a 100644 --- a/3-0-java-core/3-6-2-file-stats/src/main/java/com/bobocode/se/FileStats.java +++ b/3-0-java-core/3-6-2-file-stats/src/main/java/com/bobocode/se/FileStats.java @@ -4,7 +4,6 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Comparator; import java.util.Map; import java.util.function.Function; import java.util.stream.Stream; diff --git a/3-0-java-core/3-6-3-crazy-regex/src/main/java/com/bobocode/se/CrazyRegex.java b/3-0-java-core/3-6-3-crazy-regex/src/main/java/com/bobocode/se/CrazyRegex.java index e213d3f26..340fbd6f8 100644 --- a/3-0-java-core/3-6-3-crazy-regex/src/main/java/com/bobocode/se/CrazyRegex.java +++ b/3-0-java-core/3-6-3-crazy-regex/src/main/java/com/bobocode/se/CrazyRegex.java @@ -2,6 +2,7 @@ import com.bobocode.util.ExerciseNotCompletedException; +import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -21,7 +22,7 @@ public class CrazyRegex { * @return a pattern that looks for the word "Curiosity" */ public Pattern findSpecificWord() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("Curiosity"); } /** @@ -30,7 +31,7 @@ public Pattern findSpecificWord() { * @return a pattern that looks for the first word in text */ public Pattern findFirstWord() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("^\\w+"); } /** @@ -39,7 +40,7 @@ public Pattern findFirstWord() { * @return a pattern that looks for the last word in text */ public Pattern findLastWord() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\w+$"); } /** @@ -50,7 +51,7 @@ public Pattern findLastWord() { * @return a pattern that looks for numbers */ public Pattern findAllNumbers() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\d+"); } /** @@ -59,7 +60,7 @@ public Pattern findAllNumbers() { * @return a pattern that looks for dates */ public Pattern findDates() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\d{4}-\\d{2}-\\d{2}"); } /** @@ -69,7 +70,7 @@ public Pattern findDates() { * @return a pattern that looks for different variations of word "color" */ public Pattern findDifferentSpellingsOfColor() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("colo\\w+"); } /** @@ -80,7 +81,7 @@ public Pattern findDifferentSpellingsOfColor() { * @return a pattern that looks for zip codes */ public Pattern findZipCodes() { - throw new ExerciseNotCompletedException(); + return Pattern.compile(" \\d{5} "); } /** @@ -90,7 +91,7 @@ public Pattern findZipCodes() { * @return a pattern that looks for different variations of word "link" */ public Pattern findDifferentSpellingsOfLink() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("l[\\p{Punct}|\\s|\\w+]nk"); } /** @@ -100,7 +101,7 @@ public Pattern findDifferentSpellingsOfLink() { * @return a pattern that looks for phone numbers */ public Pattern findSimplePhoneNumber() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\d{3}-\\d{3}-\\d{4}"); } /** @@ -111,7 +112,7 @@ public Pattern findSimplePhoneNumber() { * @return a pattern that looks for numbers with length 3 and digits from 0 to 5 in the middle */ public Pattern findNumbersFromZeroToFiveWithLengthThree() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("[0-5]{3}"); } /** @@ -120,7 +121,7 @@ public Pattern findNumbersFromZeroToFiveWithLengthThree() { * @return a pattern that looks for the words that have length 5 */ public Pattern findAllWordsWithFiveLength() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\b\\p{Alpha}{5}\\b"); } /** @@ -131,7 +132,7 @@ public Pattern findAllWordsWithFiveLength() { * @return a pattern that looks for words and numbers that not shorter 2 and not longer 3 */ public Pattern findAllLettersAndDigitsWithLengthThree() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\b\\p{Alpha}{2,3}\\b|\\b\\p{Alnum}{2,3}\\b"); } /** @@ -140,7 +141,7 @@ public Pattern findAllLettersAndDigitsWithLengthThree() { * @return a pattern that looks for the words that begin with capital letter */ public Pattern findAllWordsWhichBeginWithCapitalLetter() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\b[A-Z][a-z]*\\b"); } /** @@ -150,7 +151,7 @@ public Pattern findAllWordsWhichBeginWithCapitalLetter() { * @return a pattern that looks for the abbreviations above */ public Pattern findAbbreviation() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\b\\p{Alpha}\\p{javaUpperCase}\\b"); } /** @@ -159,7 +160,7 @@ public Pattern findAbbreviation() { * @return a pattern that looks for all open braces */ public Pattern findAllOpenBraces() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\{+"); } /** @@ -168,7 +169,7 @@ public Pattern findAllOpenBraces() { * @return a pattern that looks for everything inside [] */ public Pattern findOnlyResources() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("(?<=\\[).*?(?=])"); } /** @@ -177,7 +178,7 @@ public Pattern findOnlyResources() { * @return a pattern that looks for all https links in note.txt */ public Pattern findOnlyLinksInNote() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("https://(www.)?+[a-z]+(.com)"); } /** @@ -186,7 +187,7 @@ public Pattern findOnlyLinksInNote() { * @return a pattern that looks for all http links in nasa.json */ public Pattern findOnlyLinksInJson() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("http://(.*)JPG"); } /** @@ -195,9 +196,8 @@ public Pattern findOnlyLinksInJson() { * @return a pattern that looks for all .com, .net and .edu emails */ public Pattern findAllEmails() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("[\\w.]+@[\\w]+\\.(com|net|edu)"); } - /** * A Pattern that finds the following examples of phone numbers: * - 555-555-5555 @@ -207,7 +207,7 @@ public Pattern findAllEmails() { * @return a pattern that looks for phone numbers patterns above */ public Pattern findAllPatternsForPhoneNumbers() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\(?\\d{3}[-.)]\\d{3}[-.)]\\d{4}"); } /** @@ -216,7 +216,7 @@ public Pattern findAllPatternsForPhoneNumbers() { * @return a pattern that looks for duplicates */ public Pattern findOnlyDuplicates() { - throw new ExerciseNotCompletedException(); + return Pattern.compile("\\b(\\w+)\\s\\1\\b"); } /** @@ -227,7 +227,8 @@ public Pattern findOnlyDuplicates() { * @return String where all names recorded as last name first name */ public String replaceFirstAndLastNames(String names) { - throw new ExerciseNotCompletedException(); + Matcher matcher = Pattern.compile("(\\w+),\\s+(\\w+)").matcher(names); + return matcher.replaceAll("$2 $1"); } /** @@ -238,7 +239,8 @@ public String replaceFirstAndLastNames(String names) { * @return String where in all phone numbers last 7 digits replaced to X */ public String replaceLastSevenDigitsOfPhoneNumberToX(String phones) { - throw new ExerciseNotCompletedException(); + Matcher matcher = Pattern.compile("\\(?(\\d{3})[-.)]\\d{3}[-.)]\\d{4}").matcher(phones); + return matcher.replaceAll("$1-XXX-XXXX"); } /** @@ -250,6 +252,7 @@ public String replaceLastSevenDigitsOfPhoneNumberToX(String phones) { * @return String where all resources embraced in href */ public String insertLinksAndResourcesIntoHref(String links) { - throw new ExerciseNotCompletedException(); + Matcher matcher = Pattern.compile("\\[(.*?)]\\((http.*?)\\)").matcher(links); + return matcher.replaceAll("$1"); } } diff --git a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/FlightService.java b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/FlightService.java index fad792e47..101fa2581 100644 --- a/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/FlightService.java +++ b/4-0-object-oriented-programming/4-3-1-flight-search/src/main/java/com/bobocode/oop/service/FlightService.java @@ -36,7 +36,8 @@ public boolean registerFlight(String flightNumber) { * @return a list of found flight numbers */ public List searchFlights(String query) { - return flights.findAll().stream() + return flights.findAll() + .stream() .filter(line -> line.contains(query)) .collect(Collectors.toList()); } From ab00af7d36f355913335ca4e29065525c34550ea Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Thu, 27 Mar 2025 22:44:45 +0200 Subject: [PATCH 14/15] CrazyLambdas.java --- .../java/com/bobocode/fp/CrazyLambdas.java | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/5-0-functional-programming/5-1-1-crazy-lambdas/src/main/java/com/bobocode/fp/CrazyLambdas.java b/5-0-functional-programming/5-1-1-crazy-lambdas/src/main/java/com/bobocode/fp/CrazyLambdas.java index 78feebde2..91c3240e6 100644 --- a/5-0-functional-programming/5-1-1-crazy-lambdas/src/main/java/com/bobocode/fp/CrazyLambdas.java +++ b/5-0-functional-programming/5-1-1-crazy-lambdas/src/main/java/com/bobocode/fp/CrazyLambdas.java @@ -11,11 +11,6 @@ * {@link CrazyLambdas} is an exercise class. Each method returns a functional interface and it should be implemented * using either lambda or a method reference. Every method that is not implemented yet throws * {@link ExerciseNotCompletedException}. - *

- * TODO: remove exception and implement each method of this class using lambda or method reference - *

- * TODO: to get the most out of your learning, visit our website - *

* * @author Taras Boychuk */ @@ -27,7 +22,7 @@ public class CrazyLambdas { * @return a string supplier */ public static Supplier helloSupplier() { - throw new ExerciseNotCompletedException(); + return () -> "Hello"; } /** @@ -36,7 +31,7 @@ public static Supplier helloSupplier() { * @return a string predicate */ public static Predicate isEmptyPredicate() { - throw new ExerciseNotCompletedException(); + return String::isEmpty; } /** @@ -46,7 +41,7 @@ public static Predicate isEmptyPredicate() { * @return function that repeats Strings */ public static BiFunction stringMultiplier() { - throw new ExerciseNotCompletedException(); + return String::repeat; } /** @@ -56,7 +51,7 @@ public static BiFunction stringMultiplier() { * @return function that converts adds dollar sign */ public static Function toDollarStringFunction() { - throw new ExerciseNotCompletedException(); + return bigDecimal -> "$" + bigDecimal; } /** @@ -68,7 +63,7 @@ public static Function toDollarStringFunction() { * @return a string predicate */ public static Predicate lengthInRangePredicate(int min, int max) { - throw new ExerciseNotCompletedException(); + return s -> min <= s.length() && s.length() < max; } /** @@ -77,7 +72,7 @@ public static Predicate lengthInRangePredicate(int min, int max) { * @return int supplier */ public static IntSupplier randomIntSupplier() { - throw new ExerciseNotCompletedException(); + return () -> (int) (Math.random() * 100); } @@ -87,7 +82,7 @@ public static IntSupplier randomIntSupplier() { * @return int operation */ public static IntUnaryOperator boundedRandomIntSupplier() { - throw new ExerciseNotCompletedException(); + return i -> (int) (Math.random() * i); } /** @@ -96,7 +91,7 @@ public static IntUnaryOperator boundedRandomIntSupplier() { * @return square operation */ public static IntUnaryOperator intSquareOperation() { - throw new ExerciseNotCompletedException(); + return i -> i * i; } /** @@ -105,7 +100,7 @@ public static IntUnaryOperator intSquareOperation() { * @return binary sum operation */ public static LongBinaryOperator longSumOperation() { - throw new ExerciseNotCompletedException(); + return Long::sum; } /** @@ -114,7 +109,7 @@ public static LongBinaryOperator longSumOperation() { * @return string to int converter */ public static ToIntFunction stringToIntConverter() { - throw new ExerciseNotCompletedException(); + return Integer::valueOf; } /** @@ -125,16 +120,15 @@ public static ToIntFunction stringToIntConverter() { * @return a function supplier */ public static Supplier nMultiplyFunctionSupplier(int n) { - throw new ExerciseNotCompletedException(); + return () -> x -> n * x; } - /** * Returns a {@link UnaryOperator} that accepts str to str function and returns the same function composed with trim * * @return function that composes functions with trim() function */ public static UnaryOperator> composeWithTrimFunction() { - throw new ExerciseNotCompletedException(); + return f -> f.compose(String::trim); } /** @@ -145,7 +139,11 @@ public static UnaryOperator> composeWithTrimFunction() * @return a thread supplier */ public static Supplier runningThreadSupplier(Runnable runnable) { - throw new ExerciseNotCompletedException(); + return () -> { + Thread thread = new Thread(runnable); + thread.start(); + return thread; + }; } /** @@ -154,7 +152,7 @@ public static Supplier runningThreadSupplier(Runnable runnable) { * @return a runnable consumer */ public static Consumer newThreadRunnableConsumer() { - throw new ExerciseNotCompletedException(); + return Runnable::run; } /** @@ -164,7 +162,11 @@ public static Consumer newThreadRunnableConsumer() { * @return a function that transforms runnable into a thread supplier */ public static Function> runnableToThreadSupplierFunction() { - throw new ExerciseNotCompletedException(); + return runnable -> () -> { + Thread thread = new Thread(runnable); + thread.start(); + return thread; + }; } /** @@ -177,7 +179,7 @@ public static Function> runnableToThreadSupplierFunct * @return a binary function that receiver predicate and function and compose them to create a new function */ public static BiFunction functionToConditionalFunction() { - throw new ExerciseNotCompletedException(); + return (intFunction, condition) -> x -> condition.test(x) ? intFunction.applyAsInt(x) : x; } /** @@ -188,7 +190,7 @@ public static BiFunction funct * @return a high-order function that fetches a function from a function map by a given name or returns identity() */ public static BiFunction, String, IntUnaryOperator> functionLoader() { - throw new ExerciseNotCompletedException(); + return (functionMap, functionName) -> functionMap.getOrDefault(functionName, IntUnaryOperator.identity()); } /** @@ -206,7 +208,7 @@ public static BiFunction, String, IntUnaryOperator * @return a comparator instance */ public static > Comparator comparing(Function mapper) { - throw new ExerciseNotCompletedException(); + return (o1, o2) -> mapper.apply(o1).compareTo(mapper.apply(o2)); } /** @@ -226,7 +228,13 @@ public static > Comparator comparing(Funct */ public static > Comparator thenComparing( Comparator comparator, Function mapper) { - throw new ExerciseNotCompletedException(); + return (o1, o2) -> { + var initialResult = comparator.compare(o1, o2); + if (initialResult != 0) { + return initialResult; + } + return mapper.apply(o1).compareTo(mapper.apply(o2)); + }; } /** @@ -235,7 +243,7 @@ public static > Comparator thenComparing( * @return a supplier instance */ public static Supplier>> trickyWellDoneSupplier() { - throw new ExerciseNotCompletedException(); + return () -> () -> () -> "WELL DONE!"; } } From 85a4758c8580767af98cd3bfd00255b397b274fe Mon Sep 17 00:00:00 2001 From: JaverJaver Date: Fri, 28 Mar 2025 22:36:37 +0200 Subject: [PATCH 15/15] CrazyOptionals.java --- .../java/com/bobocode/fp/CrazyOptionals.java | 64 ++++++++++++------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/5-0-functional-programming/5-3-1-crazy-optionals/src/main/java/com/bobocode/fp/CrazyOptionals.java b/5-0-functional-programming/5-3-1-crazy-optionals/src/main/java/com/bobocode/fp/CrazyOptionals.java index 1ab1faa67..b8687080f 100644 --- a/5-0-functional-programming/5-3-1-crazy-optionals/src/main/java/com/bobocode/fp/CrazyOptionals.java +++ b/5-0-functional-programming/5-3-1-crazy-optionals/src/main/java/com/bobocode/fp/CrazyOptionals.java @@ -12,19 +12,12 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.math.BigDecimal; -import java.util.List; -import java.util.Optional; -import java.util.OptionalDouble; +import java.util.*; /** * {@link CrazyOptionals} is an exercise class. Each method represents some operation with a {@link Account} and * should be implemented using Optional API. Every method that is not implemented yet throws * {@link ExerciseNotCompletedException}. - *

- * TODO: remove exception and implement each method of this class using Optional API - *

- * TODO: to get the most out of your learning, visit our website - *

* * @author Taras Boychuk */ @@ -37,7 +30,7 @@ public class CrazyOptionals { * @return optional object that holds text */ public static Optional optionalOfString(@Nullable String text) { - throw new ExerciseNotCompletedException(); + return Optional.ofNullable(text); } /** @@ -47,7 +40,9 @@ public static Optional optionalOfString(@Nullable String text) { * @param amount money to deposit */ public static void deposit(AccountProvider accountProvider, BigDecimal amount) { - throw new ExerciseNotCompletedException(); + accountProvider.getAccount() + .ifPresent(account -> account.setBalance( + account.getBalance().add(amount))); } /** @@ -57,7 +52,7 @@ public static void deposit(AccountProvider accountProvider, BigDecimal amount) { * @return optional object that holds account */ public static Optional optionalOfAccount(@Nonnull Account account) { - throw new ExerciseNotCompletedException(); + return Optional.of(account); } /** @@ -69,7 +64,7 @@ public static Optional optionalOfAccount(@Nonnull Account account) { * @return account from provider or defaultAccount */ public static Account getAccount(AccountProvider accountProvider, Account defaultAccount) { - throw new ExerciseNotCompletedException(); + return accountProvider.getAccount().orElse(defaultAccount); } /** @@ -80,7 +75,8 @@ public static Account getAccount(AccountProvider accountProvider, Account defaul * @param accountService */ public static void processAccount(AccountProvider accountProvider, AccountService accountService) { - throw new ExerciseNotCompletedException(); + accountProvider.getAccount() + .ifPresentOrElse(accountService::processAccount, accountService::processWithNoAccount); } /** @@ -91,7 +87,8 @@ public static void processAccount(AccountProvider accountProvider, AccountServic * @return provided or generated account */ public static Account getOrGenerateAccount(AccountProvider accountProvider) { - throw new ExerciseNotCompletedException(); + return accountProvider.getAccount() + .orElseGet(Accounts::generateAccount); } /** @@ -101,7 +98,8 @@ public static Account getOrGenerateAccount(AccountProvider accountProvider) { * @return optional balance */ public static Optional retrieveBalance(AccountProvider accountProvider) { - throw new ExerciseNotCompletedException(); + return accountProvider.getAccount() + .map(Account::getBalance); } /** @@ -112,7 +110,9 @@ public static Optional retrieveBalance(AccountProvider accountProvid * @return provided account */ public static Account getAccount(AccountProvider accountProvider) { - throw new ExerciseNotCompletedException(); + return accountProvider.getAccount().orElseThrow( + () -> new AccountNotFoundException("No Account provided!") + ); } /** @@ -122,7 +122,8 @@ public static Account getAccount(AccountProvider accountProvider) { * @return optional credit balance */ public static Optional retrieveCreditBalance(CreditAccountProvider accountProvider) { - throw new ExerciseNotCompletedException(); + return accountProvider.getAccount() + .flatMap(CreditAccount::getCreditBalance); } @@ -134,7 +135,9 @@ public static Optional retrieveCreditBalance(CreditAccountProvider a * @return optional gmail account */ public static Optional retrieveAccountGmail(AccountProvider accountProvider) { - throw new ExerciseNotCompletedException(); + return accountProvider.getAccount() + .filter(account -> account.getEmail().endsWith("gmail.com")) + .or(Optional::empty); } /** @@ -147,7 +150,9 @@ public static Optional retrieveAccountGmail(AccountProvider accountProv * @return account got from either accountProvider or fallbackProvider */ public static Account getAccountWithFallback(AccountProvider accountProvider, AccountProvider fallbackProvider) { - throw new ExerciseNotCompletedException(); + return accountProvider.getAccount() + .or(fallbackProvider::getAccount) + .orElseThrow(); } /** @@ -158,7 +163,9 @@ public static Account getAccountWithFallback(AccountProvider accountProvider, Ac * @return account with the highest balance */ public static Account getAccountWithMaxBalance(List accounts) { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .max(Comparator.comparing(Account::getBalance)) + .orElseThrow(); } /** @@ -168,7 +175,12 @@ public static Account getAccountWithMaxBalance(List accounts) { * @return the lowest balance values */ public static OptionalDouble findMinBalanceValue(List accounts) { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .min(Comparator.comparing(Account::getBalance)) + .map(Account::getBalance) + .map(BigDecimal::doubleValue) + .map(OptionalDouble::of) + .orElse(OptionalDouble.empty()); } /** @@ -178,7 +190,9 @@ public static OptionalDouble findMinBalanceValue(List accounts) { * @param accountService */ public static void processAccountWithMaxBalance(List accounts, AccountService accountService) { - throw new ExerciseNotCompletedException(); + accounts.stream() + .max(Comparator.comparing(Account::getBalance)) + .ifPresent(accountService::processAccount); } /** @@ -188,7 +202,11 @@ public static void processAccountWithMaxBalance(List accounts, AccountS * @return total credit balance */ public static double calculateTotalCreditBalance(List accounts) { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .map(CreditAccount::getCreditBalance) + .flatMap(Optional::stream) + .mapToDouble(BigDecimal::doubleValue) + .sum(); } }