diff --git a/.idea/compiler.xml b/.idea/compiler.xml index e1211661e8..0d92c7f2b6 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -18,6 +18,7 @@ + @@ -31,7 +32,6 @@ - @@ -39,6 +39,9 @@ + + + diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 485ea4d754..ec5eb51b99 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -33,6 +33,8 @@ + + diff --git a/core-java-modules/core-java-collections-list-2/README.md b/core-java-modules/core-java-collections-list-2/README.md deleted file mode 100644 index 77d583d7de..0000000000 --- a/core-java-modules/core-java-collections-list-2/README.md +++ /dev/null @@ -1,15 +0,0 @@ -## Java 核心(Core Java)集合中的 List 列表 (第2部分) - -This module contains articles about the Java List collection - -### Relevant Articles: -- [Check If Two Lists are Equal in Java](https://www.baeldung.com/java-test-a-list-for-ordinality-and-equality) -- [Java 8 Streams: Find Items From One List Based On Values From Another List](https://www.baeldung.com/java-streams-find-list-items) -- [A Guide to the Java LinkedList](https://www.baeldung.com/java-linkedlist) -- [Java List UnsupportedOperationException](https://www.baeldung.com/java-list-unsupported-operation-exception) -- [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line) -- [Ways to Iterate Over a List in Java](https://www.baeldung.com/java-iterate-list) -- [Flattening Nested Collections in Java](https://www.baeldung.com/java-flatten-nested-collections) -- [Intersection of Two Lists in Java](https://www.baeldung.com/java-lists-intersection) -- [Searching for a String in an ArrayList](https://www.baeldung.com/java-search-string-arraylist) -- [[<-- Prev]](/core-java-modules/core-java-collections-list)[[Next -->]](/core-java-modules/core-java-collections-list-3) diff --git a/core-java-modules/core-java-collections-list/README.md b/core-java-modules/core-java-collections-list/README.md index 47d8d9c41f..36ceee579c 100644 --- a/core-java-modules/core-java-collections-list/README.md +++ b/core-java-modules/core-java-collections-list/README.md @@ -12,4 +12,12 @@ - [How to Find an Element in a List with Java](http://www.baeldung.com/find-list-element-java) - [Finding Max/Min of a List or Collection](http://www.baeldung.com/java-collection-min-max) - [Remove All Occurrences of a Specific Value from a List](https://www.baeldung.com/java-remove-value-from-list) -- [[Next -->]](/core-java-modules/core-java-collections-list-2) +- [Check If Two Lists are Equal in Java](https://www.baeldung.com/java-test-a-list-for-ordinality-and-equality) +- [Java 8 Streams: Find Items From One List Based On Values From Another List](https://www.baeldung.com/java-streams-find-list-items) +- [A Guide to the Java LinkedList](https://www.baeldung.com/java-linkedlist) +- [Java List UnsupportedOperationException](https://www.baeldung.com/java-list-unsupported-operation-exception) +- [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line) +- [Ways to Iterate Over a List in Java](https://www.baeldung.com/java-iterate-list) +- [Flattening Nested Collections in Java](https://www.baeldung.com/java-flatten-nested-collections) +- [Intersection of Two Lists in Java](https://www.baeldung.com/java-lists-intersection) +- [Searching for a String in an ArrayList](https://www.baeldung.com/java-search-string-arraylist) \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-2/src/main/java/com/ossez/findastring/FindAStringInGivenList.java b/core-java-modules/core-java-collections-list/src/main/java/com/ossez/findastring/FindAStringInGivenList.java similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/main/java/com/ossez/findastring/FindAStringInGivenList.java rename to core-java-modules/core-java-collections-list/src/main/java/com/ossez/findastring/FindAStringInGivenList.java diff --git a/core-java-modules/core-java-collections-list-2/src/main/java/com/ossez/java/list/WaysToIterate.java b/core-java-modules/core-java-collections-list/src/main/java/com/ossez/list/WaysToIterate.java similarity index 98% rename from core-java-modules/core-java-collections-list-2/src/main/java/com/ossez/java/list/WaysToIterate.java rename to core-java-modules/core-java-collections-list/src/main/java/com/ossez/list/WaysToIterate.java index 26dddc9bf3..6e0453d395 100644 --- a/core-java-modules/core-java-collections-list-2/src/main/java/com/ossez/java/list/WaysToIterate.java +++ b/core-java-modules/core-java-collections-list/src/main/java/com/ossez/list/WaysToIterate.java @@ -1,4 +1,4 @@ -package com.ossez.java.list; +package com.ossez.list; import java.util.Arrays; import java.util.Iterator; diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/array/converter/ArrayConvertToListUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/converter/ArrayConvertToListUnitTest.java similarity index 99% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/array/converter/ArrayConvertToListUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/converter/ArrayConvertToListUnitTest.java index 89b0bbcf53..94cc365181 100644 --- a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/array/converter/ArrayConvertToListUnitTest.java +++ b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/converter/ArrayConvertToListUnitTest.java @@ -1,4 +1,4 @@ -package com.ossez.array.converter; +package com.ossez.converter; import org.junit.Test; diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/findItems/FindItemsBasedOnOtherStreamUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/findItems/FindItemsBasedOnOtherStreamUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/findItems/FindItemsBasedOnOtherStreamUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/findItems/FindItemsBasedOnOtherStreamUnitTest.java diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/findastring/FindAStringInListUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/findastring/FindAStringInListUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/findastring/FindAStringInListUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/findastring/FindAStringInListUnitTest.java diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/list/flattennestedlist/FlattenNestedListUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/flattennestedlist/FlattenNestedListUnitTest.java similarity index 97% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/list/flattennestedlist/FlattenNestedListUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/flattennestedlist/FlattenNestedListUnitTest.java index 2370b7be69..ac9f77c03a 100644 --- a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/list/flattennestedlist/FlattenNestedListUnitTest.java +++ b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/flattennestedlist/FlattenNestedListUnitTest.java @@ -1,4 +1,4 @@ -package com.ossez.list.flattennestedlist; +package com.ossez.flattennestedlist; import static java.util.Arrays.asList; import static org.junit.Assert.assertNotNull; diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/list/ListAssertJUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/list/ListAssertJUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/list/ListAssertJUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/list/ListAssertJUnitTest.java diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/list/ListJUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/list/ListJUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/list/ListJUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/list/ListJUnitTest.java diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/list/ListTestNgUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/list/ListTestNgUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/list/ListTestNgUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/list/ListTestNgUnitTest.java diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/list/WaysToIterateUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/list/WaysToIterateUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/list/WaysToIterateUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/list/WaysToIterateUnitTest.java diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/listInitialization/ListInitializationUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/listInitialization/ListInitializationUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/ossez/java/listInitialization/ListInitializationUnitTest.java rename to core-java-modules/core-java-collections-list/src/test/java/com/ossez/java/listInitialization/ListInitializationUnitTest.java diff --git a/core-java-modules/core-java-lambdas/README.md b/core-java-modules/core-java-lambdas/README.md new file mode 100644 index 0000000000..a216a50574 --- /dev/null +++ b/core-java-modules/core-java-lambdas/README.md @@ -0,0 +1,14 @@ +## Lambdas 函数 + +本文件夹中包含有所有 Java 相关的 Lambdas 函数及其示例 + +- [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables) +- [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda) +- [Functional Interfaces in Java 8](http://www.baeldung.com/java-8-functional-interfaces) +- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips) +- [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions) +- [Method References in Java](https://www.baeldung.com/java-method-references) +- [The Double Colon Operator in Java 8](https://www.baeldung.com/java-8-double-colon-operator) +- [Serialize a Lambda in Java](https://www.baeldung.com/java-serialize-lambda) +- [Convert Anonymous Class into Lambda in Java](https://www.baeldung.com/java-from-anonymous-class-to-lambda) +- [When to Use Callable and Supplier in Java](https://www.baeldung.com/java-callable-vs-supplier) diff --git a/core-java-modules/core-java-collections-list-2/pom.xml b/core-java-modules/core-java-lambdas/pom.xml similarity index 57% rename from core-java-modules/core-java-collections-list-2/pom.xml rename to core-java-modules/core-java-lambdas/pom.xml index fc022180db..0e6b049d2a 100644 --- a/core-java-modules/core-java-collections-list-2/pom.xml +++ b/core-java-modules/core-java-lambdas/pom.xml @@ -3,10 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - core-java-collections-list-2 - 0.1.0-SNAPSHOT - core-java-collections-list-2 + core-java-lambdas jar + core-java-lambdas com.ossez.core-java-modules @@ -18,14 +17,8 @@ org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - org.projectlombok - lombok - ${lombok.version} - provided + commons-lang3 + ${commons-lang3.version} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/Computer.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/Computer.java new file mode 100644 index 0000000000..e3f04d7fee --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/Computer.java @@ -0,0 +1,85 @@ +package com.ossez.doublecolon; + +public class Computer { + + private Integer age; + private String color; + private Integer healty; + + Computer(final int age, final String color) { + this.age = age; + this.color = color; + } + + Computer(final Integer age, final String color, final Integer healty) { + this.age = age; + this.color = color; + this.healty = healty; + } + + public Computer() { + } + + public Integer getAge() { + return age; + } + + public void setAge(final Integer age) { + this.age = age; + } + + String getColor() { + return color; + } + + public void setColor(final String color) { + this.color = color; + } + + Integer getHealty() { + return healty; + } + + void setHealty(final Integer healty) { + this.healty = healty; + } + + public void turnOnPc() { + System.out.println("Computer turned on"); + } + + public void turnOffPc() { + System.out.println("Computer turned off"); + } + + public Double calculateValue(Double initialValue) { + return initialValue / 1.50; + } + + @Override + public String toString() { + return "Computer{" + "age=" + age + ", color='" + color + '\'' + ", healty=" + healty + '}'; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final Computer computer = (Computer) o; + + return (age != null ? age.equals(computer.age) : computer.age == null) && (color != null ? color.equals(computer.color) : computer.color == null); + + } + + @Override + public int hashCode() { + int result = age != null ? age.hashCode() : 0; + result = 31 * result + (color != null ? color.hashCode() : 0); + return result; + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/ComputerUtils.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/ComputerUtils.java new file mode 100644 index 0000000000..1949d62db6 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/ComputerUtils.java @@ -0,0 +1,27 @@ +package com.ossez.doublecolon; + +import java.util.ArrayList; +import java.util.List; + +import com.ossez.doublecolon.function.ComputerPredicate; + +public class ComputerUtils { + + static final ComputerPredicate after2010Predicate = (c) -> (c.getAge() > 2010); + static final ComputerPredicate blackPredicate = (c) -> "black".equals(c.getColor()); + + public static List filter(final List inventory, final ComputerPredicate p) { + + final List result = new ArrayList<>(); + inventory.stream().filter(p::filter).forEach(result::add); + + return result; + } + + static void repair(final Computer computer) { + if (computer.getHealty() < 50) { + computer.setHealty(100); + } + } + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/MacbookPro.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/MacbookPro.java new file mode 100644 index 0000000000..50a206067d --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/MacbookPro.java @@ -0,0 +1,39 @@ +package com.ossez.doublecolon; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.Function; + +public class MacbookPro extends Computer { + + private static final Logger LOG = LoggerFactory.getLogger(MacbookPro.class); + + public MacbookPro(int age, String color) { + super(age, color); + } + + MacbookPro(Integer age, String color, Integer healty) { + super(age, color, healty); + } + + @Override + public void turnOnPc() { + LOG.debug("MacbookPro turned on"); + } + + @Override + public void turnOffPc() { + LOG.debug("MacbookPro turned off"); + } + + @Override + public Double calculateValue(Double initialValue) { + + Function function = super::calculateValue; + final Double pcValue = function.apply(initialValue); + LOG.debug("First value is:" + pcValue); + return pcValue + (initialValue / 10); + + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/function/ComputerPredicate.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/function/ComputerPredicate.java new file mode 100644 index 0000000000..fe64ba90df --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/function/ComputerPredicate.java @@ -0,0 +1,10 @@ +package com.ossez.doublecolon.function; + +import com.ossez.doublecolon.Computer; + +@FunctionalInterface +public interface ComputerPredicate { + + boolean filter(Computer c); + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/function/TriFunction.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/function/TriFunction.java new file mode 100644 index 0000000000..66fc53e908 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/doublecolon/function/TriFunction.java @@ -0,0 +1,15 @@ +package com.ossez.doublecolon.function; + +import java.util.Objects; +import java.util.function.Function; + +@FunctionalInterface +public interface TriFunction { + + R apply(A a, B b, C c); + + default TriFunction andThen(final Function super R, ? extends V> after) { + Objects.requireNonNull(after); + return (final A a, final B b, final C c) -> after.apply(apply(a, b, c)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/entity/Human.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/entity/Human.java new file mode 100644 index 0000000000..49f62d7ae4 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/entity/Human.java @@ -0,0 +1,89 @@ +package com.ossez.java8.entity; + +public class Human { + private String name; + private int age; + + public Human() { + super(); + } + + public Human(final String name, final int age) { + super(); + + this.name = name; + this.age = age; + } + + // API + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(final int age) { + this.age = age; + } + + // compare + + public static int compareByNameThenAge(final Human lhs, final Human rhs) { + if (lhs.name.equals(rhs.name)) { + return Integer.compare(lhs.age, rhs.age); + } else { + return lhs.name.compareTo(rhs.name); + } + } + + // + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + age; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Human other = (Human) obj; + if (age != other.age) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Human [name=").append(name).append(", age=").append(age).append("]"); + return builder.toString(); + } + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/exceptions/LambdaExceptionWrappers.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/exceptions/LambdaExceptionWrappers.java new file mode 100644 index 0000000000..21c441b545 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/exceptions/LambdaExceptionWrappers.java @@ -0,0 +1,62 @@ +package com.ossez.java8.lambda.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.Consumer; + +public class LambdaExceptionWrappers { + + private static final Logger LOGGER = LoggerFactory.getLogger(LambdaExceptionWrappers.class); + + public static Consumer lambdaWrapper(Consumer consumer) { + return i -> { + try { + consumer.accept(i); + } catch (ArithmeticException e) { + LOGGER.error("Arithmetic Exception occurred.", e); + } + }; + } + + static Consumer consumerWrapper(Consumer consumer, Class clazz) { + return i -> { + try { + consumer.accept(i); + } catch (Exception ex) { + try { + E exCast = clazz.cast(ex); + LOGGER.error("Exception occurred.", exCast); + } catch (ClassCastException ccEx) { + throw ex; + } + } + }; + } + + public static Consumer throwingConsumerWrapper(ThrowingConsumer throwingConsumer) { + return i -> { + try { + throwingConsumer.accept(i); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }; + } + + public static Consumer handlingConsumerWrapper(ThrowingConsumer throwingConsumer, Class exceptionClass) { + return i -> { + try { + throwingConsumer.accept(i); + } catch (Exception ex) { + try { + E exCast = exceptionClass.cast(ex); + LOGGER.error("Exception occurred.", exCast); + } catch (ClassCastException ccEx) { + throw new RuntimeException(ex); + } + } + }; + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/exceptions/ThrowingConsumer.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/exceptions/ThrowingConsumer.java new file mode 100644 index 0000000000..36db53e158 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/exceptions/ThrowingConsumer.java @@ -0,0 +1,8 @@ +package com.ossez.java8.lambda.exceptions; + +@FunctionalInterface +public interface ThrowingConsumer { + + void accept(T t) throws E; + +} \ No newline at end of file diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Bar.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Bar.java new file mode 100644 index 0000000000..698f51c89c --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Bar.java @@ -0,0 +1,16 @@ +package com.ossez.java8.lambda.tips; + + +@FunctionalInterface +public interface Bar { + + String method(String string); + + default String defaultBar() { + return "Default String from Bar"; + } + + default String defaultCommon() { + return "Default Common from Bar"; + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Baz.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Baz.java new file mode 100644 index 0000000000..990f2b7149 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Baz.java @@ -0,0 +1,16 @@ +package com.ossez.java8.lambda.tips; + + +@FunctionalInterface +public interface Baz { + + String method(String string); + + default String defaultBaz() { + return "Default String from Baz"; + } + + default String defaultCommon(){ + return "Default Common from Baz"; + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Foo.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Foo.java new file mode 100644 index 0000000000..7a042bf368 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Foo.java @@ -0,0 +1,11 @@ +package com.ossez.java8.lambda.tips; + + +@FunctionalInterface +public interface Foo { + + String method(String string); + + default void defaultMethod() { + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/FooExtended.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/FooExtended.java new file mode 100644 index 0000000000..55eb83865b --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/FooExtended.java @@ -0,0 +1,11 @@ +package com.ossez.java8.lambda.tips; + + +@FunctionalInterface +public interface FooExtended extends Baz, Bar { + + @Override + default String defaultCommon() { + return Bar.super.defaultCommon(); + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Processor.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Processor.java new file mode 100644 index 0000000000..056e6d3f25 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/Processor.java @@ -0,0 +1,12 @@ +package com.ossez.java8.lambda.tips; + +import java.util.concurrent.Callable; +import java.util.function.Supplier; + +public interface Processor { + + String processWithCallable(Callable c) throws Exception; + + String processWithSupplier(Supplier s); + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/ProcessorImpl.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/ProcessorImpl.java new file mode 100644 index 0000000000..db4f67536f --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/ProcessorImpl.java @@ -0,0 +1,18 @@ +package com.ossez.java8.lambda.tips; + + +import java.util.concurrent.Callable; +import java.util.function.Supplier; + +public class ProcessorImpl implements Processor { + + @Override + public String processWithCallable(Callable c) throws Exception { + return c.call(); + } + + @Override + public String processWithSupplier(Supplier s) { + return s.get(); + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/UseFoo.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/UseFoo.java new file mode 100644 index 0000000000..d3bb13df0b --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/java8/lambda/tips/UseFoo.java @@ -0,0 +1,38 @@ +package com.ossez.java8.lambda.tips; + + +import java.util.function.Function; + +public class UseFoo { + + private String value = "Enclosing scope value"; + + public String add(final String string, final Foo foo) { + return foo.method(string); + } + + public String addWithStandardFI(final String string, final Function fn) { + return fn.apply(string); + } + + public String scopeExperiment() { + final Foo fooIC = new Foo() { + String value = "Inner class value"; + + @Override + public String method(final String string) { + return value; + } + }; + final String resultIC = fooIC.method(""); + + final Foo fooLambda = parameter -> { + final String value = "Lambda value"; + return this.value; + }; + final String resultLambda = fooLambda.method(""); + + return "Results: resultIC = " + resultIC + ", resultLambda = " + resultLambda; + } + +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/ossez/lambdas/LambdaVariables.java b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/lambdas/LambdaVariables.java new file mode 100644 index 0000000000..52dca253d2 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/ossez/lambdas/LambdaVariables.java @@ -0,0 +1,88 @@ +package com.ossez.lambdas; + +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +/** + * Class with examples about working with capturing lambdas. + */ +public class LambdaVariables { + + private volatile boolean run = true; + private int start = 0; + + private ExecutorService executor = Executors.newFixedThreadPool(3); + + public static void main(String[] args) { + new LambdaVariables().localVariableMultithreading(); + } + + Supplier incrementer(int start) { + return () -> start; // can't modify start parameter inside the lambda + } + + Supplier incrementer() { + return () -> start++; + } + + public void localVariableMultithreading() { + boolean run = true; + executor.execute(() -> { + while (run) { + // do operation + } + }); + // commented because it doesn't compile, it's just an example of non-final local variables in lambdas + // run = false; + } + + public void instanceVariableMultithreading() { + executor.execute(() -> { + while (run) { + // do operation + } + }); + + run = false; + } + + /** + * WARNING: always avoid this workaround!! + */ + public void workaroundSingleThread() { + int[] holder = new int[] { 2 }; + IntStream sums = IntStream + .of(1, 2, 3) + .map(val -> val + holder[0]); + + holder[0] = 0; + + System.out.println(sums.sum()); + } + + /** + * WARNING: always avoid this workaround!! + */ + public void workaroundMultithreading() { + int[] holder = new int[] { 2 }; + Runnable runnable = () -> System.out.println(IntStream + .of(1, 2, 3) + .map(val -> val + holder[0]) + .sum()); + + new Thread(runnable).start(); + + // simulating some processing + try { + Thread.sleep(new Random().nextInt(3) * 1000L); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + holder[0] = 0; + } + +} diff --git a/core-java-modules/core-java-collections-list-2/src/main/resources/logback.xml b/core-java-modules/core-java-lambdas/src/main/resources/logback.xml similarity index 100% rename from core-java-modules/core-java-collections-list-2/src/main/resources/logback.xml rename to core-java-modules/core-java-lambdas/src/main/resources/logback.xml diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/doublecolon/ComputerUtilsUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/doublecolon/ComputerUtilsUnitTest.java new file mode 100644 index 0000000000..0afce2e0e6 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/doublecolon/ComputerUtilsUnitTest.java @@ -0,0 +1,94 @@ +package com.ossez.doublecolon; + +import com.ossez.doublecolon.Computer; +import com.ossez.doublecolon.ComputerUtils; +import com.ossez.doublecolon.MacbookPro; +import com.ossez.doublecolon.function.TriFunction; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.function.BiFunction; + +import static com.ossez.doublecolon.ComputerUtils.*; + +public class ComputerUtilsUnitTest { + + @Before + public void setup() { + } + + @After + public void tearDown() { + } + + @Test + public void testConstructorReference() { + + Computer c1 = new Computer(2015, "white"); + Computer c2 = new Computer(2009, "black"); + Computer c3 = new Computer(2014, "black"); + + BiFunction c4Function = Computer::new; + Computer c4 = c4Function.apply(2013, "white"); + BiFunction c5Function = Computer::new; + Computer c5 = c5Function.apply(2010, "black"); + BiFunction c6Function = Computer::new; + Computer c6 = c6Function.apply(2008, "black"); + + List inventory = Arrays.asList(c1, c2, c3, c4, c5, c6); + + List blackComputer = filter(inventory, blackPredicate); + Assert.assertEquals("The black Computers are: ", blackComputer.size(), 4); + + List after2010Computer = filter(inventory, after2010Predicate); + Assert.assertEquals("The Computer bought after 2010 are: ", after2010Computer.size(), 3); + + List before2011Computer = filter(inventory, c -> c.getAge() < 2011); + Assert.assertEquals("The Computer bought before 2011 are: ", before2011Computer.size(), 3); + + inventory.sort(Comparator.comparing(Computer::getAge)); + + Assert.assertEquals("Oldest Computer in inventory", c6, inventory.get(0)); + + } + + @Test + public void testStaticMethodReference() { + + Computer c1 = new Computer(2015, "white", 35); + Computer c2 = new Computer(2009, "black", 65); + TriFunction c6Function = Computer::new; + Computer c3 = c6Function.apply(2008, "black", 90); + + List inventory = Arrays.asList(c1, c2, c3); + inventory.forEach(ComputerUtils::repair); + + Assert.assertEquals("Computer repaired", new Integer(100), c1.getHealty()); + } + + @Test + public void testInstanceMethodArbitraryObjectParticularType() { + + Computer c1 = new Computer(2015, "white", 35); + Computer c2 = new MacbookPro(2009, "black", 65); + List inventory = Arrays.asList(c1, c2); + inventory.forEach(Computer::turnOnPc); + + } + + @Test + public void testSuperMethodReference() { + + final TriFunction integerStringIntegerObjectTriFunction = MacbookPro::new; + final MacbookPro macbookPro = integerStringIntegerObjectTriFunction.apply(2010, "black", 100); + Double initialValue = 999.99; + final Double actualValue = macbookPro.calculateValue(initialValue); + Assert.assertEquals(766.659, actualValue, 0.0); + } + +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/functionalinterface/FunctionalInterfaceUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/functionalinterface/FunctionalInterfaceUnitTest.java new file mode 100644 index 0000000000..c48b67d2f9 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/functionalinterface/FunctionalInterfaceUnitTest.java @@ -0,0 +1,187 @@ +package com.ossez.functionalinterface; + +import com.google.common.util.concurrent.Uninterruptibles; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.*; + +public class FunctionalInterfaceUnitTest { + + private static final Logger LOG = LoggerFactory.getLogger(FunctionalInterfaceUnitTest.class); + + @Test + public void whenPassingLambdaToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() { + Map nameMap = new HashMap<>(); + Integer value = nameMap.computeIfAbsent("John", String::length); + + assertEquals(new Integer(4), nameMap.get("John")); + assertEquals(new Integer(4), value); + } + + @Test + public void whenPassingMethodReferenceToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() { + Map nameMap = new HashMap<>(); + Integer value = nameMap.computeIfAbsent("John", String::length); + + assertEquals(new Integer(4), nameMap.get("John")); + assertEquals(new Integer(4), value); + } + + @Test + public void whenUsingCustomFunctionalInterfaceForPrimitives_thenCanUseItAsLambda() { + + short[] array = { (short) 1, (short) 2, (short) 3 }; + byte[] transformedArray = transformArray(array, s -> (byte) (s * 2)); + + byte[] expectedArray = { (byte) 2, (byte) 4, (byte) 6 }; + assertArrayEquals(expectedArray, transformedArray); + + } + + @Test + public void whenUsingBiFunction_thenCanUseItToReplaceMapValues() { + Map salaries = new HashMap<>(); + salaries.put("John", 40000); + salaries.put("Freddy", 30000); + salaries.put("Samuel", 50000); + + salaries.replaceAll((name, oldValue) -> name.equals("Freddy") ? oldValue : oldValue + 10000); + + assertEquals(new Integer(50000), salaries.get("John")); + assertEquals(new Integer(30000), salaries.get("Freddy")); + assertEquals(new Integer(60000), salaries.get("Samuel")); + } + + @Test + public void whenPassingLambdaToThreadConstructor_thenLambdaInferredToRunnable() { + Thread thread = new Thread(() -> LOG.debug("Hello From Another Thread")); + thread.start(); + } + + @Test + public void whenUsingSupplierToGenerateNumbers_thenCanUseItInStreamGenerate() { + + int[] fibs = { 0, 1 }; + Stream fibonacci = Stream.generate(() -> { + int result = fibs[1]; + int fib3 = fibs[0] + fibs[1]; + fibs[0] = fibs[1]; + fibs[1] = fib3; + return result; + }); + + List fibonacci5 = fibonacci.limit(5) + .collect(Collectors.toList()); + + assertEquals(new Integer(1), fibonacci5.get(0)); + assertEquals(new Integer(1), fibonacci5.get(1)); + assertEquals(new Integer(2), fibonacci5.get(2)); + assertEquals(new Integer(3), fibonacci5.get(3)); + assertEquals(new Integer(5), fibonacci5.get(4)); + } + + @Test + public void whenUsingConsumerInForEach_thenConsumerExecutesForEachListElement() { + List names = Arrays.asList("John", "Freddy", "Samuel"); + names.forEach(name -> LOG.debug("Hello, " + name)); + } + + @Test + public void whenUsingBiConsumerInForEach_thenConsumerExecutesForEachMapElement() { + Map ages = new HashMap<>(); + ages.put("John", 25); + ages.put("Freddy", 24); + ages.put("Samuel", 30); + + ages.forEach((name, age) -> LOG.debug(name + " is " + age + " years old")); + } + + @Test + public void whenUsingPredicateInFilter_thenListValuesAreFilteredOut() { + List names = Arrays.asList("Angela", "Aaron", "Bob", "Claire", "David"); + + List namesWithA = names.stream() + .filter(name -> name.startsWith("A")) + .collect(Collectors.toList()); + + assertEquals(2, namesWithA.size()); + assertTrue(namesWithA.contains("Angela")); + assertTrue(namesWithA.contains("Aaron")); + } + + @Test + public void whenUsingUnaryOperatorWithReplaceAll_thenAllValuesInTheListAreReplaced() { + List names = Arrays.asList("bob", "josh", "megan"); + + names.replaceAll(String::toUpperCase); + + assertEquals("BOB", names.get(0)); + assertEquals("JOSH", names.get(1)); + assertEquals("MEGAN", names.get(2)); + } + + @Test + public void whenUsingBinaryOperatorWithStreamReduce_thenResultIsSumOfValues() { + + List values = Arrays.asList(3, 5, 8, 9, 12); + + int sum = values.stream() + .reduce(0, (i1, i2) -> i1 + i2); + + assertEquals(37, sum); + + } + + @Test + public void whenComposingTwoFunctions_thenFunctionsExecuteSequentially() { + + Function intToString = Object::toString; + Function quote = s -> "'" + s + "'"; + + Function quoteIntToString = quote.compose(intToString); + + assertEquals("'5'", quoteIntToString.apply(5)); + + } + + @Test + public void whenUsingSupplierToGenerateValue_thenValueIsGeneratedLazily() { + + Supplier lazyValue = () -> { + Uninterruptibles.sleepUninterruptibly(1000, TimeUnit.MILLISECONDS); + return 9d; + }; + + double valueSquared = squareLazy(lazyValue); + + assertEquals(81d, valueSquared, 0); + + } + + // + + public double squareLazy(Supplier lazyValue) { + return Math.pow(lazyValue.get(), 2); + } + + public byte[] transformArray(short[] array, ShortToByteFunction function) { + byte[] transformedArray = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + transformedArray[i] = function.applyAsByte(array[i]); + } + return transformedArray; + } + +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/functionalinterface/ShortToByteFunction.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/functionalinterface/ShortToByteFunction.java new file mode 100644 index 0000000000..ce34c74e18 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/functionalinterface/ShortToByteFunction.java @@ -0,0 +1,8 @@ +package com.ossez.functionalinterface; + +@FunctionalInterface +public interface ShortToByteFunction { + + byte applyAsByte(short s); + +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/Java8SortUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/Java8SortUnitTest.java new file mode 100644 index 0000000000..0ba3e63eaf --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/Java8SortUnitTest.java @@ -0,0 +1,210 @@ +package com.ossez.java8; + +import com.ossez.java8.entity.Human; +import com.google.common.collect.Lists; +import com.google.common.primitives.Ints; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import static org.hamcrest.Matchers.equalTo; + +public class Java8SortUnitTest { + + // tests - + + @Test + public final void givenPreLambda_whenSortingEntitiesByName_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + + Collections.sort(humans, new Comparator() { + @Override + public final int compare(final Human h1, final Human h2) { + return h1.getName().compareTo(h2.getName()); + } + }); + + Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12))); + } + + @Test + public final void whenSortingEntitiesByName_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + + humans.sort((final Human h1, final Human h2) -> h1.getName().compareTo(h2.getName())); + + Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12))); + } + + @Test + public final void givenLambdaShortForm_whenSortingEntitiesByName_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + + humans.sort((h1, h2) -> h1.getName().compareTo(h2.getName())); + + Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12))); + } + + @Test + public final void whenSortingEntitiesByNameThenAge_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 12), new Human("Sarah", 10), new Human("Zack", 12)); + humans.sort((lhs, rhs) -> { + if (lhs.getName().equals(rhs.getName())) { + return Integer.compare(lhs.getAge(), rhs.getAge()); + } else { + return lhs.getName().compareTo(rhs.getName()); + } + }); + Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10))); + } + + @Test + public final void givenCompositionVerbose_whenSortingEntitiesByNameThenAge_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 12), new Human("Sarah", 10), new Human("Zack", 12)); + final Comparator byName = (h1, h2) -> h1.getName().compareTo(h2.getName()); + final Comparator byAge = (h1, h2) -> Ints.compare(h1.getAge(), h2.getAge()); + + humans.sort(byName.thenComparing(byAge)); + Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10))); + } + + @Test + public final void givenComposition_whenSortingEntitiesByNameThenAge_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 12), new Human("Sarah", 10), new Human("Zack", 12)); + + humans.sort(Comparator.comparing(Human::getName).thenComparing(Human::getAge)); + Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10))); + } + + @Test + public final void whenSortingEntitiesByAge_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + + humans.sort((h1, h2) -> Ints.compare(h1.getAge(), h2.getAge())); + Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10))); + } + + @Test + public final void whenSortingEntitiesByNameReversed_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + final Comparator comparator = (h1, h2) -> h1.getName().compareTo(h2.getName()); + + humans.sort(comparator.reversed()); + Assert.assertThat(humans.get(0), equalTo(new Human("Sarah", 10))); + } + + @Test + public final void givenMethodDefinition_whenSortingEntitiesByNameThenAge_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + + humans.sort(Human::compareByNameThenAge); + Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12))); + } + + @Test + public final void givenInstanceMethod_whenSortingEntitiesByName_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + + humans.sort(Comparator.comparing(Human::getName)); + Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12))); + } + + @Test + public final void givenStreamNaturalOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { + final List letters = Lists.newArrayList("B", "A", "C"); + + final List sortedLetters = letters.stream().sorted().collect(Collectors.toList()); + Assert.assertThat(sortedLetters.get(0), equalTo("A")); + } + + @Test + public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + final Comparator nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName()); + + final List sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList()); + Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12))); + } + + @Test + public final void givenStreamComparatorOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + + final List sortedHumans = humans.stream().sorted(Comparator.comparing(Human::getName)).collect(Collectors.toList()); + Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12))); + } + + @Test + public final void givenStreamNaturalOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() { + final List letters = Lists.newArrayList("B", "A", "C"); + + final List reverseSortedLetters = letters.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()); + Assert.assertThat(reverseSortedLetters.get(0), equalTo("C")); + } + + @Test + public final void givenStreamCustomOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + final Comparator reverseNameComparator = (h1, h2) -> h2.getName().compareTo(h1.getName()); + + final List reverseSortedHumans = humans.stream().sorted(reverseNameComparator).collect(Collectors.toList()); + Assert.assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10))); + } + + @Test + public final void givenStreamComparatorOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() { + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + + final List reverseSortedHumans = humans.stream().sorted(Comparator.comparing(Human::getName, Comparator.reverseOrder())).collect(Collectors.toList()); + Assert.assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10))); + } + + @Test(expected = NullPointerException.class) + public final void givenANullElement_whenSortingEntitiesByName_thenThrowsNPE() { + final List humans = Lists.newArrayList(null, new Human("Jack", 12)); + + humans.sort((h1, h2) -> h1.getName().compareTo(h2.getName())); + } + + @Test + public final void givenANullElement_whenSortingEntitiesByNameManually_thenMovesTheNullToLast() { + final List humans = Lists.newArrayList(null, new Human("Jack", 12), null); + + humans.sort((h1, h2) -> { + if (h1 == null) return h2 == null ? 0 : 1; + else if (h2 == null) return -1; + + return h1.getName().compareTo(h2.getName()); + }); + + Assert.assertNotNull(humans.get(0)); + Assert.assertNull(humans.get(1)); + Assert.assertNull(humans.get(2)); + } + + @Test + public final void givenANullElement_whenSortingEntitiesByName_thenMovesTheNullToLast() { + final List humans = Lists.newArrayList(null, new Human("Jack", 12), null); + + humans.sort(Comparator.nullsLast(Comparator.comparing(Human::getName))); + + Assert.assertNotNull(humans.get(0)); + Assert.assertNull(humans.get(1)); + Assert.assertNull(humans.get(2)); + } + + @Test + public final void givenANullElement_whenSortingEntitiesByName_thenMovesTheNullToStart() { + final List humans = Lists.newArrayList(null, new Human("Jack", 12), null); + + humans.sort(Comparator.nullsFirst(Comparator.comparing(Human::getName))); + + Assert.assertNull(humans.get(0)); + Assert.assertNull(humans.get(1)); + Assert.assertNotNull(humans.get(2)); + } +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java new file mode 100644 index 0000000000..d23ec4caf9 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java @@ -0,0 +1,50 @@ +package com.ossez.java8.lambda.exceptions; + +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import static com.ossez.java8.lambda.exceptions.LambdaExceptionWrappers.*; + +public class LambdaExceptionWrappersUnitTest { + + private static final Logger LOG = LoggerFactory.getLogger(LambdaExceptionWrappersUnitTest.class); + + private List integers; + + @Before + public void init() { + integers = Arrays.asList(3, 9, 7, 0, 10, 20); + } + + @Test + public void whenNoExceptionFromLambdaWrapper_thenSuccess() { + integers.forEach(lambdaWrapper(i -> LOG.debug("{}", 50 / i))); + } + + @Test + public void whenNoExceptionFromConsumerWrapper_thenSuccess() { + integers.forEach(consumerWrapper(i -> LOG.debug("{}", 50 / i), ArithmeticException.class)); + } + + @Test(expected = RuntimeException.class) + public void whenExceptionFromThrowingConsumerWrapper_thenSuccess() { + integers.forEach(throwingConsumerWrapper(i -> writeToFile(i))); + } + + @Test + public void whenNoExceptionFromHandlingConsumerWrapper_thenSuccess() { + integers.forEach(handlingConsumerWrapper(i -> writeToFile(i), IOException.class)); + } + + private void writeToFile(Integer i) throws IOException { + if (i == 0) { + throw new IOException(); // mock IOException + } + } +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/Bicycle.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/Bicycle.java new file mode 100644 index 0000000000..a83d76faae --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/Bicycle.java @@ -0,0 +1,34 @@ +package com.ossez.java8.lambda.methodreference; + +public class Bicycle { + + private String brand; + private Integer frameSize; + + public Bicycle(String brand) { + this.brand = brand; + this.frameSize = 0; + } + + public Bicycle(String brand, Integer frameSize) { + this.brand = brand; + this.frameSize = frameSize; + } + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + public Integer getFrameSize() { + return frameSize; + } + + public void setFrameSize(Integer frameSize) { + this.frameSize = frameSize; + } + +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/BicycleComparator.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/BicycleComparator.java new file mode 100644 index 0000000000..4406ef4faa --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/BicycleComparator.java @@ -0,0 +1,13 @@ +package com.ossez.java8.lambda.methodreference; + +import java.util.Comparator; + +public class BicycleComparator implements Comparator { + + @Override + public int compare(Bicycle a, Bicycle b) { + return a.getFrameSize() + .compareTo(b.getFrameSize()); + } + +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/MethodReferenceUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/MethodReferenceUnitTest.java new file mode 100644 index 0000000000..f3cc99951e --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/methodreference/MethodReferenceUnitTest.java @@ -0,0 +1,79 @@ +package com.ossez.java8.lambda.methodreference; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MethodReferenceUnitTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(MethodReferenceUnitTest.class); + + private static void doNothingAtAll(Object... o) { + } + + @Test + public void referenceToStaticMethod() { + List messages = Arrays.asList("Hello", "Baeldung", "readers!"); + messages.forEach(word -> StringUtils.capitalize(word)); + messages.forEach(StringUtils::capitalize); + } + + @Test + public void referenceToInstanceMethodOfParticularObject() { + BicycleComparator bikeFrameSizeComparator = new BicycleComparator(); + createBicyclesList().stream() + .sorted((a, b) -> bikeFrameSizeComparator.compare(a, b)); + createBicyclesList().stream() + .sorted(bikeFrameSizeComparator::compare); + } + + @Test + public void referenceToInstanceMethodOfArbitratyObjectOfParticularType() { + List numbers = Arrays.asList(5, 3, 50, 24, 40, 2, 9, 18); + numbers.stream() + .sorted((a, b) -> a.compareTo(b)); + numbers.stream() + .sorted(Integer::compareTo); + } + + @Test + public void referenceToConstructor() { + BiFunction bikeCreator = (brand, frameSize) -> new Bicycle(brand, frameSize); + BiFunction bikeCreatorMethodReference = Bicycle::new; + List bikes = new ArrayList<>(); + bikes.add(bikeCreator.apply("Giant", 50)); + bikes.add(bikeCreator.apply("Scott", 20)); + bikes.add(bikeCreatorMethodReference.apply("Trek", 35)); + bikes.add(bikeCreatorMethodReference.apply("GT", 40)); + } + + @Test + public void referenceToConstructorSimpleExample() { + List bikeBrands = Arrays.asList("Giant", "Scott", "Trek", "GT"); + bikeBrands.stream() + .map(Bicycle::new) + .toArray(Bicycle[]::new); + } + + @Test + public void limitationsAndAdditionalExamples() { + createBicyclesList().forEach(b -> LOGGER.debug("Bike brand is '{}' and frame size is '{}'", b.getBrand(), b.getFrameSize())); + createBicyclesList().forEach((o) -> MethodReferenceUnitTest.doNothingAtAll(o)); + } + + private List createBicyclesList() { + List bikes = new ArrayList<>(); + bikes.add(new Bicycle("Giant", 50)); + bikes.add(new Bicycle("Scott", 20)); + bikes.add(new Bicycle("Trek", 35)); + bikes.add(new Bicycle("GT", 40)); + return bikes; + } + +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java new file mode 100644 index 0000000000..19d7b5a8ae --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/ossez/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java @@ -0,0 +1,94 @@ +package com.ossez.java8.lambda.tips; + +import com.ossez.java8.lambda.tips.Foo; +import com.ossez.java8.lambda.tips.FooExtended; +import com.ossez.java8.lambda.tips.UseFoo; +import org.junit.Before; +import org.junit.Test; + +import java.util.function.Function; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class Java8FunctionalInteracesLambdasUnitTest { + + private UseFoo useFoo; + + @Before + public void init() { + useFoo = new UseFoo(); + } + + @Test + public void functionalInterfaceInstantiation_whenReturnDefiniteString_thenCorrect() { + final Foo foo = parameter -> parameter + "from lambda"; + final String result = useFoo.add("Message ", foo); + + assertEquals("Message from lambda", result); + } + + @Test + public void standardFIParameter_whenReturnDefiniteString_thenCorrect() { + final Function fn = parameter -> parameter + "from lambda"; + final String result = useFoo.addWithStandardFI("Message ", fn); + + assertEquals("Message from lambda", result); + } + + @Test + public void defaultMethodFromExtendedInterface_whenReturnDefiniteString_thenCorrect() { + final FooExtended fooExtended = string -> string; + final String result = fooExtended.defaultCommon(); + + assertEquals("Default Common from Bar", result); + } + + @Test + public void lambdaAndInnerClassInstantiation_whenReturnSameString_thenCorrect() { + final Foo foo = parameter -> parameter + "from Foo"; + + final Foo fooByIC = new Foo() { + @Override + public String method(final String string) { + return string + "from Foo"; + } + }; + + assertEquals(foo.method("Something "), fooByIC.method("Something ")); + } + + @Test + public void accessVariablesFromDifferentScopes_whenReturnPredefinedString_thenCorrect() { + assertEquals("Results: resultIC = Inner class value, resultLambda = Enclosing scope value", useFoo.scopeExperiment()); + } + + @Test + public void shorteningLambdas_whenReturnEqualsResults_thenCorrect() { + final Foo foo = parameter -> buildString(parameter); + + final Foo fooHuge = parameter -> { + final String result = "Something " + parameter; + // many lines of code + return result; + }; + + assertEquals(foo.method("Something"), fooHuge.method("Something")); + } + + private String buildString(final String parameter) { + final String result = "Something " + parameter; + // many lines of code + return result; + } + + @Test + public void mutatingOfEffectivelyFinalVariable_whenNotEquals_thenCorrect() { + final int[] total = new int[1]; + final Runnable r = () -> total[0]++; + r.run(); + + assertNotEquals(0, total[0]); + } + +} diff --git a/core-java-modules/core-java-uuid/src/main/resources/log4jstructuraldp.properties b/core-java-modules/core-java-uuid/src/main/resources/log4jstructuraldp.properties new file mode 100644 index 0000000000..5bc2bfe4b9 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/main/resources/log4jstructuraldp.properties @@ -0,0 +1,9 @@ + +# Root logger +log4j.rootLogger=INFO, file, stdout + +# Write to console +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/core-java-modules/core-java-uuid/src/main/resources/logback.xml b/core-java-modules/core-java-uuid/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/core-java-modules/core-java-uuid/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %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-uuid/src/test/java/com/ossez/uuid/DecodeUUIDStringFromBase64UnitTest.java b/core-java-modules/core-java-uuid/src/test/java/com/ossez/uuid/DecodeUUIDStringFromBase64UnitTest.java new file mode 100644 index 0000000000..a0fffb1027 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/test/java/com/ossez/uuid/DecodeUUIDStringFromBase64UnitTest.java @@ -0,0 +1,64 @@ +package com.ossez.uuid; + +import static org.apache.commons.codec.binary.Base64.decodeBase64; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.nio.ByteBuffer; +import java.util.Base64; +import java.util.UUID; + +import org.apache.commons.lang3.Conversion; +import org.junit.jupiter.api.Test; + +public class DecodeUUIDStringFromBase64UnitTest { + private final UUID originalUUID = UUID.fromString("cc5f93f7-8cf1-4a51-83c6-e740313a0c6c"); + + @Test + public void givenEncodedString_whenDecodingUsingBase64Decoder_thenGiveExpectedUUID() { + String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw"; + byte[] decodedBytes = Base64.getDecoder() + .decode(expectedEncodedString); + UUID uuid = convertToUUID(decodedBytes); + assertEquals(originalUUID, uuid); + } + + @Test + public void givenEncodedString_whenDecodingUsingByteBufferAndBase64UrlDecoder_thenGiveExpectedUUID() { + String expectedEncodedString = "zF-T94zxSlGDxudAMToMbA"; + byte[] decodedBytes = Base64.getUrlDecoder() + .decode(expectedEncodedString); + ByteBuffer byteBuffer = ByteBuffer.wrap(decodedBytes); + long mostSignificantBits = byteBuffer.getLong(); + long leastSignificantBits = byteBuffer.getLong(); + UUID uuid = new UUID(mostSignificantBits, leastSignificantBits); + assertEquals(originalUUID, uuid); + } + + @Test + public void givenEncodedString_whenDecodingUsingApacheUtils_thenGiveExpectedUUID() { + String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw"; + byte[] decodedBytes = decodeBase64(expectedEncodedString); + UUID uuid = Conversion.byteArrayToUuid(decodedBytes, 0); + assertEquals(originalUUID, uuid); + } + + private UUID convertToUUID(byte[] src) { + long mostSignificantBits = convertBytesToLong(src, 0); + long leastSignificantBits = convertBytesToLong(src, 8); + + return new UUID(mostSignificantBits, leastSignificantBits); + } + + private long convertBytesToLong(byte[] uuidBytes, int start) { + long result = 0; + + for(int i = 0; i < 8; i++) { + int shift = i * 8; + long bits = (255L & (long)uuidBytes[i + start]) << shift; + long mask = 255L << shift; + result = result & ~mask | bits; + } + + return result; + } +} diff --git a/core-java-modules/core-java-uuid/src/test/java/com/ossez/uuid/EncodeUUIDToBase64StringUnitTest.java b/core-java-modules/core-java-uuid/src/test/java/com/ossez/uuid/EncodeUUIDToBase64StringUnitTest.java new file mode 100644 index 0000000000..d8f1b4a13f --- /dev/null +++ b/core-java-modules/core-java-uuid/src/test/java/com/ossez/uuid/EncodeUUIDToBase64StringUnitTest.java @@ -0,0 +1,62 @@ +package com.ossez.uuid; + +import static org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.nio.ByteBuffer; +import java.util.Base64; +import java.util.UUID; + +import org.apache.commons.lang3.Conversion; +import org.junit.jupiter.api.Test; + +public class EncodeUUIDToBase64StringUnitTest { + private final UUID originalUUID = UUID.fromString("cc5f93f7-8cf1-4a51-83c6-e740313a0c6c"); + + @Test + public void givenUUID_whenEncodingUsingBase64Encoder_thenGiveExpectedEncodedString() { + String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw"; + byte[] uuidBytes = convertToByteArray(originalUUID); + String encodedUUID = Base64.getEncoder().withoutPadding() + .encodeToString(uuidBytes); + assertEquals(expectedEncodedString, encodedUUID); + } + + @Test + public void givenUUID_whenEncodingUsingByteBufferAndBase64UrlEncoder_thenGiveExpectedEncodedString() { + String expectedEncodedString = "zF-T94zxSlGDxudAMToMbA"; + ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]); + byteBuffer.putLong(originalUUID.getMostSignificantBits()); + byteBuffer.putLong(originalUUID.getLeastSignificantBits()); + String encodedUUID = Base64.getUrlEncoder().withoutPadding() + .encodeToString(byteBuffer.array()); + assertEquals(expectedEncodedString, encodedUUID); + } + + @Test + public void givenUUID_whenEncodingUsingApacheUtils_thenGiveExpectedEncodedString() { + String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw"; + byte[] bytes = Conversion.uuidToByteArray(originalUUID, new byte[16], 0, 16); + String encodedUUID = encodeBase64URLSafeString(bytes); + assertEquals(expectedEncodedString, encodedUUID); + } + + private byte[] convertToByteArray(UUID uuid) { + byte[] result = new byte[16]; + + long mostSignificantBits = uuid.getMostSignificantBits(); + fillByteArray(0, 8, result, mostSignificantBits); + + long leastSignificantBits = uuid.getLeastSignificantBits(); + fillByteArray(8, 16, result, leastSignificantBits); + + return result; + } + + private static void fillByteArray(int start, int end, byte[] result, long bits) { + for (int i = start; i < end; i++) { + int shift = i * 8; + result[i] = (byte) ((int) (255L & bits >> shift)); + } + } +} diff --git a/core-java-modules/core-java-uuid/src/test/java/com/ossez/uuid/UUIDPositiveLongGeneratorUnitTest.java b/core-java-modules/core-java-uuid/src/test/java/com/ossez/uuid/UUIDPositiveLongGeneratorUnitTest.java new file mode 100644 index 0000000000..e16c866c34 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/test/java/com/ossez/uuid/UUIDPositiveLongGeneratorUnitTest.java @@ -0,0 +1,22 @@ +package com.ossez.uuid; + +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UUIDPositiveLongGeneratorUnitTest { + + @Test + public void whenGetMostSignificantBits_thenAssertPositive() { + long randomPositiveLong = Math.abs(UUID.randomUUID().getMostSignificantBits()); + assertThat(randomPositiveLong).isNotNegative(); + } + + @Test + public void whenGetLeastSignificantBits_thenAssertPositive() { + long randomPositiveLong = Math.abs(UUID.randomUUID().getLeastSignificantBits()); + assertThat(randomPositiveLong).isNotNegative(); + } +} diff --git a/core-java-modules/core-java-uuid/src/test/resources/logback.xml b/core-java-modules/core-java-uuid/src/test/resources/logback.xml new file mode 100644 index 0000000000..a076f8db47 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/test/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + \ No newline at end of file diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index cfb968235b..9a5afb75d8 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -27,11 +27,11 @@ core-java-collections-conversions core-java-collections-conversions-2 core-java-collections-list - core-java-collections-list-2 core-java-collections-list-3 core-java-datetime-conversion core-java-io core-java-io-2 + core-java-lambdas core-java-serialization core-java-streams core-java-streams