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..5a49d0717 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 @@ -6,9 +6,15 @@ import java.io.Serializable; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +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 @@ -33,8 +39,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 +51,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,8 +65,10 @@ 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 +78,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 +90,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(getMax()) > 0) { + max = val; + } } - public Object getMax() { + public T getMax() { return max; } } @@ -97,8 +107,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 & Serializable> { // todo: make it generic + void process(T obj); } /** @@ -108,10 +118,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 +130,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 +143,11 @@ 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 + default int compareTo(Collection other) { + return Integer.compare(this.size(), other.size()); + } } /** @@ -147,7 +161,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 +174,8 @@ 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(entity -> entity.getUuid() == null); } /** @@ -173,8 +187,8 @@ 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 collection, Predicate validationPredicate) { + return collection.stream().allMatch(validationPredicate); } /** @@ -187,8 +201,10 @@ 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(List entities, T targetEntity) { + return entities.stream() + .filter(entity -> entity.getUuid().equals(targetEntity.getUuid())) + .count() > 1; } /** @@ -201,6 +217,18 @@ 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); + return StreamSupport.stream(elements.spliterator(), false) + .max(comparator); + + } /** * findMostRecentlyCreatedEntity is a generic util method that accepts a collection of entities and returns the @@ -215,6 +243,9 @@ 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, CREATED_ON_COMPARATOR).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 @@ -226,10 +257,27 @@ 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 + + //#1 Collections.swap(elements, i, j); + + +// // #2 OR Swap elements manually +// List rawList = (List) elements; +// Object temp = rawList.get(i); +// rawList.set(i, rawList.get(j)); +// rawList.set(j, temp); + + swapHelper(elements, i, j); + } + public 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-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..d60f046c8 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,7 +1,11 @@ package com.bobocode.basics; +import java.util.Comparator; +import java.util.HashMap; import java.util.Map; +import static java.util.Comparator.naturalOrder; + /** * {@link HeterogeneousMaxHolder} is a multi-type container that holds maximum values per each type. It's kind of a * key/value map, where the key is a type and the value is the maximum among all values of this type that were put. @@ -14,8 +18,8 @@ * * @author Taras Boychuk */ -public class HeterogeneousMaxHolder { - +public class HeterogeneousMaxHolder { + private static Map, Object> maxValueMap = 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,6 +35,9 @@ public class HeterogeneousMaxHolder { * @return a smaller value among the provided value and the current maximum */ // todo: implement a method according to javadoc + public static > T put(Class key, T value) { + return put(key, value, naturalOrder()); + } /** * An overloaded method put implements the same logic using a custom comparator. A given comparator is wrapped with @@ -45,7 +52,14 @@ public class HeterogeneousMaxHolder { * @return a smaller value among the provided value and the current maximum */ // todo: implement a method according to javadoc - + public static T put(Class key, T value, Comparator comparator) { + comparator = Comparator.nullsFirst(comparator); + T currentMax = key.cast( maxValueMap.get(key)); + if (comparator.compare(value, currentMax) > 0) { + return key.cast( maxValueMap.put(key, value)) ; + } + 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 +68,8 @@ public class HeterogeneousMaxHolder { * @return current max value or null */ // todo: implement a method according to javadoc + + public static T getMax(Class key) { + return key.cast( maxValueMap.get(key)); + } } 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..424606343 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,5 +1,6 @@ package com.bobocode.oop.data; +import com.bobocode.oop.service.Flights; import com.bobocode.util.ExerciseNotCompletedException; import java.util.HashSet; @@ -12,7 +13,7 @@ * 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<>(); /** @@ -22,7 +23,7 @@ public class FlightDao { * @return {@code true} if a flight number was stored, {@code false} otherwise */ public boolean register(String flightNumber) { - throw new ExerciseNotCompletedException();// todo: implement this method + return flights.add(flightNumber); } /** @@ -31,7 +32,6 @@ public boolean register(String flightNumber) { * @return a set of flight numbers */ 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..5c9c2b3c0 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,5 +1,6 @@ package com.bobocode.oop.factory; +import com.bobocode.oop.data.FlightDao; import com.bobocode.oop.service.FlightService; import com.bobocode.util.ExerciseNotCompletedException; @@ -10,12 +11,14 @@ */ 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..df699fc95 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,12 @@ package com.bobocode.oop.service; +import com.bobocode.oop.data.FlightDao; import com.bobocode.util.ExerciseNotCompletedException; import java.util.List; +import java.util.Set; + +import static java.util.stream.Collectors.toList; /** * {@link FlightService} provides an API that allows to manage flight numbers @@ -12,6 +16,12 @@ */ public class FlightService { + private Flights flights; + + public FlightService(Flights flights) { + this.flights = flights; + } + /** * Adds a new flight number * @@ -19,7 +29,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 +39,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(flightNum -> flightNum.toUpperCase().contains(query.toUpperCase())) + .collect(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..8396774b7 --- /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.List; +import java.util.Set; + +public interface Flights { + boolean register(String flightNumber); + Set findAll(); +} 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..827da8c14 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,6 +29,11 @@ public static FunctionMap intFunctionMap() { FunctionMap intFunctionMap = new FunctionMap<>(); // todo: according to the javadoc add functions using lambda expression + intFunctionMap.addFunction("abs", Math::abs); + intFunctionMap.addFunction("sgn", e -> (int) Math.signum(e)); + intFunctionMap.addFunction("increment", Math::incrementExact); + intFunctionMap.addFunction("decrement", Math::decrementExact); + intFunctionMap.addFunction("square", e -> e * e); 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..298603784 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,11 @@ 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(e -> e * e).sum(); +// int sumOfSquares = 0; +// for (int i = startInclusive; i <= endInclusive; i++) { +// sumOfSquares += i * i; +// } +// return sumOfSquares; } } 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..48def33f1 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,7 +5,9 @@ import java.math.BigDecimal; import java.util.Comparator; import java.util.Map; +import java.util.Random; import java.util.function.*; +import java.util.stream.IntStream; /** * {@link CrazyLambdas} is an exercise class. Each method returns a functional interface and it should be implemented @@ -27,7 +29,7 @@ public class CrazyLambdas { * @return a string supplier */ public static Supplier helloSupplier() { - throw new ExerciseNotCompletedException(); + return () -> "Hello"; } /** @@ -36,7 +38,7 @@ public static Supplier helloSupplier() { * @return a string predicate */ public static Predicate isEmptyPredicate() { - throw new ExerciseNotCompletedException(); + return String::isEmpty; } /** @@ -46,7 +48,7 @@ public static Predicate isEmptyPredicate() { * @return function that repeats Strings */ public static BiFunction stringMultiplier() { - throw new ExerciseNotCompletedException(); + return String::repeat; } /** @@ -56,7 +58,7 @@ public static BiFunction stringMultiplier() { * @return function that converts adds dollar sign */ public static Function toDollarStringFunction() { - throw new ExerciseNotCompletedException(); + return e -> "$" + e.toString(); } /** @@ -68,7 +70,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 +79,7 @@ public static Predicate lengthInRangePredicate(int min, int max) { * @return int supplier */ public static IntSupplier randomIntSupplier() { - throw new ExerciseNotCompletedException(); + return () -> new Random().nextInt(); } @@ -87,7 +89,7 @@ public static IntSupplier randomIntSupplier() { * @return int operation */ public static IntUnaryOperator boundedRandomIntSupplier() { - throw new ExerciseNotCompletedException(); + return bound -> new Random().nextInt(bound); } /** @@ -96,7 +98,7 @@ public static IntUnaryOperator boundedRandomIntSupplier() { * @return square operation */ public static IntUnaryOperator intSquareOperation() { - throw new ExerciseNotCompletedException(); + return number -> number * number; } /** @@ -105,7 +107,7 @@ public static IntUnaryOperator intSquareOperation() { * @return binary sum operation */ public static LongBinaryOperator longSumOperation() { - throw new ExerciseNotCompletedException(); + return Long::sum; } /** @@ -114,7 +116,7 @@ public static LongBinaryOperator longSumOperation() { * @return string to int converter */ public static ToIntFunction stringToIntConverter() { - throw new ExerciseNotCompletedException(); + return Integer::valueOf; } /** @@ -125,7 +127,7 @@ public static ToIntFunction stringToIntConverter() { * @return a function supplier */ public static Supplier nMultiplyFunctionSupplier(int n) { - throw new ExerciseNotCompletedException(); + return () -> e -> n * e; } /** @@ -134,7 +136,7 @@ public static Supplier nMultiplyFunctionSupplier(int n) { * @return function that composes functions with trim() function */ public static UnaryOperator> composeWithTrimFunction() { - throw new ExerciseNotCompletedException(); + return stringStringFunction -> stringStringFunction.compose(String::trim); } /** @@ -145,7 +147,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 +160,7 @@ public static Supplier runningThreadSupplier(Runnable runnable) { * @return a runnable consumer */ public static Consumer newThreadRunnableConsumer() { - throw new ExerciseNotCompletedException(); + return runnable -> new Thread(runnable).start(); } /** @@ -164,7 +170,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 +187,8 @@ 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 (intUnaryOperator, intPredicate) -> value -> intPredicate.test(value) + ? intUnaryOperator.applyAsInt(value) : value; } /** @@ -188,7 +199,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 (stringIntUnaryOperatorMap, s) -> stringIntUnaryOperatorMap.getOrDefault(s, IntUnaryOperator.identity()); } /** @@ -206,7 +217,11 @@ public static BiFunction, String, IntUnaryOperator * @return a comparator instance */ public static > Comparator comparing(Function mapper) { - throw new ExerciseNotCompletedException(); + return (o1, o2) -> { + U value1 = mapper.apply(o1); + U value2 = mapper.apply(o2); + return value1.compareTo(value2); + }; } /** @@ -226,7 +241,15 @@ public static > Comparator comparing(Funct */ public static > Comparator thenComparing( Comparator comparator, Function mapper) { - throw new ExerciseNotCompletedException(); + return (o1, o2) -> { + int result = comparator.compare(o1, o2); + if (result == 0) { + U value1 = mapper.apply(o1); + U value2 = mapper.apply(o2); + result = value1.compareTo(value2); + } + return result; + }; } /** @@ -235,7 +258,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..235edbce5 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,5 +1,6 @@ package com.bobocode.fp; +import com.bobocode.fp.exception.EntityNotFoundException; import com.bobocode.model.Account; import com.bobocode.util.ExerciseNotCompletedException; import lombok.AllArgsConstructor; @@ -7,6 +8,14 @@ import java.math.BigDecimal; import java.time.Month; import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.groupingBy; /** * {@link CrazyStreams} is an exercise class. Each method represent some operation with a collection of accounts that @@ -30,7 +39,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 +49,7 @@ public Optional findRichestPerson() { * @return a list of accounts */ public List findAccountsByBirthdayMonth(Month birthdayMonth) { - throw new ExerciseNotCompletedException(); + return accounts.stream().filter(a -> a.getBirthday().getMonth() == birthdayMonth).toList(); } /** @@ -50,7 +59,7 @@ 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(a -> a.getSex().name().equals("MALE"))); } /** @@ -60,7 +69,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(a -> a.getEmail().split("@")[1])); } /** @@ -69,7 +78,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(a -> Math.addExact(a.getFirstName().length(), a.getLastName().length())).sum(); } /** @@ -78,7 +87,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 +96,10 @@ 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 account) -> account.getFirstName()) + .thenComparing(Comparator.comparing(Account::getLastName))) + .toList(); } /** @@ -97,7 +109,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(a -> a.getEmail().contains(emailDomain)); } /** @@ -108,7 +120,11 @@ public boolean containsAccountWithEmailDomain(String emailDomain) { * @return account balance */ public BigDecimal getBalanceByEmail(String email) { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .filter(a -> a.getEmail().equals(email)) + .findAny() + .orElseThrow(() -> new EntityNotFoundException(String.format("Cannot find Account by email=%s", email))) + .getBalance(); } /** @@ -117,7 +133,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), a -> a)); } /** @@ -128,7 +144,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(a -> a.getCreationDate().getYear() == year) + .collect(Collectors.toMap((Account::getEmail), (Account::getBalance))); } /** @@ -138,7 +156,11 @@ 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 +170,10 @@ 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( + a -> a.getBirthday().getMonth(), + Collectors.mapping(Account::getFirstName, Collectors.joining(", ")))); } /** @@ -158,7 +183,9 @@ 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(a -> a.getCreationDate().getMonth(), + Collectors.mapping(Account::getBalance, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)))); } /** @@ -168,7 +195,9 @@ 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() + .flatMap(a -> a.getFirstName().chars().mapToObj(c -> (char) c)) + .collect(Collectors.groupingBy(c -> c, Collectors.counting())); } /** @@ -179,7 +208,19 @@ 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() + .flatMap(a-> Stream.of(a.getFirstName(), a.getLastName())) + .filter(name -> name.length() >= nameLengthBound) + .map(String::toLowerCase) + .flatMapToInt(String::chars) + .mapToObj(c -> (char) c) + .collect(groupingBy(identity(), Collectors.counting())); + +// return accounts.stream() +// .filter(a -> (a.getFirstName().length() + a.getLastName().length()) >= nameLengthBound) +// .flatMap(a -> (a.getFirstName() + a.getLastName()).toLowerCase().chars().mapToObj(c -> (char) c)) +// .collect(Collectors.groupingBy(c -> c, Collectors.counting())); + } } diff --git a/lesson-demo/pom.xml b/lesson-demo/pom.xml index 0bd7ccdcf..e32b6b7b5 100644 --- a/lesson-demo/pom.xml +++ b/lesson-demo/pom.xml @@ -17,6 +17,13 @@ java-fundamentals-util 1.0-SNAPSHOT + + org.json + json + 20231013 + + + \ No newline at end of file diff --git a/lesson-demo/src/main/java/com/bobocode/DemoApp.java b/lesson-demo/src/main/java/com/bobocode/DemoApp.java index f27749017..c92ddfb30 100644 --- a/lesson-demo/src/main/java/com/bobocode/DemoApp.java +++ b/lesson-demo/src/main/java/com/bobocode/DemoApp.java @@ -1,6 +1,63 @@ package com.bobocode; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.IntBinaryOperator; +import java.util.function.Supplier; + public class DemoApp { public static void main(String[] args) { +// Function + List numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + List result1 = convert(numbers, number -> number * 2); + System.out.println(result1); +// IntBinaryOperator + System.out.println(convert(1, 1, Integer::sum)); +// Consumer + print("Consumer", System.out::println); + +// Supplier + System.out.println(getObject(() -> "Supplier")); +// BiFunction + BiFunction stringConcatenator = (str1, str2) -> str1 + str2; + System.out.println(convert("first", "second", stringConcatenator)); + + // quize + // Object o = () -> {System.out.println("Tricky example"); }; // will not compile + Runnable trickyExample = () -> { + System.out.println("Tricky example"); + }; + + + + } +// Function + public static List convert(List list, Function function){ + + List result = new ArrayList<>(); + for (T t : list) { + result.add(function.apply(t)); + } + return result; + } + + // IntBinaryOperator + public static int convert(int number, int number2, IntBinaryOperator function){ + return function.applyAsInt(number, number2); + } + // Consumer + public static void print(T string, Consumer consumer) { + consumer.accept(string); + } + // Supplier + public static T getObject(Supplier supplier) { + return supplier.get(); + } + // BiFunction + public static R convert(T t, U u, BiFunction function) { + return function.apply(t, u); } }