diff --git a/core-java-modules/core-java-8/.gitignore b/core-java-modules/core-java-8/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/core-java-modules/core-java-8/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/core-java-modules/core-java-8/README.md b/core-java-modules/core-java-8/README.md new file mode 100644 index 0000000000..72bdafe5fa --- /dev/null +++ b/core-java-modules/core-java-8/README.md @@ -0,0 +1,15 @@ +## Core Java 8 + +This module contains articles about Java 8 core features + +### Relevant Articles: +- [New Features in Java 8](https://www.baeldung.com/java-8-new-features) +- [Guide to Java 8 groupingBy Collector](https://www.baeldung.com/java-groupingby-collector) +- [Strategy Design Pattern in Java 8](https://www.baeldung.com/java-strategy-pattern) +- [Guide to Java 8 Comparator.comparing()](https://www.baeldung.com/java-8-comparator-comparing) +- [Guide to the Java 8 forEach](https://www.baeldung.com/foreach-java) +- [Introduction to Spliterator in Java](https://www.baeldung.com/java-spliterator) +- [Finding Min/Max in an Array with Java](https://www.baeldung.com/java-array-min-max) +- [Internationalization and Localization in Java 8](https://www.baeldung.com/java-8-localization) +- [Generalized Target-Type Inference in Java](https://www.baeldung.com/java-generalized-target-type-inference) +- [[More -->]](/core-java-modules/core-java-8-2) diff --git a/core-java-modules/core-java-8/pom.xml b/core-java-modules/core-java-8/pom.xml new file mode 100644 index 0000000000..c5ffa6e8ec --- /dev/null +++ b/core-java-modules/core-java-8/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + core-java-8 + 0.1.0-SNAPSHOT + core-java-8 + jar + + + com.ossez.core-java-modules + core-java-modules + 0.0.2-SNAPSHOT + + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + core-java-8 + + + src/main/resources + true + + + + + + + 4.1 + + 3.6.1 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/aspect/ChangeCallsToCurrentTimeInMillisMethod.aj b/core-java-modules/core-java-8/src/main/java/com/ossez/aspect/ChangeCallsToCurrentTimeInMillisMethod.aj new file mode 100644 index 0000000000..b28bebfdaf --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/aspect/ChangeCallsToCurrentTimeInMillisMethod.aj @@ -0,0 +1,9 @@ +package com.baeldung.aspect; + +public aspect ChangeCallsToCurrentTimeInMillisMethod { + long around(): + call(public static native long java.lang.System.currentTimeMillis()) + && within(user.code.base.pckg.*) { + return 0; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/Address.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/Address.java new file mode 100644 index 0000000000..8f6cd17e26 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/Address.java @@ -0,0 +1,14 @@ +package com.ossez.java_8_features; + +public class Address { + + private String street; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/CustomException.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/CustomException.java new file mode 100644 index 0000000000..5fb2a527de --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/CustomException.java @@ -0,0 +1,4 @@ +package com.ossez.java_8_features; + +public class CustomException extends RuntimeException { +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/OptionalAddress.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/OptionalAddress.java new file mode 100644 index 0000000000..7a17de1079 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/OptionalAddress.java @@ -0,0 +1,16 @@ +package com.ossez.java_8_features; + +import java.util.Optional; + +public class OptionalAddress { + + private String street; + + public Optional getStreet() { + return Optional.ofNullable(street); + } + + public void setStreet(String street) { + this.street = street; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/OptionalUser.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/OptionalUser.java new file mode 100644 index 0000000000..ba519770ff --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/OptionalUser.java @@ -0,0 +1,16 @@ +package com.ossez.java_8_features; + +import java.util.Optional; + +public class OptionalUser { + + private OptionalAddress address; + + public Optional getAddress() { + return Optional.of(address); + } + + public void setAddress(OptionalAddress address) { + this.address = address; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/User.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/User.java new file mode 100644 index 0000000000..c63cc2c956 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/User.java @@ -0,0 +1,40 @@ +package com.ossez.java_8_features; + +import java.util.Optional; + +public class User { + + private String name; + + private Address address; + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public User() { + } + + public User(String name) { + this.name = name; + } + + public static boolean isRealUser(User user) { + return true; + } + + public String getOrThrow() { + String value = null; + Optional valueOpt = Optional.ofNullable(value); + String result = valueOpt.orElseThrow(CustomException::new).toUpperCase(); + return result; + } + + public boolean isLegalName(String name) { + return name.length() > 3 && name.length() < 16; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/Vehicle.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/Vehicle.java new file mode 100644 index 0000000000..110e8cc5e9 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/Vehicle.java @@ -0,0 +1,18 @@ +package com.ossez.java_8_features; + +public interface Vehicle { + + void moveTo(long altitude, long longitude); + + static String producer() { + return "N&F Vehicles"; + } + + default long[] startPosition() { + return new long[] { 23, 15 }; + } + + default String getOverview() { + return "ATV made by " + producer(); + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/VehicleImpl.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/VehicleImpl.java new file mode 100644 index 0000000000..4bd702534d --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/VehicleImpl.java @@ -0,0 +1,9 @@ +package com.ossez.java_8_features; + +public class VehicleImpl implements Vehicle { + + @Override + public void moveTo(long altitude, long longitude) { + // do nothing + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/BlogPost.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/BlogPost.java new file mode 100644 index 0000000000..44965f0ce2 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/BlogPost.java @@ -0,0 +1,36 @@ +package com.ossez.java_8_features.groupingby; + +public class BlogPost { + private String title; + private String author; + private BlogPostType type; + private int likes; + + public BlogPost(String title, String author, BlogPostType type, int likes) { + this.title = title; + this.author = author; + this.type = type; + this.likes = likes; + } + + public String getTitle() { + return title; + } + + public String getAuthor() { + return author; + } + + public BlogPostType getType() { + return type; + } + + public int getLikes() { + return likes; + } + + @Override + public String toString() { + return "BlogPost{" + "title='" + title + '\'' + ", type=" + type + ", likes=" + likes + '}'; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/BlogPostType.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/BlogPostType.java new file mode 100644 index 0000000000..3b8eeb3da5 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/BlogPostType.java @@ -0,0 +1,5 @@ +package com.ossez.java_8_features.groupingby; + +public enum BlogPostType { + NEWS, REVIEW, GUIDE +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/Tuple.java b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/Tuple.java new file mode 100644 index 0000000000..1761e2757a --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/java_8_features/groupingby/Tuple.java @@ -0,0 +1,41 @@ +package com.ossez.java_8_features.groupingby; + +import java.util.Objects; + +public class Tuple { + private final BlogPostType type; + private final String author; + + public Tuple(BlogPostType type, String author) { + this.type = type; + this.author = author; + } + + public BlogPostType getType() { + return type; + } + + public String getAuthor() { + return author; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Tuple tuple = (Tuple) o; + return type == tuple.type && author.equals(tuple.author); + } + + @Override + public int hashCode() { + return Objects.hash(type, author); + } + + @Override + public String toString() { + return "Tuple{" + "type=" + type + ", author='" + author + '\'' + '}'; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java b/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java new file mode 100644 index 0000000000..fb72c104ee --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java @@ -0,0 +1,19 @@ +package com.ossez.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.stream.Stream; +import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; + +public class NullSafeCollectionStreamsUsingCommonsEmptyIfNull { + + /** + * This method shows how to make a null safe stream from a collection through the use of + * emptyIfNull() method from Apache Commons CollectionUtils library + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return emptyIfNull(collection).stream(); + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java b/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java new file mode 100644 index 0000000000..7ab449f232 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java @@ -0,0 +1,21 @@ +package com.ossez.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Stream; + +public class NullSafeCollectionStreamsUsingJava8OptionalContainer { + + /** + * This method shows how to make a null safe stream from a collection through the use of + * Java SE 8’s Optional Container + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return Optional.ofNullable(collection) + .map(Collection::stream) + .orElseGet(Stream::empty); + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java b/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java new file mode 100644 index 0000000000..d06bd2e270 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java @@ -0,0 +1,20 @@ +package com.ossez.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.stream.Stream; + +public class NullSafeCollectionStreamsUsingNullDereferenceCheck { + + /** + * This method shows how to make a null safe stream from a collection through the use of a check + * to prevent null dereferences + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return collection == null ? Stream.empty() : collection.stream(); + } + + +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Article.java b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Article.java new file mode 100644 index 0000000000..99784cbfbe --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Article.java @@ -0,0 +1,44 @@ +package com.ossez.spliteratorAPI; + +import java.util.List; + +public class Article { + private List listOfAuthors; + private int id; + private String name; + + public Article(String name) { + this.name = name; + } + + public Article(List listOfAuthors, int id) { + super(); + this.listOfAuthors = listOfAuthors; + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public List getListOfAuthors() { + return listOfAuthors; + } + + public void setListOfAuthors(List listOfAuthors) { + this.listOfAuthors = listOfAuthors; + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Author.java b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Author.java new file mode 100644 index 0000000000..68f9ae21f2 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Author.java @@ -0,0 +1,33 @@ +package com.ossez.spliteratorAPI; + +public class Author { + private String name; + private int relatedArticleId; + + public Author(String name, int relatedArticleId) { + this.name = name; + this.relatedArticleId = relatedArticleId; + } + + public int getRelatedArticleId() { + return relatedArticleId; + } + + public void setRelatedArticleId(int relatedArticleId) { + this.relatedArticleId = relatedArticleId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "[name: " + name + ", relatedId: " + relatedArticleId + "]"; + } +} + diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Executor.java b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Executor.java new file mode 100644 index 0000000000..894bd5ba66 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Executor.java @@ -0,0 +1,19 @@ +package com.ossez.spliteratorAPI; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class Executor { + + public static int countAutors(Stream stream) { + RelatedAuthorCounter wordCounter = stream.reduce(new RelatedAuthorCounter(0, true), + RelatedAuthorCounter::accumulate, RelatedAuthorCounter::combine); + return wordCounter.getCounter(); + } + + public static List
generateElements() { + return Stream.generate(() -> new Article("Java")).limit(35000).collect(Collectors.toList()); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/RelatedAuthorCounter.java b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/RelatedAuthorCounter.java new file mode 100644 index 0000000000..f6bca6ac3e --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/RelatedAuthorCounter.java @@ -0,0 +1,27 @@ +package com.ossez.spliteratorAPI; + +public class RelatedAuthorCounter { + private final int counter; + private final boolean isRelated; + + public RelatedAuthorCounter(int counter, boolean isRelated) { + this.counter = counter; + this.isRelated = isRelated; + } + + public RelatedAuthorCounter accumulate(Author author) { + if (author.getRelatedArticleId() == 0) { + return isRelated ? this : new RelatedAuthorCounter(counter, true); + } else { + return isRelated ? new RelatedAuthorCounter(counter + 1, false) : this; + } + } + + public RelatedAuthorCounter combine(RelatedAuthorCounter RelatedAuthorCounter) { + return new RelatedAuthorCounter(counter + RelatedAuthorCounter.counter, RelatedAuthorCounter.isRelated); + } + + public int getCounter() { + return counter; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/RelatedAuthorSpliterator.java b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/RelatedAuthorSpliterator.java new file mode 100644 index 0000000000..239747f7a5 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/RelatedAuthorSpliterator.java @@ -0,0 +1,49 @@ +package com.ossez.spliteratorAPI; + +import java.util.List; +import java.util.Spliterator; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; + +public class RelatedAuthorSpliterator implements Spliterator { + private final List list; + AtomicInteger current = new AtomicInteger(); + + public RelatedAuthorSpliterator(List list) { + this.list = list; + } + + @Override + public boolean tryAdvance(Consumer action) { + + action.accept(list.get(current.getAndIncrement())); + return current.get() < list.size(); + } + + @Override + public Spliterator trySplit() { + int currentSize = list.size() - current.get(); + if (currentSize < 10) { + return null; + } + for (int splitPos = currentSize / 2 + current.intValue(); splitPos < list.size(); splitPos++) { + if (list.get(splitPos).getRelatedArticleId() == 0) { + Spliterator spliterator = new RelatedAuthorSpliterator(list.subList(current.get(), splitPos)); + current.set(splitPos); + return spliterator; + } + } + return null; + } + + @Override + public long estimateSize() { + return list.size() - current.get(); + } + + @Override + public int characteristics() { + return CONCURRENT; + } + +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Task.java b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Task.java new file mode 100644 index 0000000000..e4bff0efa7 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/spliteratorAPI/Task.java @@ -0,0 +1,27 @@ +package com.ossez.spliteratorAPI; + +import java.util.Spliterator; +import java.util.concurrent.Callable; + +public class Task implements Callable { + private Spliterator
spliterator; + private final static String SUFFIX = "- published by Baeldung"; + + public Task(Spliterator
spliterator) { + this.spliterator = spliterator; + } + + @Override + public String call() { + int current = 0; + while (spliterator.tryAdvance(article -> { + article.setName(article.getName() + .concat(SUFFIX)); + })) { + current++; + } + ; + return Thread.currentThread() + .getName() + ":" + current; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/ChristmasDiscounter.java b/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/ChristmasDiscounter.java new file mode 100644 index 0000000000..87532af1fd --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/ChristmasDiscounter.java @@ -0,0 +1,11 @@ +package com.ossez.strategy; + +import java.math.BigDecimal; + +public class ChristmasDiscounter implements Discounter { + + @Override + public BigDecimal apply(BigDecimal amount) { + return amount.multiply(BigDecimal.valueOf(0.9)); + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/Discounter.java b/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/Discounter.java new file mode 100644 index 0000000000..82e177638a --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/Discounter.java @@ -0,0 +1,23 @@ +package com.ossez.strategy; + +import java.math.BigDecimal; +import java.util.function.UnaryOperator; + +public interface Discounter extends UnaryOperator { + + default Discounter combine(Discounter after) { + return value -> after.apply(this.apply(value)); + } + + static Discounter christmas() { + return (amount) -> amount.multiply(BigDecimal.valueOf(0.9)); + } + + static Discounter newYear() { + return (amount) -> amount.multiply(BigDecimal.valueOf(0.8)); + } + + static Discounter easter() { + return (amount) -> amount.multiply(BigDecimal.valueOf(0.5)); + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/EasterDiscounter.java b/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/EasterDiscounter.java new file mode 100644 index 0000000000..32d1c4d69e --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/strategy/EasterDiscounter.java @@ -0,0 +1,11 @@ +package com.ossez.strategy; + +import java.math.BigDecimal; + +public class EasterDiscounter implements Discounter { + + @Override + public BigDecimal apply(BigDecimal amount) { + return amount.multiply(BigDecimal.valueOf(0.5)); + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/application/Application.java b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/application/Application.java new file mode 100644 index 0000000000..07a58b70b6 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/application/Application.java @@ -0,0 +1,63 @@ +package com.ossez.streamreduce.application; + +import com.ossez.streamreduce.entities.User; +import com.ossez.streamreduce.utilities.NumberUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Application { + + public static void main(String[] args) { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + int result1 = numbers.stream().reduce(0, (a, b) -> a + b); + System.out.println(result1); + + int result2 = numbers.stream().reduce(0, Integer::sum); + System.out.println(result2); + + List letters = Arrays.asList("a", "b", "c", "d", "e"); + String result3 = letters.stream().reduce("", (a, b) -> a + b); + System.out.println(result3); + + String result4 = letters.stream().reduce("", String::concat); + System.out.println(result4); + + String result5 = letters.stream().reduce("", (a, b) -> a.toUpperCase() + b.toUpperCase()); + System.out.println(result5); + + List users = Arrays.asList(new User("John", 30), new User("Julie", 35)); + int result6 = users.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); + System.out.println(result6); + + String result7 = letters.parallelStream().reduce("", String::concat); + System.out.println(result7); + + int result8 = users.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); + System.out.println(result8); + + List userList = new ArrayList<>(); + for (int i = 0; i <= 1000000; i++) { + userList.add(new User("John" + i, i)); + } + + long t1 = System.currentTimeMillis(); + int result9 = userList.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); + long t2 = System.currentTimeMillis(); + System.out.println(result9); + System.out.println("Sequential stream time: " + (t2 - t1) + "ms"); + + long t3 = System.currentTimeMillis(); + int result10 = userList.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); + long t4 = System.currentTimeMillis(); + System.out.println(result10); + System.out.println("Parallel stream time: " + (t4 - t3) + "ms"); + + int result11 = NumberUtils.divideListElements(numbers, 1); + System.out.println(result11); + + int result12 = NumberUtils.divideListElementsWithExtractedTryCatchBlock(numbers, 0); + System.out.println(result12); + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/Rating.java b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/Rating.java new file mode 100644 index 0000000000..a36371dde1 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/Rating.java @@ -0,0 +1,39 @@ +package com.ossez.streamreduce.entities; + +import java.util.ArrayList; +import java.util.List; + +public class Rating { + + double points; + List reviews = new ArrayList<>(); + + public Rating() {} + + public void add(Review review) { + reviews.add(review); + computeRating(); + } + + private double computeRating() { + double totalPoints = reviews.stream().map(Review::getPoints).reduce(0, Integer::sum); + this.points = totalPoints / reviews.size(); + return this.points; + } + + public static Rating average(Rating r1, Rating r2) { + Rating combined = new Rating(); + combined.reviews = new ArrayList<>(r1.reviews); + combined.reviews.addAll(r2.reviews); + combined.computeRating(); + return combined; + } + + public double getPoints() { + return points; + } + + public List getReviews() { + return reviews; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/Review.java b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/Review.java new file mode 100644 index 0000000000..3f63d00f98 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/Review.java @@ -0,0 +1,28 @@ +package com.ossez.streamreduce.entities; + +public class Review { + + int points; + String review; + + public Review(int points, String review) { + this.points = points; + this.review = review; + } + + public int getPoints() { + return points; + } + + public void setPoints(int points) { + this.points = points; + } + + public String getReview() { + return review; + } + + public void setReview(String review) { + this.review = review; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/User.java b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/User.java new file mode 100644 index 0000000000..949b9ef388 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/entities/User.java @@ -0,0 +1,30 @@ +package com.ossez.streamreduce.entities; + +public class User { + + private final String name; + private final int age; + private final Rating rating = new Rating(); + + public User(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public Rating getRating() { + return rating; + } + + @Override + public String toString() { + return "User{" + "name=" + name + ", age=" + age + '}'; + } +} diff --git a/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/utilities/NumberUtils.java b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/utilities/NumberUtils.java new file mode 100644 index 0000000000..b36c4b3554 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/java/com/ossez/streamreduce/utilities/NumberUtils.java @@ -0,0 +1,52 @@ +package com.ossez.streamreduce.utilities; + +import java.util.List; +import java.util.function.BiFunction; +import java.util.logging.Level; +import java.util.logging.Logger; + +public abstract class NumberUtils { + + private static final Logger LOGGER = Logger.getLogger(NumberUtils.class.getName()); + + public static int divideListElements(List values, Integer divider) { + return values.stream() + .reduce(0, (a, b) -> { + try { + return a / divider + b / divider; + } catch (ArithmeticException e) { + LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero"); + } + return 0; + }); + } + + public static int divideListElementsWithExtractedTryCatchBlock(List values, int divider) { + return values.stream().reduce(0, (a, b) -> divide(a, divider) + divide(b, divider)); + } + + public static int divideListElementsWithApplyFunctionMethod(List values, int divider) { + BiFunction division = (a, b) -> a / b; + return values.stream().reduce(0, (a, b) -> applyFunction(division, a, divider) + applyFunction(division, b, divider)); + } + + private static int divide(int value, int factor) { + int result = 0; + try { + result = value / factor; + } catch (ArithmeticException e) { + LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero"); + } + return result; + } + + private static int applyFunction(BiFunction function, int a, int b) { + try { + return function.apply(a, b); + } + catch(Exception e) { + LOGGER.log(Level.INFO, "Exception occurred!"); + } + return 0; + } +} diff --git a/core-java-modules/core-java-8/src/main/resources/logback.xml b/core-java-modules/core-java-8/src/main/resources/logback.xml new file mode 100644 index 0000000000..11032b47f4 --- /dev/null +++ b/core-java-modules/core-java-8/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/internationalization/DateFormatUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/internationalization/DateFormatUnitTest.java new file mode 100644 index 0000000000..2e7a140f5a --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/internationalization/DateFormatUnitTest.java @@ -0,0 +1,110 @@ +package com.ossez.internationalization; + +import org.junit.Assert; +import org.junit.Test; + +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; + +public class DateFormatUnitTest { + + @Test + public void givenGregorianCalendar_whenLocaleSpecificDateInstance_givenLanguageSpecificMonths() { + GregorianCalendar gregorianCalendar = new GregorianCalendar(2018, 1, 1, 10, 15, 20); + Date date = gregorianCalendar.getTime(); + + DateFormat itInstance = DateFormat.getDateInstance(DateFormat.FULL, Locale.ITALY); + DateFormat usInstance = DateFormat.getDateInstance(DateFormat.FULL, Locale.US); + + Assert.assertEquals("giovedì 1 febbraio 2018", itInstance.format(date)); + Assert.assertEquals("Thursday, February 1, 2018", usInstance.format(date)); + } + + @Test + public void givenGregorianCalendar_whenDateInstanceWithDifferentFormats_givenSpecificDateFormatting() { + GregorianCalendar gregorianCalendar = new GregorianCalendar(2018, 1, 1, 10, 15, 20); + Date date = gregorianCalendar.getTime(); + + DateFormat fullInstance = DateFormat.getDateInstance(DateFormat.FULL, Locale.ITALY); + DateFormat mediumInstance = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.ITALY); + + Assert.assertEquals("giovedì 1 febbraio 2018", fullInstance.format(date)); + Assert.assertEquals("1-feb-2018", mediumInstance.format(date)); + } + + @Test + public void givenGregorianCalendar_whenTimeInstanceWithDifferentFormats_givenSpecificTimeFormatting() { + GregorianCalendar gregorianCalendar = new GregorianCalendar(2018, 1, 1, 10, 15, 20); + gregorianCalendar.setTimeZone(TimeZone.getTimeZone("CET")); + TimeZone.setDefault(TimeZone.getTimeZone("CET")); + Date date = gregorianCalendar.getTime(); + + DateFormat fullInstance = DateFormat.getTimeInstance(DateFormat.FULL, Locale.ITALY); + DateFormat mediumInstance = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.ITALY); + + Assert.assertEquals("10.15.20 CET", fullInstance.format(date)); + Assert.assertEquals("10.15.20" , mediumInstance.format(date)); + } + + @Test + public void givenGregorianCalendar_whenDateTimeInstanceWithDifferentFormats_givenSpecificDateTimeFormatting() { + GregorianCalendar gregorianCalendar = new GregorianCalendar(2018, 1, 1, 10, 15, 20); + gregorianCalendar.setTimeZone(TimeZone.getTimeZone("CET")); + TimeZone.setDefault(TimeZone.getTimeZone("CET")); + Date date = gregorianCalendar.getTime(); + + DateFormat ffInstance = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ITALY); + DateFormat smInstance = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, Locale.ITALY); + + Assert.assertEquals("giovedì 1 febbraio 2018 10.15.20 CET", ffInstance.format(date)); + Assert.assertEquals("01/02/18 10.15.20", smInstance.format(date)); + } + + @Test + public void givenGregorianCalendar_whenLocaleSpecificDateTimeInstance_givenLocaleSpecificFormatting() { + GregorianCalendar gregorianCalendar = new GregorianCalendar(2018, 1, 1, 10, 15, 20); + gregorianCalendar.setTimeZone(TimeZone.getTimeZone("CET")); + TimeZone.setDefault(TimeZone.getTimeZone("CET")); + Date date = gregorianCalendar.getTime(); + + DateFormat itInstance = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ITALY); + DateFormat jpInstance = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.JAPAN); + + Assert.assertEquals("giovedì 1 febbraio 2018 10.15.20 CET", itInstance.format(date)); + Assert.assertEquals("2018年2月1日 10時15分20秒 CET", jpInstance.format(date)); + } + + @Test + public void givenGregorianCalendar_whenCustomizedSimpleDateFormat_thenSpecificMonthRepresentations() { + GregorianCalendar gregorianCalendar = new GregorianCalendar(2018, 1, 1, 10, 15, 20); + Date date = gregorianCalendar.getTime(); + Locale.setDefault(new Locale("pl", "PL")); + + SimpleDateFormat fullMonthDateFormat = new SimpleDateFormat("dd-MMMM-yyyy HH:mm:ss:SSS"); + SimpleDateFormat shortMonthsimpleDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss:SSS"); + + Assert.assertEquals("01-lutego-2018 10:15:20:000", fullMonthDateFormat.format(date)); + Assert.assertEquals("01-02-2018 10:15:20:000" , shortMonthsimpleDateFormat.format(date)); + } + + @Test + public void givenGregorianCalendar_whenCustomizedDateFormatSymbols_thenChangedDayNames() { + GregorianCalendar gregorianCalendar = new GregorianCalendar(2018, 1, 1, 10, 15, 20); + Date date = gregorianCalendar.getTime(); + Locale.setDefault(new Locale("pl", "PL")); + + DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(); + dateFormatSymbols.setWeekdays(new String[]{"A", "B", "C", "D", "E", "F", "G", "H"}); + SimpleDateFormat standardDateFormat = new SimpleDateFormat("EEEE-MMMM-yyyy HH:mm:ss:SSS"); + SimpleDateFormat newDaysDateFormat = new SimpleDateFormat("EEEE-MMMM-yyyy HH:mm:ss:SSS", dateFormatSymbols); + + Assert.assertEquals("czwartek-lutego-2018 10:15:20:000", standardDateFormat.format(date)); + Assert.assertEquals("F-lutego-2018 10:15:20:000", newDaysDateFormat.format(date)); + } + +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/internationalization/NumbersCurrenciesFormattingUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/internationalization/NumbersCurrenciesFormattingUnitTest.java new file mode 100644 index 0000000000..db59219d7f --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/internationalization/NumbersCurrenciesFormattingUnitTest.java @@ -0,0 +1,76 @@ +package com.ossez.internationalization; + +import org.junit.Assert; +import org.junit.Test; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.util.Currency; +import java.util.Locale; + +public class NumbersCurrenciesFormattingUnitTest { + + @Test + public void givenDifferentLocalesAndDoubleNumber_whenNumberInstance_thenDifferentOutput() { + Locale usLocale = Locale.US; + Locale plLocale = new Locale("pl", "PL"); + Locale deLocale = Locale.GERMANY; + double number = 102_300.456d; + + NumberFormat usNumberFormat = NumberFormat.getInstance(usLocale); + NumberFormat plNumberFormat = NumberFormat.getInstance(plLocale); + NumberFormat deNumberFormat = NumberFormat.getInstance(deLocale); + + Assert.assertEquals(usNumberFormat.format(number), "102,300.456"); + Assert.assertEquals(plNumberFormat.format(number), "102 300,456"); + Assert.assertEquals(deNumberFormat.format(number), "102.300,456"); + } + + @Test + public void givenDifferentLocalesAndDoubleAmount_whenCurrencyInstance_thenDifferentOutput() { + Locale usLocale = Locale.US; + Locale plLocale = new Locale("pl", "PL"); + Locale deLocale = Locale.GERMANY; + BigDecimal number = new BigDecimal(102_300.456d); + + NumberFormat usNumberFormat = NumberFormat.getCurrencyInstance(usLocale); + NumberFormat plNumberFormat = NumberFormat.getCurrencyInstance(plLocale); + NumberFormat deNumberFormat = NumberFormat.getCurrencyInstance(deLocale); + + Assert.assertEquals(usNumberFormat.format(number), "$102,300.46"); + Assert.assertEquals(plNumberFormat.format(number), "102 300,46 zł"); + Assert.assertEquals(deNumberFormat.format(number), "102.300,46 €"); + } + + @Test + public void givenLocaleAndNumber_whenSpecificDecimalFormat_thenSpecificOutput() { + Locale.setDefault(Locale.FRANCE); + BigDecimal number = new BigDecimal(102_300.456d); + + DecimalFormat zeroDecimalFormat = new DecimalFormat("000000000.0000"); + DecimalFormat hashDecimalFormat = new DecimalFormat("###,###.#"); + DecimalFormat dollarDecimalFormat = new DecimalFormat("$###,###.##"); + + Assert.assertEquals(zeroDecimalFormat.format(number), "000102300,4560"); + Assert.assertEquals(hashDecimalFormat.format(number), "102 300,5"); + Assert.assertEquals(dollarDecimalFormat.format(number), "$102 300,46"); + } + + @Test + public void givenLocaleAndNumber_whenSpecificDecimalFormatSymbols_thenSpecificOutput() { + Locale.setDefault(Locale.FRANCE); + BigDecimal number = new BigDecimal(102_300.456d); + + DecimalFormatSymbols decimalFormatSymbols = DecimalFormatSymbols.getInstance(); + decimalFormatSymbols.setGroupingSeparator('^'); + decimalFormatSymbols.setDecimalSeparator('@'); + DecimalFormat separatorsDecimalFormat = new DecimalFormat("$###,###.##"); + separatorsDecimalFormat.setGroupingSize(4); + separatorsDecimalFormat.setCurrency(Currency.getInstance(Locale.JAPAN)); + separatorsDecimalFormat.setDecimalFormatSymbols(decimalFormatSymbols); + + Assert.assertEquals(separatorsDecimalFormat.format(number), "$10^2300@46"); + } +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8DefaultStaticIntefaceMethodsUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8DefaultStaticIntefaceMethodsUnitTest.java new file mode 100644 index 0000000000..8a1b0705f5 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8DefaultStaticIntefaceMethodsUnitTest.java @@ -0,0 +1,27 @@ +package com.ossez.java8; + +import com.ossez.java_8_features.Vehicle; +import com.ossez.java_8_features.VehicleImpl; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class Java8DefaultStaticIntefaceMethodsUnitTest { + + @Test + public void callStaticInterfaceMethdosMethods_whenExpectedResults_thenCorrect() { + Vehicle vehicle = new VehicleImpl(); + String overview = vehicle.getOverview(); + long[] startPosition = vehicle.startPosition(); + + assertEquals(overview, "ATV made by N&F Vehicles"); + assertEquals(startPosition[0], 23); + assertEquals(startPosition[1], 15); + } + + @Test + public void callDefaultInterfaceMethods_whenExpectedResults_thenCorrect() { + String producer = Vehicle.producer(); + assertEquals(producer, "N&F Vehicles"); + } +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8MethodReferenceUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8MethodReferenceUnitTest.java new file mode 100644 index 0000000000..3f3fe24bbc --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8MethodReferenceUnitTest.java @@ -0,0 +1,67 @@ +package com.ossez.java8; + +import com.ossez.java_8_features.User; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class Java8MethodReferenceUnitTest { + + private List list; + + @Before + public void init() { + list = new ArrayList<>(); + list.add("One"); + list.add("OneAndOnly"); + list.add("Derek"); + list.add("Change"); + list.add("factory"); + list.add("justBefore"); + list.add("Italy"); + list.add("Italy"); + list.add("Thursday"); + list.add(""); + list.add(""); + } + + @Test + public void checkStaticMethodReferences_whenWork_thenCorrect() { + + List users = new ArrayList<>(); + users.add(new User()); + users.add(new User()); + boolean isReal = users.stream().anyMatch(u -> User.isRealUser(u)); + boolean isRealRef = users.stream().anyMatch(User::isRealUser); + assertTrue(isReal); + assertTrue(isRealRef); + } + + @Test + public void checkInstanceMethodReferences_whenWork_thenCorrect() { + User user = new User(); + boolean isLegalName = list.stream().anyMatch(user::isLegalName); + assertTrue(isLegalName); + } + + @Test + public void checkParticularTypeReferences_whenWork_thenCorrect() { + long count = list.stream().filter(String::isEmpty).count(); + assertEquals(count, 2); + } + + @Test + public void checkConstructorReferences_whenWork_thenCorrect() { + Stream stream = list.stream().map(User::new); + List userList = stream.collect(Collectors.toList()); + assertEquals(userList.size(), list.size()); + assertTrue(userList.get(0) instanceof User); + } +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8OptionalUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8OptionalUnitTest.java new file mode 100644 index 0000000000..9f408cf577 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/Java8OptionalUnitTest.java @@ -0,0 +1,116 @@ +package com.ossez.java8; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.junit.Before; +import org.junit.Test; + +import com.ossez.java_8_features.Address; +import com.ossez.java_8_features.CustomException; +import com.ossez.java_8_features.OptionalAddress; +import com.ossez.java_8_features.OptionalUser; +import com.ossez.java_8_features.User; + +public class Java8OptionalUnitTest { + + private List list; + + @Before + public void init() { + list = new ArrayList<>(); + list.add("One"); + list.add("OneAndOnly"); + list.add("Derek"); + list.add("Change"); + list.add("factory"); + list.add("justBefore"); + list.add("Italy"); + list.add("Italy"); + list.add("Thursday"); + list.add(""); + list.add(""); + } + + @Test + public void checkOptional_whenAsExpected_thenCorrect() { + Optional optionalEmpty = Optional.empty(); + assertFalse(optionalEmpty.isPresent()); + + String str = "value"; + Optional optional = Optional.of(str); + assertEquals(optional.get(), "value"); + + Optional optionalNullable = Optional.ofNullable(str); + Optional optionalNull = Optional.ofNullable(null); + assertEquals(optionalNullable.get(), "value"); + assertFalse(optionalNull.isPresent()); + + List listOpt = Optional.of(list).orElse(new ArrayList<>()); + List listNull = null; + List listOptNull = Optional.ofNullable(listNull).orElse(new ArrayList<>()); + assertTrue(listOpt == list); + assertTrue(listOptNull.isEmpty()); + + Optional user = Optional.ofNullable(getUser()); + String result = user.map(User::getAddress).map(Address::getStreet).orElse("not specified"); + assertEquals(result, "1st Avenue"); + + Optional optionalUser = Optional.ofNullable(getOptionalUser()); + String resultOpt = optionalUser.flatMap(OptionalUser::getAddress).flatMap(OptionalAddress::getStreet).orElse("not specified"); + assertEquals(resultOpt, "1st Avenue"); + + Optional userNull = Optional.ofNullable(getUserNull()); + String resultNull = userNull.map(User::getAddress).map(Address::getStreet).orElse("not specified"); + assertEquals(resultNull, "not specified"); + + Optional optionalUserNull = Optional.ofNullable(getOptionalUserNull()); + String resultOptNull = optionalUserNull.flatMap(OptionalUser::getAddress).flatMap(OptionalAddress::getStreet).orElse("not specified"); + assertEquals(resultOptNull, "not specified"); + + } + + @Test(expected = CustomException.class) + public void callMethod_whenCustomException_thenCorrect() { + User user = new User(); + String result = user.getOrThrow(); + } + + private User getUser() { + User user = new User(); + Address address = new Address(); + address.setStreet("1st Avenue"); + user.setAddress(address); + return user; + } + + private OptionalUser getOptionalUser() { + OptionalUser user = new OptionalUser(); + OptionalAddress address = new OptionalAddress(); + address.setStreet("1st Avenue"); + user.setAddress(address); + return user; + } + + private OptionalUser getOptionalUserNull() { + OptionalUser user = new OptionalUser(); + OptionalAddress address = new OptionalAddress(); + address.setStreet(null); + user.setAddress(address); + return user; + } + + private User getUserNull() { + User user = new User(); + Address address = new Address(); + address.setStreet(null); + user.setAddress(address); + return user; + } + +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/java8/comparator/Employee.java b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/comparator/Employee.java new file mode 100644 index 0000000000..7030f4c2a1 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/comparator/Employee.java @@ -0,0 +1,22 @@ +package com.ossez.java8.comparator; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Data +@AllArgsConstructor +@ToString +@EqualsAndHashCode +public class Employee implements Comparable{ + String name; + int age; + double salary; + long mobile; + + @Override + public int compareTo(Employee argEmployee) { + return name.compareTo(argEmployee.getName()); + } + +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/java8/comparator/Java8ComparatorUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/comparator/Java8ComparatorUnitTest.java new file mode 100644 index 0000000000..252967fb04 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/java8/comparator/Java8ComparatorUnitTest.java @@ -0,0 +1,152 @@ +package com.ossez.java8.comparator; + +import java.util.Arrays; +import java.util.Comparator; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class Java8ComparatorUnitTest { + + private Employee[] employees; + private Employee[] employeesArrayWithNulls; + private Employee[] sortedEmployeesByName; + private Employee[] sortedEmployeesByNameDesc; + private Employee[] sortedEmployeesByAge; + private Employee[] sortedEmployeesByMobile; + private Employee[] sortedEmployeesBySalary; + private Employee[] sortedEmployeesArray_WithNullsFirst; + private Employee[] sortedEmployeesArray_WithNullsLast; + private Employee[] sortedEmployeesByNameAge; + private Employee[] someMoreEmployees; + private Employee[] sortedEmployeesByAgeName;; + + @Before + public void initData() { + employees = new Employee[] { new Employee("John", 25, 3000, 9922001), new Employee("Ace", 22, 2000, 5924001), new Employee("Keith", 35, 4000, 3924401) }; + employeesArrayWithNulls = new Employee[] { new Employee("John", 25, 3000, 9922001), null, new Employee("Ace", 22, 2000, 5924001), null, new Employee("Keith", 35, 4000, 3924401) }; + + sortedEmployeesByName = new Employee[] { new Employee("Ace", 22, 2000, 5924001), new Employee("John", 25, 3000, 9922001), new Employee("Keith", 35, 4000, 3924401) }; + sortedEmployeesByNameDesc = new Employee[] { new Employee("Keith", 35, 4000, 3924401), new Employee("John", 25, 3000, 9922001), new Employee("Ace", 22, 2000, 5924001) }; + + sortedEmployeesByAge = new Employee[] { new Employee("Ace", 22, 2000, 5924001), new Employee("John", 25, 3000, 9922001), new Employee("Keith", 35, 4000, 3924401) }; + + sortedEmployeesByMobile = new Employee[] { new Employee("Keith", 35, 4000, 3924401), new Employee("Ace", 22, 2000, 5924001), new Employee("John", 25, 3000, 9922001), }; + + sortedEmployeesBySalary = new Employee[] { new Employee("Ace", 22, 2000, 5924001), new Employee("John", 25, 3000, 9922001), new Employee("Keith", 35, 4000, 3924401), }; + + sortedEmployeesArray_WithNullsFirst = new Employee[] { null, null, new Employee("Ace", 22, 2000, 5924001), new Employee("John", 25, 3000, 9922001), new Employee("Keith", 35, 4000, 3924401) }; + sortedEmployeesArray_WithNullsLast = new Employee[] { new Employee("Ace", 22, 2000, 5924001), new Employee("John", 25, 3000, 9922001), new Employee("Keith", 35, 4000, 3924401), null, null }; + + someMoreEmployees = new Employee[] { new Employee("Jake", 25, 3000, 9922001), new Employee("Jake", 22, 2000, 5924001), new Employee("Ace", 22, 3000, 6423001), new Employee("Keith", 35, 4000, 3924401) }; + + sortedEmployeesByAgeName = new Employee[] { new Employee("Ace", 22, 3000, 6423001), new Employee("Jake", 22, 2000, 5924001), new Employee("Jake", 25, 3000, 9922001), new Employee("Keith", 35, 4000, 3924401) }; + sortedEmployeesByNameAge = new Employee[] { new Employee("Ace", 22, 3000, 6423001), new Employee("Jake", 22, 2000, 5924001), new Employee("Jake", 25, 3000, 9922001), new Employee("Keith", 35, 4000, 3924401) }; + } + + @Test + public void whenComparing_thenSortedByName() { + Comparator employeeNameComparator = Comparator.comparing(Employee::getName); + Arrays.sort(employees, employeeNameComparator); + // System.out.println(Arrays.toString(employees)); + assertTrue(Arrays.equals(employees, sortedEmployeesByName)); + } + + @Test + public void whenComparingWithComparator_thenSortedByNameDesc() { + Comparator employeeNameComparator = Comparator.comparing(Employee::getName, (s1, s2) -> { + return s2.compareTo(s1); + }); + Arrays.sort(employees, employeeNameComparator); + // System.out.println(Arrays.toString(employees)); + assertTrue(Arrays.equals(employees, sortedEmployeesByNameDesc)); + } + + @Test + public void whenReversed_thenSortedByNameDesc() { + Comparator employeeNameComparator = Comparator.comparing(Employee::getName); + Comparator employeeNameComparatorReversed = employeeNameComparator.reversed(); + Arrays.sort(employees, employeeNameComparatorReversed); + // System.out.println(Arrays.toString(employees)); + assertTrue(Arrays.equals(employees, sortedEmployeesByNameDesc)); + } + + @Test + public void whenComparingInt_thenSortedByAge() { + Comparator employeeAgeComparator = Comparator.comparingInt(Employee::getAge); + Arrays.sort(employees, employeeAgeComparator); + // System.out.println(Arrays.toString(employees)); + assertTrue(Arrays.equals(employees, sortedEmployeesByAge)); + } + + @Test + public void whenComparingLong_thenSortedByMobile() { + Comparator employeeMobileComparator = Comparator.comparingLong(Employee::getMobile); + Arrays.sort(employees, employeeMobileComparator); + // System.out.println(Arrays.toString(employees)); + assertTrue(Arrays.equals(employees, sortedEmployeesByMobile)); + } + + @Test + public void whenComparingDouble_thenSortedBySalary() { + Comparator employeeSalaryComparator = Comparator.comparingDouble(Employee::getSalary); + Arrays.sort(employees, employeeSalaryComparator); + // System.out.println(Arrays.toString(employees)); + assertTrue(Arrays.equals(employees, sortedEmployeesBySalary)); + } + + @Test + public void whenNaturalOrder_thenSortedByName() { + Comparator employeeNameComparator = Comparator. naturalOrder(); + Arrays.sort(employees, employeeNameComparator); + // System.out.println(Arrays.toString(employees)); + assertTrue(Arrays.equals(employees, sortedEmployeesByName)); + } + + @Test + public void whenReverseOrder_thenSortedByNameDesc() { + Comparator employeeNameComparator = Comparator. reverseOrder(); + Arrays.sort(employees, employeeNameComparator); + // System.out.println(Arrays.toString(employees)); + assertTrue(Arrays.equals(employees, sortedEmployeesByNameDesc)); + } + + @Test + public void whenNullsFirst_thenSortedByNameWithNullsFirst() { + Comparator employeeNameComparator = Comparator.comparing(Employee::getName); + Comparator employeeNameComparator_nullFirst = Comparator.nullsFirst(employeeNameComparator); + Arrays.sort(employeesArrayWithNulls, employeeNameComparator_nullFirst); + // System.out.println(Arrays.toString(employeesArrayWithNulls)); + assertTrue(Arrays.equals(employeesArrayWithNulls, sortedEmployeesArray_WithNullsFirst)); + } + + @Test + public void whenNullsLast_thenSortedByNameWithNullsLast() { + Comparator employeeNameComparator = Comparator.comparing(Employee::getName); + Comparator employeeNameComparator_nullLast = Comparator.nullsLast(employeeNameComparator); + Arrays.sort(employeesArrayWithNulls, employeeNameComparator_nullLast); + // System.out.println(Arrays.toString(employeesArrayWithNulls)); + assertTrue(Arrays.equals(employeesArrayWithNulls, sortedEmployeesArray_WithNullsLast)); + } + + @Test + public void whenThenComparing_thenSortedByAgeName() { + Comparator employee_Age_Name_Comparator = Comparator.comparing(Employee::getAge).thenComparing(Employee::getName); + + Arrays.sort(someMoreEmployees, employee_Age_Name_Comparator); + // System.out.println(Arrays.toString(someMoreEmployees)); + assertTrue(Arrays.equals(someMoreEmployees, sortedEmployeesByAgeName)); + } + + @Test + public void whenThenComparing_thenSortedByNameAge() { + Comparator employee_Name_Age_Comparator = Comparator.comparing(Employee::getName).thenComparingInt(Employee::getAge); + + Arrays.sort(someMoreEmployees, employee_Name_Age_Comparator); + // System.out.println(Arrays.toString(someMoreEmployees)); + assertTrue(Arrays.equals(someMoreEmployees, sortedEmployeesByNameAge)); + } + +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/java_8_features/groupingby/Java8GroupingByCollectorUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/java_8_features/groupingby/Java8GroupingByCollectorUnitTest.java new file mode 100644 index 0000000000..b4185e9156 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/java_8_features/groupingby/Java8GroupingByCollectorUnitTest.java @@ -0,0 +1,215 @@ +package com.ossez.java_8_features.groupingby; + +import static java.util.Comparator.comparingInt; +import static java.util.stream.Collectors.averagingInt; +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.groupingByConcurrent; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.maxBy; +import static java.util.stream.Collectors.summarizingInt; +import static java.util.stream.Collectors.summingInt; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.IntSummaryStatistics; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; + +import org.junit.Test; + +public class Java8GroupingByCollectorUnitTest { + + private static final List posts = Arrays.asList(new BlogPost("News item 1", "Author 1", BlogPostType.NEWS, 15), new BlogPost("Tech review 1", "Author 2", BlogPostType.REVIEW, 5), + new BlogPost("Programming guide", "Author 1", BlogPostType.GUIDE, 20), new BlogPost("News item 2", "Author 2", BlogPostType.NEWS, 35), new BlogPost("Tech review 2", "Author 1", BlogPostType.REVIEW, 15)); + + @Test + public void givenAListOfPosts_whenGroupedByType_thenGetAMapBetweenTypeAndPosts() { + Map> postsPerType = posts.stream() + .collect(groupingBy(BlogPost::getType)); + + assertEquals(2, postsPerType.get(BlogPostType.NEWS) + .size()); + assertEquals(1, postsPerType.get(BlogPostType.GUIDE) + .size()); + assertEquals(2, postsPerType.get(BlogPostType.REVIEW) + .size()); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeAndTheirTitlesAreJoinedInAString_thenGetAMapBetweenTypeAndCsvTitles() { + Map postsPerType = posts.stream() + .collect(groupingBy(BlogPost::getType, mapping(BlogPost::getTitle, joining(", ", "Post titles: [", "]")))); + + assertEquals("Post titles: [News item 1, News item 2]", postsPerType.get(BlogPostType.NEWS)); + assertEquals("Post titles: [Programming guide]", postsPerType.get(BlogPostType.GUIDE)); + assertEquals("Post titles: [Tech review 1, Tech review 2]", postsPerType.get(BlogPostType.REVIEW)); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeAndSumTheLikes_thenGetAMapBetweenTypeAndPostLikes() { + Map likesPerType = posts.stream() + .collect(groupingBy(BlogPost::getType, summingInt(BlogPost::getLikes))); + + assertEquals(50, likesPerType.get(BlogPostType.NEWS) + .intValue()); + assertEquals(20, likesPerType.get(BlogPostType.REVIEW) + .intValue()); + assertEquals(20, likesPerType.get(BlogPostType.GUIDE) + .intValue()); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeInAnEnumMap_thenGetAnEnumMapBetweenTypeAndPosts() { + EnumMap> postsPerType = posts.stream() + .collect(groupingBy(BlogPost::getType, () -> new EnumMap<>(BlogPostType.class), toList())); + + assertEquals(2, postsPerType.get(BlogPostType.NEWS) + .size()); + assertEquals(1, postsPerType.get(BlogPostType.GUIDE) + .size()); + assertEquals(2, postsPerType.get(BlogPostType.REVIEW) + .size()); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeInSets_thenGetAMapBetweenTypesAndSetsOfPosts() { + Map> postsPerType = posts.stream() + .collect(groupingBy(BlogPost::getType, toSet())); + + assertEquals(2, postsPerType.get(BlogPostType.NEWS) + .size()); + assertEquals(1, postsPerType.get(BlogPostType.GUIDE) + .size()); + assertEquals(2, postsPerType.get(BlogPostType.REVIEW) + .size()); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeConcurrently_thenGetAMapBetweenTypeAndPosts() { + ConcurrentMap> postsPerType = posts.parallelStream() + .collect(groupingByConcurrent(BlogPost::getType)); + + assertEquals(2, postsPerType.get(BlogPostType.NEWS) + .size()); + assertEquals(1, postsPerType.get(BlogPostType.GUIDE) + .size()); + assertEquals(2, postsPerType.get(BlogPostType.REVIEW) + .size()); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeAndAveragingLikes_thenGetAMapBetweenTypeAndAverageNumberOfLikes() { + Map averageLikesPerType = posts.stream() + .collect(groupingBy(BlogPost::getType, averagingInt(BlogPost::getLikes))); + + assertEquals(25, averageLikesPerType.get(BlogPostType.NEWS) + .intValue()); + assertEquals(20, averageLikesPerType.get(BlogPostType.GUIDE) + .intValue()); + assertEquals(10, averageLikesPerType.get(BlogPostType.REVIEW) + .intValue()); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeAndCounted_thenGetAMapBetweenTypeAndNumberOfPosts() { + Map numberOfPostsPerType = posts.stream() + .collect(groupingBy(BlogPost::getType, counting())); + + assertEquals(2, numberOfPostsPerType.get(BlogPostType.NEWS) + .intValue()); + assertEquals(1, numberOfPostsPerType.get(BlogPostType.GUIDE) + .intValue()); + assertEquals(2, numberOfPostsPerType.get(BlogPostType.REVIEW) + .intValue()); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeAndMaxingLikes_thenGetAMapBetweenTypeAndMaximumNumberOfLikes() { + Map> maxLikesPerPostType = posts.stream() + .collect(groupingBy(BlogPost::getType, maxBy(comparingInt(BlogPost::getLikes)))); + + assertTrue(maxLikesPerPostType.get(BlogPostType.NEWS) + .isPresent()); + assertEquals(35, maxLikesPerPostType.get(BlogPostType.NEWS) + .get() + .getLikes()); + + assertTrue(maxLikesPerPostType.get(BlogPostType.GUIDE) + .isPresent()); + assertEquals(20, maxLikesPerPostType.get(BlogPostType.GUIDE) + .get() + .getLikes()); + + assertTrue(maxLikesPerPostType.get(BlogPostType.REVIEW) + .isPresent()); + assertEquals(15, maxLikesPerPostType.get(BlogPostType.REVIEW) + .get() + .getLikes()); + } + + @Test + public void givenAListOfPosts_whenGroupedByAuthorAndThenByType_thenGetAMapBetweenAuthorAndMapsBetweenTypeAndBlogPosts() { + Map>> map = posts.stream() + .collect(groupingBy(BlogPost::getAuthor, groupingBy(BlogPost::getType))); + + assertEquals(1, map.get("Author 1") + .get(BlogPostType.NEWS) + .size()); + assertEquals(1, map.get("Author 1") + .get(BlogPostType.GUIDE) + .size()); + assertEquals(1, map.get("Author 1") + .get(BlogPostType.REVIEW) + .size()); + + assertEquals(1, map.get("Author 2") + .get(BlogPostType.NEWS) + .size()); + assertEquals(1, map.get("Author 2") + .get(BlogPostType.REVIEW) + .size()); + assertNull(map.get("Author 2") + .get(BlogPostType.GUIDE)); + } + + @Test + public void givenAListOfPosts_whenGroupedByTypeAndSummarizingLikes_thenGetAMapBetweenTypeAndSummary() { + Map likeStatisticsPerType = posts.stream() + .collect(groupingBy(BlogPost::getType, summarizingInt(BlogPost::getLikes))); + + IntSummaryStatistics newsLikeStatistics = likeStatisticsPerType.get(BlogPostType.NEWS); + + assertEquals(2, newsLikeStatistics.getCount()); + assertEquals(50, newsLikeStatistics.getSum()); + assertEquals(25.0, newsLikeStatistics.getAverage(), 0.001); + assertEquals(35, newsLikeStatistics.getMax()); + assertEquals(15, newsLikeStatistics.getMin()); + } + + @Test + public void givenAListOfPosts_whenGroupedByComplexMapKeyType_thenGetAMapBetweenTupleAndList() { + Map> postsPerTypeAndAuthor = posts.stream() + .collect(groupingBy(post -> new Tuple(post.getType(), post.getAuthor()))); + + List result = postsPerTypeAndAuthor.get(new Tuple(BlogPostType.GUIDE, "Author 1")); + + assertThat(result.size()).isEqualTo(1); + + BlogPost blogPost = result.get(0); + + assertThat(blogPost.getTitle()).isEqualTo("Programming guide"); + assertThat(blogPost.getType()).isEqualTo(BlogPostType.GUIDE); + assertThat(blogPost.getAuthor()).isEqualTo("Author 1"); + } +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java new file mode 100644 index 0000000000..12f9fcca48 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java @@ -0,0 +1,41 @@ +package com.ossez.nullsafecollectionstreams; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; +import org.junit.Test; +import static org.junit.Assert.*; + + +public class NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest { + + private final NullSafeCollectionStreamsUsingCommonsEmptyIfNull instance = + new NullSafeCollectionStreamsUsingCommonsEmptyIfNull(); + + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java new file mode 100644 index 0000000000..8497e63f80 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java @@ -0,0 +1,50 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.ossez.nullsafecollectionstreams; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; + +import org.junit.Test; + +/** + * + * @author Kwaje Anthony + */ +public class NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest { + + private final NullSafeCollectionStreamsUsingJava8OptionalContainer instance = new NullSafeCollectionStreamsUsingJava8OptionalContainer(); + + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java new file mode 100644 index 0000000000..4cd3fc6539 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java @@ -0,0 +1,45 @@ + +package com.ossez.nullsafecollectionstreams; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Kwaje Anthony + */ +public class NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest { + + private final NullSafeCollectionStreamsUsingNullDereferenceCheck instance = + new NullSafeCollectionStreamsUsingNullDereferenceCheck(); + + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/spliteratorAPI/ExecutorUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/spliteratorAPI/ExecutorUnitTest.java new file mode 100644 index 0000000000..380aa1f729 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/spliteratorAPI/ExecutorUnitTest.java @@ -0,0 +1,44 @@ +package com.ossez.spliteratorAPI; + +import java.util.Arrays; +import java.util.Spliterator; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import static org.assertj.core.api.Assertions.*; +import org.junit.Before; +import org.junit.Test; + +public class ExecutorUnitTest { + Article article; + Stream stream; + Spliterator spliterator; + Spliterator
split1; + Spliterator
split2; + + @Before + public void init() { + article = new Article(Arrays.asList(new Author("Ahmad", 0), new Author("Eugen", 0), new Author("Alice", 1), + new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), + new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), + new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), + new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), + new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0); + stream = article.getListOfAuthors().stream(); + split1 = Executor.generateElements().spliterator(); + split2 = split1.trySplit(); + spliterator = new RelatedAuthorSpliterator(article.getListOfAuthors()); + } + + @Test + public void givenAstreamOfAuthors_whenProcessedInParallelWithCustomSpliterator_coubtProducessRightOutput() { + Stream stream2 = StreamSupport.stream(spliterator, true); + assertThat(Executor.countAutors(stream2.parallel())).isEqualTo(9); + } + + @Test + public void givenSpliterator_whenAppliedToAListOfArticle_thenSplittedInHalf() { + assertThat(new Task(split1).call()).containsSequence(Executor.generateElements().size() / 2 + ""); + assertThat(new Task(split2).call()).containsSequence(Executor.generateElements().size() / 2 + ""); + } +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/strategy/StrategyDesignPatternUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/strategy/StrategyDesignPatternUnitTest.java new file mode 100644 index 0000000000..d10e283568 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/strategy/StrategyDesignPatternUnitTest.java @@ -0,0 +1,72 @@ +package com.ossez.strategy; + +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +import static org.assertj.core.api.Assertions.assertThat; + +public class StrategyDesignPatternUnitTest { + @Test + public void shouldDivideByTwo_WhenApplyingStaffDiscounter() { + Discounter staffDiscounter = new EasterDiscounter(); + + final BigDecimal discountedValue = staffDiscounter + .apply(BigDecimal.valueOf(100)); + + assertThat(discountedValue) + .isEqualByComparingTo(BigDecimal.valueOf(50)); + } + + @Test + public void shouldDivideByTwo_WhenApplyingStaffDiscounterWithAnonyousTypes() { + Discounter staffDiscounter = new Discounter() { + @Override + public BigDecimal apply(BigDecimal amount) { + return amount.multiply(BigDecimal.valueOf(0.5)); + } + }; + + final BigDecimal discountedValue = staffDiscounter + .apply(BigDecimal.valueOf(100)); + + assertThat(discountedValue) + .isEqualByComparingTo(BigDecimal.valueOf(50)); + } + + @Test + public void shouldDivideByTwo_WhenApplyingStaffDiscounterWithLamda() { + Discounter staffDiscounter = amount -> amount.multiply(BigDecimal.valueOf(0.5)); + + final BigDecimal discountedValue = staffDiscounter + .apply(BigDecimal.valueOf(100)); + + assertThat(discountedValue) + .isEqualByComparingTo(BigDecimal.valueOf(50)); + } + + @Test + public void shouldApplyAllDiscounts() { + List discounters = Arrays.asList(Discounter.christmas(), Discounter.newYear(), Discounter.easter()); + + BigDecimal amount = BigDecimal.valueOf(100); + + final Discounter combinedDiscounter = discounters + .stream() + .reduce(v -> v, Discounter::combine); + + combinedDiscounter.apply(amount); + } + + @Test + public void shouldChainDiscounters() { + final Function combinedDiscounters = Discounter + .christmas() + .andThen(Discounter.newYear()); + + combinedDiscounters.apply(BigDecimal.valueOf(100)); + } +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/streamreduce/tests/StreamReduceManualTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/streamreduce/tests/StreamReduceManualTest.java new file mode 100644 index 0000000000..28b184338d --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/streamreduce/tests/StreamReduceManualTest.java @@ -0,0 +1,153 @@ +package com.ossez.streamreduce.tests; + +import com.ossez.streamreduce.entities.Rating; +import com.ossez.streamreduce.entities.Review; +import com.ossez.streamreduce.entities.User; +import com.ossez.streamreduce.utilities.NumberUtils; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class StreamReduceManualTest { + + @Test + public void givenIntegerList_whenReduceWithSumAccumulatorLambda_thenCorrect() { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + + int result = numbers.stream().reduce(0, (a, b) -> a + b); + + assertThat(result).isEqualTo(21); + } + + @Test + public void givenIntegerList_whenReduceWithSumAccumulatorMethodReference_thenCorrect() { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + + int result = numbers.stream().reduce(0, Integer::sum); + + assertThat(result).isEqualTo(21); + } + + @Test + public void givenStringList_whenReduceWithConcatenatorAccumulatorLambda_thenCorrect() { + List letters = Arrays.asList("a", "b", "c", "d", "e"); + + String result = letters.stream().reduce("", (a, b) -> a + b); + + assertThat(result).isEqualTo("abcde"); + } + + @Test + public void givenStringList_whenReduceWithConcatenatorAccumulatorMethodReference_thenCorrect() { + List letters = Arrays.asList("a", "b", "c", "d", "e"); + + String result = letters.stream().reduce("", String::concat); + + assertThat(result).isEqualTo("abcde"); + } + + @Test + public void givenStringList_whenReduceWithUppercaseConcatenatorAccumulator_thenCorrect() { + List letters = Arrays.asList("a", "b", "c", "d", "e"); + + String result = letters.stream().reduce("", (a, b) -> a.toUpperCase() + b.toUpperCase()); + + assertThat(result).isEqualTo("ABCDE"); + } + + @Test + public void givenUserList_whenReduceWithAgeAccumulatorAndSumCombiner_thenCorrect() { + List users = Arrays.asList(new User("John", 30), new User("Julie", 35)); + + int result = users.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); + + assertThat(result).isEqualTo(65); + } + + @Test + public void givenUserList_whenReduceWithGreaterAgeAccumulator_thenFindsOldest() { + List users = Arrays.asList(new User("John", 30), new User("Alex", 40), new User("Julie", 35)); + + User oldest = users.stream().reduce(users.get(0), (user1, user2) -> user1.getAge() >= user2.getAge() ? user1 : user2); + + assertThat(oldest).isEqualTo(users.get(1)); + } + + @Test + public void givenUserListWithRatings_whenReduceWithGreaterAgeAccumulator_thenFindsOldest() { + User john = new User("John", 30); + john.getRating().add(new Review(5, "")); + john.getRating().add(new Review(3, "not bad")); + User julie = new User("Julie", 35); + john.getRating().add(new Review(4, "great!")); + john.getRating().add(new Review(2, "terrible experience")); + john.getRating().add(new Review(4, "")); + List users = Arrays.asList(john, julie); + + Rating averageRating = users.stream().reduce(new Rating(), (rating, user) -> Rating.average(rating, user.getRating()), Rating::average); + + assertThat(averageRating.getPoints()).isEqualTo(3.6); + } + + @Test + public void givenStringList_whenReduceWithParallelStream_thenCorrect() { + List letters = Arrays.asList("a", "b", "c", "d", "e"); + + String result = letters.parallelStream().reduce("", String::concat); + + assertThat(result).isEqualTo("abcde"); + } + + @Test + public void givenNumberUtilsClass_whenCalledDivideListElements_thenCorrect() { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + + assertThat(NumberUtils.divideListElements(numbers, 1)).isEqualTo(21); + } + + @Test + public void givenNumberUtilsClass_whenCalledDivideListElementsWithExtractedTryCatchBlock_thenCorrect() { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + + assertThat(NumberUtils.divideListElementsWithExtractedTryCatchBlock(numbers, 1)).isEqualTo(21); + } + + @Test + public void givenNumberUtilsClass_whenCalledDivideListElementsWithExtractedTryCatchBlockAndListContainsZero_thenCorrect() { + List numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6); + + assertThat(NumberUtils.divideListElementsWithExtractedTryCatchBlock(numbers, 1)).isEqualTo(21); + } + + @Test + public void givenNumberUtilsClass_whenCalledDivideListElementsWithExtractedTryCatchBlockAndDividerIsZero_thenCorrect() { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + + assertThat(NumberUtils.divideListElementsWithExtractedTryCatchBlock(numbers, 0)).isEqualTo(0); + } + + @Test + public void givenStream_whneCalleddivideListElementsWithApplyFunctionMethod_thenCorrect() { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); + + assertThat(NumberUtils.divideListElementsWithApplyFunctionMethod(numbers, 1)).isEqualTo(21); + } + + @Test + public void givenTwoStreams_whenCalledReduceOnParallelizedStream_thenFasterExecutionTime() { + List userList = new ArrayList<>(); + for (int i = 0; i <= 1000000; i++) { + userList.add(new User("John" + i, i)); + } + long currentTime1 = System.currentTimeMillis(); + userList.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); + long sequentialExecutionTime = System.currentTimeMillis() -currentTime1; + long currentTime2 = System.currentTimeMillis(); + userList.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); + long parallelizedExecutionTime = System.currentTimeMillis() - currentTime2; + + assertThat(parallelizedExecutionTime).isLessThan(sequentialExecutionTime); + } +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/typeinference/TypeInferenceUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/typeinference/TypeInferenceUnitTest.java new file mode 100644 index 0000000000..829a7c98a0 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/typeinference/TypeInferenceUnitTest.java @@ -0,0 +1,87 @@ +package com.ossez.typeinference; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +public class TypeInferenceUnitTest { + + @Test + public void givenNoTypeInference_whenInvokingGenericMethodsWithTypeParameters_ObjectsAreCreated() { + // Without type inference. code is verbose. + Map> mapOfMaps = new HashMap>(); + List strList = Collections. emptyList(); + List intList = Collections. emptyList(); + + assertTrue(mapOfMaps.isEmpty()); + assertTrue(strList.isEmpty()); + assertTrue(intList.isEmpty()); + } + + @Test + public void givenTypeInference_whenInvokingGenericMethodsWithoutTypeParameters_ObjectsAreCreated() { + // With type inference. code is concise. + List strListInferred = Collections.emptyList(); + List intListInferred = Collections.emptyList(); + + assertTrue(strListInferred.isEmpty()); + assertTrue(intListInferred.isEmpty()); + } + + @Test + public void givenJava7_whenInvokingCostructorWithoutTypeParameters_ObjectsAreCreated() { + // Type Inference for constructor using diamond operator. + Map> mapOfMapsInferred = new HashMap<>(); + + assertTrue(mapOfMapsInferred.isEmpty()); + assertEquals("public class java.util.HashMap", mapOfMapsInferred.getClass() + .toGenericString()); + } + + static List add(List list, T a, T b) { + list.add(a); + list.add(b); + return list; + } + + @Test + public void givenGenericMethod_WhenInvokedWithoutExplicitTypes_TypesAreInferred() { + // Generalized target-type inference + List strListGeneralized = add(new ArrayList<>(), "abc", "def"); + List intListGeneralized = add(new ArrayList<>(), 1, 2); + List numListGeneralized = add(new ArrayList<>(), 1, 2.0); + + assertEquals("public class java.util.ArrayList", strListGeneralized.getClass() + .toGenericString()); + assertFalse(intListGeneralized.isEmpty()); + assertEquals(2, numListGeneralized.size()); + } + + @Test + public void givenLambdaExpressions_whenParameterTypesNotSpecified_ParameterTypesAreInferred() { + // Type Inference and Lambda Expressions. + List intList = Arrays.asList(5, 3, 4, 2, 1); + Collections.sort(intList, (a, b) -> { + assertEquals("java.lang.Integer", a.getClass().getName()); + return a.compareTo(b); + }); + assertEquals("[1, 2, 3, 4, 5]", Arrays.toString(intList.toArray())); + + List strList = Arrays.asList("Red", "Blue", "Green"); + Collections.sort(strList, (a, b) -> { + assertEquals("java.lang.String", a.getClass().getName()); + return a.compareTo(b); + }); + assertEquals("[Blue, Green, Red]", Arrays.toString(strList.toArray())); + } + +} diff --git a/core-java-modules/core-java-8/src/test/java/com/ossez/util/CurrentDateTimeUnitTest.java b/core-java-modules/core-java-8/src/test/java/com/ossez/util/CurrentDateTimeUnitTest.java new file mode 100644 index 0000000000..ce4e29aeb7 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/java/com/ossez/util/CurrentDateTimeUnitTest.java @@ -0,0 +1,42 @@ +package com.ossez.util; + +import static org.junit.Assert.assertEquals; + +import java.time.Clock; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.temporal.ChronoField; + +import org.junit.Test; + +public class CurrentDateTimeUnitTest { + + private static final Clock clock = Clock.fixed(Instant.parse("2016-10-09T15:10:30.00Z"), ZoneId.of("UTC")); + + @Test + public void shouldReturnCurrentDate() { + final LocalDate now = LocalDate.now(clock); + + assertEquals(9, now.get(ChronoField.DAY_OF_MONTH)); + assertEquals(10, now.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(2016, now.get(ChronoField.YEAR)); + } + + @Test + public void shouldReturnCurrentTime() { + final LocalTime now = LocalTime.now(clock); + + assertEquals(15, now.get(ChronoField.HOUR_OF_DAY)); + assertEquals(10, now.get(ChronoField.MINUTE_OF_HOUR)); + assertEquals(30, now.get(ChronoField.SECOND_OF_MINUTE)); + } + + @Test + public void shouldReturnCurrentTimestamp() { + final Instant now = Instant.now(clock); + + assertEquals(clock.instant().getEpochSecond(), now.getEpochSecond()); + } +} diff --git a/core-java-modules/core-java-8/src/test/resources/.gitignore b/core-java-modules/core-java-8/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/core-java-modules/core-java-8/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file