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..180603a28 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-0-hello-generics/src/main/java/com/bobocode/basics/BoxDemoApp.java b/1-0-java-basics/1-3-0-hello-generics/src/main/java/com/bobocode/basics/BoxDemoApp.java
index bc12174ee..8ade1196f 100644
--- a/1-0-java-basics/1-3-0-hello-generics/src/main/java/com/bobocode/basics/BoxDemoApp.java
+++ b/1-0-java-basics/1-3-0-hello-generics/src/main/java/com/bobocode/basics/BoxDemoApp.java
@@ -9,12 +9,12 @@
*/
public class BoxDemoApp {
public static void main(String[] args) {
- Box intBox = new Box(123);
- Box intBox2 = new Box(321);
+ Box intBox = new Box<>(123);
+ Box intBox2 = new Box<>(321);
System.out.println((int) intBox.getValue() + (int) intBox2.getValue());
intBox.setValue(222);
- intBox.setValue("abc"); // this should not be allowed
+// intBox.setValue("abc"); // this should not be allowed
// the following code will compile, but will throw runtime exception
System.out.println((int) intBox.getValue() + (int) intBox2.getValue());
}
diff --git a/1-0-java-basics/1-3-0-hello-generics/src/test/java/com/bobocode/basics/BoxTest.java b/1-0-java-basics/1-3-0-hello-generics/src/test/java/com/bobocode/basics/BoxTest.java
index 76e0f385a..0f3716548 100644
--- a/1-0-java-basics/1-3-0-hello-generics/src/test/java/com/bobocode/basics/BoxTest.java
+++ b/1-0-java-basics/1-3-0-hello-generics/src/test/java/com/bobocode/basics/BoxTest.java
@@ -41,7 +41,7 @@ void typeParameterIsNotBounded() {
@SneakyThrows
@Order(4)
@DisplayName("Field \"value\" is \"T\"")
- void valueFieldIsGeneric() {
+ void valueFieldIsGeneric() throws NoSuchFieldException {
var valueField = Box.class.getDeclaredField("value");
var genericType = valueField.getGenericType();
@@ -64,7 +64,7 @@ void constructorParameterIsGeneric() {
@SneakyThrows
@Order(6)
@DisplayName("Getter return type is \"T\"")
- void getterReturnTypeIsGeneric() {
+ void getterReturnTypeIsGeneric() throws NoSuchMethodException {
var getter = Box.class.getDeclaredMethod("getValue");
assertThat(getter.getGenericReturnType().getTypeName()).isEqualTo(TYPE_PARAMETER_NAME);
@@ -74,7 +74,7 @@ void getterReturnTypeIsGeneric() {
@SneakyThrows
@Order(7)
@DisplayName("Setter parameter type is \"T\"")
- void setterParameterIsGeneric() {
+ void setterParameterIsGeneric() throws NoSuchMethodException {
var setter = Box.class.getDeclaredMethod("setValue", Object.class);
assert (setter.getParameters().length == 1);
var parameter = setter.getParameters()[0];
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..35253e7b7 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
@@ -5,10 +5,8 @@
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;
/**
* {@link CrazyGenerics} is an exercise class. It consists of classes, interfaces and methods that should be updated
@@ -33,8 +31,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 +43,18 @@ 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;
+
+
+ public Limited(T actual, T min, T max) {
+ this.actual = actual;
+ this.min = min;
+ this.max = max;
+ }
}
/**
@@ -59,8 +64,9 @@ 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
// todo: add convert method
+ R convert(T source);
}
/**
@@ -70,10 +76,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 +88,14 @@ 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) {
+ // todo: update parameter and implement the method
+ if(val.compareTo(max) > 0){
+ max = val;
+ }
}
- public Object getMax() {
+ public T getMax() {
return max;
}
}
@@ -97,8 +106,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 +117,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();
+ C getEntityCollection();
}
/**
@@ -120,7 +129,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 +142,10 @@ 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> { // todo: refactor it to make generic and provide a default impl of compareTo
+ default int compareTo(Collection> other) { // Change parameter type
+ return Integer.compare(this.size(), other.size());
+ }
}
/**
@@ -147,7 +159,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));
}
@@ -160,8 +172,14 @@ 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 extends BaseEntity> entities) {
+ // todo: refactor parameter and implement method
+ for (BaseEntity entity : entities) {
+ if (entity.getUuid() == null) {
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -173,8 +191,14 @@ 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 extends BaseEntity> entities, Predicate super BaseEntity> validationPredicate) {
+ // todo: add method parameters and implement the logic
+ for (BaseEntity entity : entities) {
+ if (!validationPredicate.test(entity)) {
+ return false;
+ }
+ }
+ return true;
}
/**
@@ -187,8 +211,17 @@ 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) {
+ // todo: update method signature and implement it
+ int count =0;
+ UUID targetUUID = targetEntity.getUuid();
+ for (T entity : entities) {
+ UUID entityUUID = entity.getUuid();
+ if (entityUUID.equals(targetUUID)) {
+ count++;
+ }
+ }
+ return count > 1;
}
/**
@@ -201,7 +234,15 @@ public static boolean hasDuplicates() {
* @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){
+ T max = null;
+ for (T element : elements) {
+ if (max == null || comparator.compare(element, max) > 0) {
+ max = element;
+ }
+ }
+ return Optional.ofNullable(max);
+ }
/**
* findMostRecentlyCreatedEntity is a generic util method that accepts a collection of entities and returns the
* one that is the most recently created. If collection is empty,
@@ -215,7 +256,10 @@ public static boolean hasDuplicates() {
* @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(NoSuchElementException::new);
+ }
/**
* An util method that allows to swap two elements of any list. It changes the list so the element with the index
* i will be located on index j, and the element with index j, will be located on the index i.
@@ -228,7 +272,14 @@ public static boolean hasDuplicates() {
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
+ // todo: complete method implementation
+ swapHelper(elements,i,j);
+ }
+
+ private static void swapHelper(List elements, int i, int j) {
+ T temp = elements.get(i);
+ elements.set(i, elements.get(j));
+ elements.set(j, 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..6651e81d9 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
@@ -18,4 +18,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/1-0-java-basics/1-3-1-crazy-generics/src/test/java/com/bobocode/basics/CrazyGenericsTest.java b/1-0-java-basics/1-3-1-crazy-generics/src/test/java/com/bobocode/basics/CrazyGenericsTest.java
index d616e908a..f9ba75514 100644
--- a/1-0-java-basics/1-3-1-crazy-generics/src/test/java/com/bobocode/basics/CrazyGenericsTest.java
+++ b/1-0-java-basics/1-3-1-crazy-generics/src/test/java/com/bobocode/basics/CrazyGenericsTest.java
@@ -12,6 +12,7 @@
import java.io.Serializable;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
@@ -70,7 +71,7 @@ void sourcedClassTypeParameterIsNotBounded() {
@SneakyThrows
@Order(4)
@DisplayName("Sourced class field \"value\" has generic type \"T\"")
- void valueFieldIsGeneric() {
+ void valueFieldIsGeneric() throws NoSuchFieldException {
var valueField = Sourced.class.getDeclaredField("value");
var genericType = valueField.getGenericType();
@@ -144,7 +145,7 @@ void converterInterfaceSecondTypeParameterIsCalledR() {
@SneakyThrows
@Order(11)
@DisplayName("Convert method parameter \"obj\" has type \"T\"")
- void converterMethodParameterHasTypeT() {
+ void converterMethodParameterHasTypeT() throws NoSuchMethodException {
var convertMethod = Converter.class.getDeclaredMethod("convert", Object.class);
var objParam = convertMethod.getParameters()[0];
@@ -155,7 +156,7 @@ void converterMethodParameterHasTypeT() {
@SneakyThrows
@Order(12)
@DisplayName("Convert method return type is \"R\"")
- void converterMethodReturnTypeIsR() {
+ void converterMethodReturnTypeIsR() throws NoSuchMethodException {
var convertMethod = Converter.class.getDeclaredMethod("convert", Object.class);
assertThat(convertMethod.getGenericReturnType().getTypeName()).isEqualTo(SECOND_TYPE_PARAMETER_NAME);
@@ -237,7 +238,7 @@ void maxHolderGetMaxReturnTypeIsT() {
@Order(20)
@SneakyThrows
@DisplayName("MaxHolder put stores argument value when it's greater than max")
- void maxHolderPut() {
+ void maxHolderPut() throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
Constructor> constructor = MaxHolder.class.getConstructors()[0];
var maxHolder = constructor.newInstance(10);
var putMethod = getMethodByName(MaxHolder.class, "put");
@@ -787,7 +788,7 @@ void findMostRecentlyCreatedEntityIsAGenericMethod() {
@DisplayName("findMostRecentlyCreatedEntity returns the most recently created entity")
@SneakyThrows
void findMostRecentlyCreatedEntityReturnsEntityWithMaxCreatedOnValue(List extends BaseEntity> entities,
- BaseEntity mostRecentlyCreatedEntity) {
+ BaseEntity mostRecentlyCreatedEntity) throws InvocationTargetException, IllegalAccessException {
var findMostRecentlyCreatedEntityMethod = getMethodByName(CollectionUtil.class, "findMostRecentlyCreatedEntity");
var result = findMostRecentlyCreatedEntityMethod.invoke(null, entities);
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..865e4f723 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,7 +17,7 @@
* @author Taras Boychuk
*/
public class HeterogeneousMaxHolder {
-
+ private final Map, Object> maxValues = 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
* of this method makes sure that only max value is stored and everything else is ignored.
@@ -31,7 +33,14 @@ public class HeterogeneousMaxHolder {
* @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) {
+ T currentValue = key.cast(maxValues.get(key));
+ if (currentValue == null || value.compareTo(currentValue) > 0) {
+ maxValues.put(key, value);
+ return currentValue;
+ }
+ return 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.
@@ -45,7 +54,15 @@ public class HeterogeneousMaxHolder {
* @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 super T> comparator) {
+ T currentValue = key.cast(maxValues.get(key));
+ if (currentValue == null || comparator.compare(value, currentValue) > 0) {
+ maxValues.put(key, value);
+ return currentValue;
+ }
+ 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.
*
@@ -54,4 +71,7 @@ public class HeterogeneousMaxHolder {
* @return current max value or null
*/
// todo: implement a method according to javadoc
+ public T getMax(Class key){
+ return (T) maxValues.get(key);
+ }
}
diff --git a/5-0-functional-programming/5-0-1-lambda-functions-map/src/main/java/com/bobocode/fp/Functions.java b/5-0-functional-programming/5-0-1-lambda-functions-map/src/main/java/com/bobocode/fp/Functions.java
index a1eed08d4..589a22889 100644
--- a/5-0-functional-programming/5-0-1-lambda-functions-map/src/main/java/com/bobocode/fp/Functions.java
+++ b/5-0-functional-programming/5-0-1-lambda-functions-map/src/main/java/com/bobocode/fp/Functions.java
@@ -29,7 +29,11 @@ public static FunctionMap intFunctionMap() {
FunctionMap intFunctionMap = new FunctionMap<>();
// todo: according to the javadoc add functions using lambda expression
-
+ intFunctionMap.addFunction("abs",x->Math.abs(x));
+ intFunctionMap.addFunction("sgn",x->Integer.compare(x,0));
+ intFunctionMap.addFunction("increment",x->x+1);
+ intFunctionMap.addFunction("decrement",x->x-1);
+ intFunctionMap.addFunction("square",x->x*x);
return intFunctionMap;
}
}
diff --git a/5-0-functional-programming/5-0-2-stream-sum-of-squares/src/main/java/com/bobocode/fp/SumOfSquares.java b/5-0-functional-programming/5-0-2-stream-sum-of-squares/src/main/java/com/bobocode/fp/SumOfSquares.java
index b043454d1..7bba7390e 100644
--- a/5-0-functional-programming/5-0-2-stream-sum-of-squares/src/main/java/com/bobocode/fp/SumOfSquares.java
+++ b/5-0-functional-programming/5-0-2-stream-sum-of-squares/src/main/java/com/bobocode/fp/SumOfSquares.java
@@ -2,6 +2,8 @@
import com.bobocode.fp.exception.InvalidRangeException;
+import java.util.stream.IntStream;
+
/**
* This class allow to calculate a sum of squares of integer number in a certain range. It was implemented using
* OO approach. Your job is to refactor it using functional approach. E.g. avoid using mutable variables
@@ -26,10 +28,6 @@ static int calculateSumOfSquaresInRange(int startInclusive, int endInclusive) {
}
// todo: refactor using functional approach – instead of using for loop, use IntStream.rangeClose()
- int sumOfSquares = 0;
- for (int i = startInclusive; i <= endInclusive; i++) {
- sumOfSquares += i * i;
- }
- return sumOfSquares;
+ return IntStream.rangeClosed(startInclusive,endInclusive).map(x->x*x).sum();
}
}
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..0279e4369 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
@@ -5,6 +5,7 @@
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Map;
+import java.util.Random;
import java.util.function.*;
/**
@@ -27,7 +28,8 @@ public class CrazyLambdas {
* @return a string supplier
*/
public static Supplier helloSupplier() {
- throw new ExerciseNotCompletedException();
+ Supplier val = () ->"Hello";
+ return val;
}
/**
@@ -36,7 +38,8 @@ public static Supplier helloSupplier() {
* @return a string predicate
*/
public static Predicate isEmptyPredicate() {
- throw new ExerciseNotCompletedException();
+ Predicate val = (x) -> x.isEmpty() ;
+ return val;
}
/**
@@ -46,7 +49,8 @@ public static Predicate isEmptyPredicate() {
* @return function that repeats Strings
*/
public static BiFunction stringMultiplier() {
- throw new ExerciseNotCompletedException();
+ BiFunction val = (x,y) -> x.repeat(y);
+ return val;
}
/**
@@ -56,7 +60,8 @@ public static BiFunction stringMultiplier() {
* @return function that converts adds dollar sign
*/
public static Function toDollarStringFunction() {
- throw new ExerciseNotCompletedException();
+ Function val = (x) -> "$"+x;
+ return val;
}
/**
@@ -68,7 +73,8 @@ public static Function toDollarStringFunction() {
* @return a string predicate
*/
public static Predicate lengthInRangePredicate(int min, int max) {
- throw new ExerciseNotCompletedException();
+ Predicate val = (x)-> min <= x.length() && x.length()< max ;
+ return val;
}
/**
@@ -77,7 +83,9 @@ public static Predicate lengthInRangePredicate(int min, int max) {
* @return int supplier
*/
public static IntSupplier randomIntSupplier() {
- throw new ExerciseNotCompletedException();
+ Random random = new Random();
+ IntSupplier val = ()-> random.nextInt();
+ return val;
}
@@ -87,7 +95,8 @@ public static IntSupplier randomIntSupplier() {
* @return int operation
*/
public static IntUnaryOperator boundedRandomIntSupplier() {
- throw new ExerciseNotCompletedException();
+ IntUnaryOperator val = (x)-> new Random(x).nextInt();
+ return val;
}
/**
@@ -96,7 +105,8 @@ public static IntUnaryOperator boundedRandomIntSupplier() {
* @return square operation
*/
public static IntUnaryOperator intSquareOperation() {
- throw new ExerciseNotCompletedException();
+ IntUnaryOperator val = (x) -> x*x;
+ return val;
}
/**
@@ -105,7 +115,8 @@ public static IntUnaryOperator intSquareOperation() {
* @return binary sum operation
*/
public static LongBinaryOperator longSumOperation() {
- throw new ExerciseNotCompletedException();
+ LongBinaryOperator val = (x,y) -> x+y;
+ return val;
}
/**
@@ -114,7 +125,7 @@ public static LongBinaryOperator longSumOperation() {
* @return string to int converter
*/
public static ToIntFunction stringToIntConverter() {
- throw new ExerciseNotCompletedException();
+ return (x) -> Integer.parseInt(x);
}
/**
@@ -125,7 +136,7 @@ public static ToIntFunction stringToIntConverter() {
* @return a function supplier
*/
public static Supplier nMultiplyFunctionSupplier(int n) {
- throw new ExerciseNotCompletedException();
+ return ()->(x)->x*n;
}
/**
@@ -134,7 +145,7 @@ public static Supplier nMultiplyFunctionSupplier(int n) {
* @return function that composes functions with trim() function
*/
public static UnaryOperator> composeWithTrimFunction() {
- throw new ExerciseNotCompletedException();
+ return (y)->(x)->y.apply(x.trim());
}
/**
@@ -145,7 +156,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.run();
+ return thread;
+ };
}
/**
@@ -154,7 +169,10 @@ public static Supplier runningThreadSupplier(Runnable runnable) {
* @return a runnable consumer
*/
public static Consumer newThreadRunnableConsumer() {
- throw new ExerciseNotCompletedException();
+ return (runnable -> {
+ Thread thread = new Thread(runnable);
+ thread.run();
+ });
}
/**
@@ -164,7 +182,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 +199,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 (x,y)->(z)-> y.test(z) ? x.applyAsInt(z):z;
}
/**
@@ -188,7 +210,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 (map,func)-> map.getOrDefault(func,IntUnaryOperator.identity());
}
/**
@@ -206,7 +228,7 @@ public static BiFunction, String, IntUnaryOperator
* @return a comparator instance
*/
public static > Comparator comparing(Function super T, ? extends U> mapper) {
- throw new ExerciseNotCompletedException();
+ return (comp1,comp2)->mapper.apply(comp1).compareTo(mapper.apply(comp2));
}
/**
@@ -226,7 +248,7 @@ public static > Comparator comparing(Funct
*/
public static > Comparator thenComparing(
Comparator super T> comparator, Function super T, ? extends U> mapper) {
- throw new ExerciseNotCompletedException();
+ return (comp1,comp2)-> comparator.compare(comp1,comp2) != 0 ? comparator.compare(comp1,comp2) : mapper.apply(comp1).compareTo(mapper.apply(comp2));
}
/**
@@ -235,7 +257,7 @@ public static > Comparator thenComparing(
* @return a supplier instance
*/
public static Supplier>> trickyWellDoneSupplier() {
- throw new ExerciseNotCompletedException();
+ return ()->()->()->"WELL DONE!";
}
}
diff --git a/5-0-functional-programming/5-2-1-crazy-streams/src/main/java/com/bobocode/fp/CrazyStreams.java b/5-0-functional-programming/5-2-1-crazy-streams/src/main/java/com/bobocode/fp/CrazyStreams.java
index 40ffc170f..093db7b3f 100644
--- a/5-0-functional-programming/5-2-1-crazy-streams/src/main/java/com/bobocode/fp/CrazyStreams.java
+++ b/5-0-functional-programming/5-2-1-crazy-streams/src/main/java/com/bobocode/fp/CrazyStreams.java
@@ -1,12 +1,18 @@
package com.bobocode.fp;
+import com.bobocode.fp.exception.EntityNotFoundException;
import com.bobocode.model.Account;
+import com.bobocode.model.Sex;
import com.bobocode.util.ExerciseNotCompletedException;
import lombok.AllArgsConstructor;
+import org.checkerframework.checker.units.qual.A;
+import org.checkerframework.checker.units.qual.C;
import java.math.BigDecimal;
import java.time.Month;
import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* {@link CrazyStreams} is an exercise class. Each method represent some operation with a collection of accounts that
@@ -30,7 +36,7 @@ public class CrazyStreams {
* @return account with max balance wrapped with optional
*/
public Optional findRichestPerson() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().max(Comparator.comparing(Account::getBalance));
}
/**
@@ -40,7 +46,7 @@ public Optional findRichestPerson() {
* @return a list of accounts
*/
public List findAccountsByBirthdayMonth(Month birthdayMonth) {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().filter(account-> account.getBirthday().getMonth() == birthdayMonth).collect(Collectors.toList());
}
/**
@@ -50,7 +56,8 @@ public List findAccountsByBirthdayMonth(Month birthdayMonth) {
* @return a map where key is true or false, and value is list of male, and female accounts
*/
public Map> partitionMaleAccounts() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream()
+ .collect(Collectors.partitioningBy(account -> Sex.MALE.equals(account.getSex())));
}
/**
@@ -60,7 +67,7 @@ public Map> partitionMaleAccounts() {
* @return a map where key is an email domain and value is a list of all account with such email
*/
public Map> groupAccountsByEmailDomain() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().collect(Collectors.groupingBy(account-> account.getEmail().substring(account.getEmail().indexOf('@')+1)));
}
/**
@@ -69,7 +76,7 @@ public Map> groupAccountsByEmailDomain() {
* @return total number of letters of first and last names of all accounts
*/
public int getNumOfLettersInFirstAndLastNames() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().mapToInt(account->account.getFirstName().length() + account.getLastName().length()).sum();
}
/**
@@ -78,7 +85,7 @@ public int getNumOfLettersInFirstAndLastNames() {
* @return total balance of all accounts
*/
public BigDecimal calculateTotalBalance() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().map(Account::getBalance).reduce(BigDecimal.ZERO,BigDecimal::add);
}
/**
@@ -87,7 +94,7 @@ public BigDecimal calculateTotalBalance() {
* @return list of accounts sorted by first and last names
*/
public List sortByFirstAndLastNames() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().sorted(Comparator.comparing(Account ::getFirstName).thenComparing(Account::getLastName)).collect(Collectors.toList());
}
/**
@@ -97,7 +104,7 @@ public List sortByFirstAndLastNames() {
* @return true if there is an account that has an email with provided domain
*/
public boolean containsAccountWithEmailDomain(String emailDomain) {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().anyMatch(x->x.getEmail().substring(x.getEmail().indexOf('@')+1).equals(emailDomain));
}
/**
@@ -108,7 +115,11 @@ public boolean containsAccountWithEmailDomain(String emailDomain) {
* @return account balance
*/
public BigDecimal getBalanceByEmail(String email) {
- throw new ExerciseNotCompletedException();
+ return accounts.stream()
+ .filter(account->account.getEmail().equals(email))
+ .map(Account::getBalance)
+ .findFirst()
+ .orElseThrow(()-> new EntityNotFoundException("Cannot find Account by email="+email));
}
/**
@@ -117,7 +128,7 @@ public BigDecimal getBalanceByEmail(String email) {
* @return map of accounts by its ids
*/
public Map collectAccountsById() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().collect(Collectors.toMap(Account::getId, account -> account));
}
/**
@@ -128,7 +139,9 @@ public Map collectAccountsById() {
* @return map of account by its ids the were created in a particular year
*/
public Map collectBalancesByEmailForAccountsCreatedOn(int year) {
- throw new ExerciseNotCompletedException();
+ return accounts.stream()
+ .filter(account -> account.getCreationDate().getYear() == year)
+ .collect(Collectors.toMap(account -> account.getEmail(),account -> account.getBalance()));
}
/**
@@ -138,7 +151,10 @@ public Map collectBalancesByEmailForAccountsCreatedOn(int ye
* @return a map where key is a last name and value is a set of first names
*/
public Map> groupFirstNamesByLastNames() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream().collect(
+ Collectors.groupingBy(
+ Account::getLastName,
+ Collectors.mapping(Account::getFirstName,Collectors.toSet())));
}
/**
@@ -148,7 +164,11 @@ public Map> groupFirstNamesByLastNames() {
* @return a map where a key is a birthday month and value is comma-separated first names
*/
public Map groupCommaSeparatedFirstNamesByBirthdayMonth() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream()
+ .collect(Collectors.groupingBy(
+ account->account.getBirthday().getMonth(),
+ Collectors.mapping(Account::getFirstName,
+ Collectors.joining(", "))));
}
/**
@@ -158,7 +178,12 @@ public Map groupCommaSeparatedFirstNamesByBirthdayMonth() {
* @return a map where key is a creation month and value is total balance of all accounts created in that month
*/
public Map groupTotalBalanceByCreationMonth() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream()
+ .collect(Collectors.groupingBy(
+ account -> account.getCreationDate().getMonth(),
+ Collectors.mapping(Account::getBalance,
+ Collectors.reducing(BigDecimal.ZERO,BigDecimal::add)
+ )));
}
/**
@@ -168,7 +193,11 @@ public Map groupTotalBalanceByCreationMonth() {
* @return a map where key is a letter and value is its count in all first names
*/
public Map getCharacterFrequencyInFirstNames() {
- throw new ExerciseNotCompletedException();
+ return accounts.stream()
+ .map(Account::getFirstName)
+ .flatMapToInt(String::chars)
+ .mapToObj(c->(char) c)
+ .collect(Collectors.groupingBy(c->c,Collectors.counting()));
}
/**
@@ -179,7 +208,14 @@ public Map getCharacterFrequencyInFirstNames() {
* @return a map where key is a letter and value is its count ignoring case in all first and last names
*/
public Map getCharacterFrequencyIgnoreCaseInFirstAndLastNames(int nameLengthBound) {
- throw new ExerciseNotCompletedException();
+ return accounts.stream()
+ .filter(account -> account.getFirstName().length() >= nameLengthBound || account.getLastName().length() >= nameLengthBound)
+ .flatMap(account -> Stream.of(account.getFirstName().toLowerCase(), account.getLastName().toLowerCase()))
+ .filter(name -> name.length() >= nameLengthBound)
+ .flatMap(name -> name.chars().mapToObj(c -> (char) c))
+ .filter(c -> c >= 'a' && c <= 'z')
+ .collect(Collectors.groupingBy(c -> c, Collectors.counting()));
+
}
}
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..228949bf5 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,9 +12,7 @@
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
@@ -37,7 +35,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 +45,9 @@ public static Optional optionalOfString(@Nullable String text) {
* @param amount money to deposit
*/
public static void deposit(AccountProvider accountProvider, BigDecimal amount) {
- throw new ExerciseNotCompletedException();
+ Optional.ofNullable(accountProvider)
+ .flatMap(AccountProvider::getAccount)
+ .ifPresent(account->account.setBalance(account.getBalance().add(amount)));
}
/**
@@ -57,7 +57,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 +69,9 @@ 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 Optional.of(accountProvider)
+ .flatMap(AccountProvider::getAccount)
+ .orElse(defaultAccount);
}
/**
@@ -80,7 +82,10 @@ public static Account getAccount(AccountProvider accountProvider, Account defaul
* @param accountService
*/
public static void processAccount(AccountProvider accountProvider, AccountService accountService) {
- throw new ExerciseNotCompletedException();
+ Optional.of(accountProvider)
+ .flatMap(AccountProvider::getAccount)
+ .ifPresentOrElse(accountService::processAccount
+ ,accountService::processWithNoAccount);
}
/**
@@ -91,7 +96,9 @@ public static void processAccount(AccountProvider accountProvider, AccountServic
* @return provided or generated account
*/
public static Account getOrGenerateAccount(AccountProvider accountProvider) {
- throw new ExerciseNotCompletedException();
+ return Optional.of(accountProvider)
+ .flatMap(AccountProvider::getAccount)
+ .orElseGet(Accounts::generateAccount);
}
/**
@@ -101,7 +108,9 @@ public static Account getOrGenerateAccount(AccountProvider accountProvider) {
* @return optional balance
*/
public static Optional retrieveBalance(AccountProvider accountProvider) {
- throw new ExerciseNotCompletedException();
+ return Optional.ofNullable(accountProvider)
+ .flatMap(AccountProvider::getAccount)
+ .map(Account::getBalance);
}
/**
@@ -112,7 +121,9 @@ public static Optional retrieveBalance(AccountProvider accountProvid
* @return provided account
*/
public static Account getAccount(AccountProvider accountProvider) {
- throw new ExerciseNotCompletedException();
+ return Optional.ofNullable(accountProvider)
+ .flatMap(AccountProvider::getAccount)
+ .orElseThrow(()-> new AccountNotFoundException("No Account provided!"));
}
/**
@@ -122,7 +133,9 @@ public static Account getAccount(AccountProvider accountProvider) {
* @return optional credit balance
*/
public static Optional retrieveCreditBalance(CreditAccountProvider accountProvider) {
- throw new ExerciseNotCompletedException();
+ return Optional.ofNullable(accountProvider)
+ .flatMap(CreditAccountProvider::getAccount)
+ .flatMap(CreditAccount::getCreditBalance);
}
@@ -134,7 +147,10 @@ public static Optional retrieveCreditBalance(CreditAccountProvider a
* @return optional gmail account
*/
public static Optional retrieveAccountGmail(AccountProvider accountProvider) {
- throw new ExerciseNotCompletedException();
+ return Optional.ofNullable(accountProvider)
+ .flatMap(AccountProvider::getAccount)
+ .filter(account -> account.getEmail()!=null && account.getEmail().endsWith("@gmail.com"));
+
}
/**
@@ -147,7 +163,10 @@ 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 Optional.ofNullable(accountProvider)
+ .flatMap(AccountProvider::getAccount)
+ .or(()->Optional.ofNullable(fallbackProvider).flatMap(AccountProvider::getAccount))
+ .orElseThrow(NoSuchElementException::new);
}
/**
@@ -158,7 +177,10 @@ public static Account getAccountWithFallback(AccountProvider accountProvider, Ac
* @return account with the highest balance
*/
public static Account getAccountWithMaxBalance(List accounts) {
- throw new ExerciseNotCompletedException();
+ return Optional.ofNullable(accounts)
+ .filter(list -> !list.isEmpty())
+ .flatMap(list -> list.stream().max(Comparator.comparing(Account::getBalance)))
+ .orElseThrow(NoSuchElementException::new);
}
/**
@@ -168,7 +190,11 @@ public static Account getAccountWithMaxBalance(List accounts) {
* @return the lowest balance values
*/
public static OptionalDouble findMinBalanceValue(List accounts) {
- throw new ExerciseNotCompletedException();
+ return Optional.ofNullable(accounts)
+ .filter(list->!list.isEmpty())
+ .flatMap(list->list.stream().min(Comparator.comparing(Account::getBalance)))
+ .map(account ->OptionalDouble.of(account.getBalance().doubleValue()))
+ .orElseGet(OptionalDouble::empty);
}
/**
@@ -178,7 +204,10 @@ public static OptionalDouble findMinBalanceValue(List accounts) {
* @param accountService
*/
public static void processAccountWithMaxBalance(List accounts, AccountService accountService) {
- throw new ExerciseNotCompletedException();
+ Optional.ofNullable(accounts)
+ .filter(list->!list.isEmpty())
+ .flatMap(list->list.stream().max(Comparator.comparing(Account::getBalance)))
+ .ifPresent(accountService::processAccount);
}
/**
@@ -188,7 +217,14 @@ public static void processAccountWithMaxBalance(List accounts, AccountS
* @return total credit balance
*/
public static double calculateTotalCreditBalance(List accounts) {
- throw new ExerciseNotCompletedException();
+
+ return Optional.ofNullable(accounts)
+ .stream()
+ .flatMap(List::stream)
+ .map(CreditAccount::getCreditBalance)
+ .flatMap(Optional::stream)
+ .mapToDouble(BigDecimal::doubleValue)
+ .sum();
}
}
diff --git a/5-0-functional-programming/5-4-1-fun-prime-numbers/src/main/java/com/bobocode/fp/PrimeNumbers.java b/5-0-functional-programming/5-4-1-fun-prime-numbers/src/main/java/com/bobocode/fp/PrimeNumbers.java
index e4a99188d..741d59127 100644
--- a/5-0-functional-programming/5-4-1-fun-prime-numbers/src/main/java/com/bobocode/fp/PrimeNumbers.java
+++ b/5-0-functional-programming/5-4-1-fun-prime-numbers/src/main/java/com/bobocode/fp/PrimeNumbers.java
@@ -1,10 +1,13 @@
package com.bobocode.fp;
import com.bobocode.util.ExerciseNotCompletedException;
+import com.google.common.math.IntMath;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.IntConsumer;
+import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
@@ -30,7 +33,8 @@ private PrimeNumbers() {
* @return an infinite int stream of prime numbers
*/
public static IntStream stream() {
- throw new ExerciseNotCompletedException(); // todo: create an infinite stream of ints, then filter prime numbs
+ // todo: create an infinite stream of ints, then filter prime numbs
+ return IntStream.iterate(0,i->i+1).filter(IntMath::isPrime);
}
/**
@@ -40,7 +44,8 @@ public static IntStream stream() {
* @return an int stream of prime numbers with a specified size
*/
public static IntStream stream(int size) {
- throw new ExerciseNotCompletedException(); // todo: use the prev to generate a stream method but limit its size
+ // todo: use the prev to generate a stream method but limit its size
+ return stream().limit(size);
}
/**
@@ -51,7 +56,8 @@ public static IntStream stream(int size) {
* @return the sum of n prime numbers
*/
public static int sum(int n) {
- throw new ExerciseNotCompletedException(); // todo: use prev method and calculate the sum
+ // todo: use prev method and calculate the sum
+ return stream().limit(n).sum();
}
@@ -61,7 +67,8 @@ public static int sum(int n) {
* @return a list of collected prime numbers
*/
public static List list(int n) {
- throw new ExerciseNotCompletedException(); // todo: collect prime numbers into the list
+ // todo: collect prime numbers into the list
+ return stream().limit(n).boxed().collect(Collectors.toList());
}
/**
@@ -71,7 +78,8 @@ public static List list(int n) {
* @param consumer a logic that should be applied to the found prime number
*/
public static void processByIndex(int idx, IntConsumer consumer) {
- throw new ExerciseNotCompletedException(); // todo: find an element in the stream by index and process it
+ // todo: find an element in the stream by index and process it
+ stream().skip(idx).findFirst().ifPresent(consumer);
}
/**
@@ -85,6 +93,10 @@ public static void processByIndex(int idx, IntConsumer consumer) {
* @return a map with prime number grouped by the amount of digits
*/
public static Map> groupByAmountOfDigits(int n) {
- throw new ExerciseNotCompletedException(); // todo: group n prime numbers by the amount of digits
+ // todo: group n prime numbers by the amount of digits
+ return stream()
+ .limit(n)
+ .boxed()
+ .collect(Collectors.groupingBy(num -> String.valueOf(num).length()));
}
}
diff --git a/java-fundamentals-util/src/main/java/com/bobocode/model/Account.java b/java-fundamentals-util/src/main/java/com/bobocode/model/Account.java
index c41a89872..0b5768123 100644
--- a/java-fundamentals-util/src/main/java/com/bobocode/model/Account.java
+++ b/java-fundamentals-util/src/main/java/com/bobocode/model/Account.java
@@ -20,5 +20,71 @@ public class Account {
private Sex sex;
private LocalDate creationDate;
private BigDecimal balance = BigDecimal.ZERO;
+
+ public BigDecimal getBalance() {
+ return balance;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public LocalDate getBirthday() {
+ return birthday;
+ }
+
+ public LocalDate getCreationDate() {
+ return creationDate;
+ }
+
+ public Sex getSex() {
+ return sex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setBalance(BigDecimal balance) {
+ this.balance = balance;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public void setBirthday(LocalDate birthday) {
+ this.birthday = birthday;
+ }
+
+ public void setCreationDate(LocalDate creationDate) {
+ this.creationDate = creationDate;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public void setSex(Sex sex) {
+ this.sex = sex;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+
}