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/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..7de57d4e8 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 @@ -28,7 +28,12 @@ private Functions() { 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", 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..c973d5849 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,9 @@ import com.bobocode.fp.exception.InvalidRangeException; +import java.util.stream.IntStream; +import java.util.stream.Stream; + /** * 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 @@ -25,11 +28,8 @@ static int calculateSumOfSquaresInRange(int startInclusive, int endInclusive) { throw new InvalidRangeException(); } - // 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(i -> i * i) + .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 c836ad51a..d89fb7bab 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,10 @@ import java.math.BigDecimal; import java.util.Comparator; import java.util.Map; +import java.util.Random; import java.util.function.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * {@link CrazyLambdas} is an exercise class. Each method returns a functional interface and it should be implemented @@ -20,14 +23,14 @@ * @author Taras Boychuk */ public class CrazyLambdas { - + private static Random random = new Random(); /** * Returns {@link Supplier} that always supply "Hello" * * @return a string supplier */ public static Supplier helloSupplier() { - throw new ExerciseNotCompletedException(); + return () -> "Hello"; } /** @@ -36,7 +39,8 @@ public static Supplier helloSupplier() { * @return a string predicate */ public static Predicate isEmptyPredicate() { - throw new ExerciseNotCompletedException(); + + return String::isEmpty; } /** @@ -46,7 +50,9 @@ public static Predicate isEmptyPredicate() { * @return function that repeats Strings */ public static BiFunction stringMultiplier() { - throw new ExerciseNotCompletedException(); + return (str,inter)-> Stream.iterate(str, x->x) + .limit(inter) + .collect(Collectors.joining("")); } /** @@ -56,7 +62,7 @@ public static BiFunction stringMultiplier() { * @return function that converts adds dollar sign */ public static Function toDollarStringFunction() { - throw new ExerciseNotCompletedException(); + return dec-> "$" + dec.toString(); } /** @@ -68,7 +74,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 +83,7 @@ public static Predicate lengthInRangePredicate(int min, int max) { * @return int supplier */ public static IntSupplier randomIntSupplier() { - throw new ExerciseNotCompletedException(); + return random::nextInt; } @@ -87,7 +93,7 @@ public static IntSupplier randomIntSupplier() { * @return int operation */ public static IntUnaryOperator boundedRandomIntSupplier() { - throw new ExerciseNotCompletedException(); + return inter -> random.nextInt(inter); } /** @@ -96,7 +102,7 @@ public static IntUnaryOperator boundedRandomIntSupplier() { * @return square operation */ public static IntUnaryOperator intSquareOperation() { - throw new ExerciseNotCompletedException(); + return inter -> inter * inter; } /** @@ -105,7 +111,7 @@ public static IntUnaryOperator intSquareOperation() { * @return binary sum operation */ public static LongBinaryOperator longSumOperation() { - throw new ExerciseNotCompletedException(); + return Long::sum; } /** @@ -114,7 +120,7 @@ public static LongBinaryOperator longSumOperation() { * @return string to int converter */ public static ToIntFunction stringToIntConverter() { - throw new ExerciseNotCompletedException(); + return Integer::parseInt; } /** @@ -125,7 +131,7 @@ public static ToIntFunction stringToIntConverter() { * @return a function supplier */ public static Supplier nMultiplyFunctionSupplier(int n) { - throw new ExerciseNotCompletedException(); + return ()-> x-> n * x; } /** @@ -134,7 +140,7 @@ public static Supplier nMultiplyFunctionSupplier(int n) { * @return function that composes functions with trim() function */ public static UnaryOperator> composeWithTrimFunction() { - throw new ExerciseNotCompletedException(); + return strFunction -> strFunction.compose(String::trim); } /** @@ -145,7 +151,11 @@ public static UnaryOperator> composeWithTrimFunction() * @return a thread supplier */ public static Supplier runningThreadSupplier(Runnable runnable) { - throw new ExerciseNotCompletedException(); + return () -> { + Thread t = new Thread(runnable); + t.start(); + return t; + }; } /** @@ -154,7 +164,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 +174,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 t = new Thread(runnable); + t.start(); + return t; + }; } /** @@ -177,7 +191,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 +202,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 +220,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 +240,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 +255,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 e04e8b582..c3ccefdc7 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,19 @@ package com.bobocode.fp; import com.bobocode.model.Account; +import com.bobocode.model.Sex; +import com.bobocode.fp.exception.EntityNotFoundException; import com.bobocode.util.ExerciseNotCompletedException; import lombok.AllArgsConstructor; import java.math.BigDecimal; import java.time.Month; import java.util.*; +import java.util.stream.Stream; + +import static java.util.Comparator.comparing; +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.*; /** * {@link CrazyStreams} is an exercise class. Each method represent some operation with a collection of accounts that @@ -30,7 +37,8 @@ public class CrazyStreams { * @return account with max balance wrapped with optional */ public Optional findRichestPerson() { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .max(comparing(Account::getBalance)); } /** @@ -40,7 +48,9 @@ public Optional findRichestPerson() { * @return a list of accounts */ public List findAccountsByBirthdayMonth(Month birthdayMonth) { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .filter(a -> a.getBirthday().getMonth().equals(birthdayMonth)) + .collect(toList()); } /** @@ -50,7 +60,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(partitioningBy(a -> a.getSex().equals(Sex.MALE))); } /** @@ -60,7 +71,8 @@ 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(groupingBy(a -> a.getEmail().split("@")[1])); } /** @@ -69,7 +81,9 @@ 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 -> a.getFirstName().length() + a.getLastName().length()) + .sum(); } /** @@ -78,7 +92,9 @@ 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 +103,10 @@ public BigDecimal calculateTotalBalance() { * @return list of accounts sorted by first and last names */ public List sortByFirstAndLastNames() { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .sorted(comparing(Account::getFirstName) + .thenComparing(Account::getLastName)) + .collect(toList()); } /** @@ -97,7 +116,9 @@ 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() + .map(Account::getEmail) + .anyMatch(email -> email.split("@")[1].equals(emailDomain)); } /** @@ -108,7 +129,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)) + .findFirst() + .map(Account::getBalance) + .orElseThrow(() -> new EntityNotFoundException(String.format("Cannot find Account by email=%s", email))); } /** @@ -117,7 +142,8 @@ public BigDecimal getBalanceByEmail(String email) { * @return map of accounts by its ids */ public Map collectAccountsById() { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .collect(toMap(Account::getId, identity())); } /** @@ -128,17 +154,20 @@ 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(toMap(Account::getEmail, Account::getBalance)); } /** * Returns a {@link Map} where key is {@link Account#lastName} and values is a {@link Set} that contains first names * of all accounts with a specific last name. * - * @return a map where key is a last name and value is a set of first names + * @return a map where key is a first name and value is a set of first names */ public Map> groupFirstNamesByLastNames() { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .collect(groupingBy(Account::getLastName, mapping(Account::getFirstName, toSet()))); } /** @@ -148,7 +177,9 @@ 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(groupingBy(a -> a.getBirthday().getMonth(), + mapping(Account::getFirstName, joining(", ")))); } /** @@ -158,7 +189,10 @@ 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(groupingBy(a -> a.getCreationDate().getMonth(), + mapping(Account::getBalance, + reducing(BigDecimal.ZERO, BigDecimal::add)))); } /** @@ -168,7 +202,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(groupingBy(identity(), counting())); } /** @@ -179,8 +217,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() + .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(), 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 d7a273f44..518f20837 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,6 +12,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.math.BigDecimal; +import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.OptionalDouble; @@ -37,7 +38,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 +48,8 @@ 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 +59,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 +71,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 +82,7 @@ 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 +93,7 @@ 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 +103,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 +115,7 @@ 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 +125,7 @@ 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 +137,8 @@ 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().split("@")[1].equals("gmail.com")); } /** @@ -147,7 +151,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 +164,8 @@ 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,10 @@ public static Account getAccountWithMaxBalance(List accounts) { * @return the lowest balance values */ public static OptionalDouble findMinBalanceValue(List accounts) { - throw new ExerciseNotCompletedException(); + return accounts.stream() + .map(Account::getBalance) + .mapToDouble(BigDecimal::doubleValue) + .min(); } /** @@ -178,7 +188,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 +200,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(); } } 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..925c7f97a 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 @@ -7,6 +7,9 @@ import java.util.function.IntConsumer; import java.util.stream.IntStream; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; + /** * {@link PrimeNumbers} provides an API to work with prime numbers. The implementation is based on the * {@link java.util.stream.IntStream} of prime numbers. That stream is used in all public methods on this class. @@ -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 + return IntStream.iterate(2, i -> i+1) + .filter(PrimeNumbers::isPrime); } /** @@ -40,7 +44,7 @@ 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 + return stream().limit(size); } /** @@ -51,7 +55,7 @@ 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 + return stream(n).sum(); } @@ -61,7 +65,9 @@ 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 + return stream(n) + .boxed() + .toList(); } /** @@ -71,7 +77,10 @@ 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 + stream(idx + 1) + .skip(idx) + .findAny() + .ifPresent(consumer); } /** @@ -85,6 +94,12 @@ 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 + return stream(n) + .boxed() + .collect(groupingBy(x -> (int) (Math.log10(x) + 1))); + } + private static boolean isPrime(int n) { + return (n != 1) && IntStream.range(2, n) + .noneMatch(i -> n % i == 0); } }