Merge pull request #81 from eugenp/master

update
This commit is contained in:
Maiklins 2021-01-31 12:56:34 +01:00 committed by GitHub
commit 39c0b3811a
725 changed files with 5412 additions and 1665 deletions

View File

@ -89,7 +89,6 @@
<properties>
<json-simple.version>1.1.1</json-simple.version>
<commons-io.version>2.5</commons-io.version>
<aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version>
<aws-lambda-java-core.version>1.2.0</aws-lambda-java-core.version>
<gson.version>2.8.2</gson.version>

View File

@ -154,7 +154,6 @@
<properties>
<blade-mvc.version>2.0.14.RELEASE</blade-mvc.version>
<bootstrap.version>4.2.1</bootstrap.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<lombok.version>1.18.4</lombok.version>
<httpclient.version>4.5.6</httpclient.version>
<httpmime.version>4.5.6</httpmime.version>

View File

@ -6,3 +6,4 @@ This module contains articles about Java 11 core features
- [Guide to Java 8 Optional](https://www.baeldung.com/java-optional)
- [Guide to Java Reflection](http://www.baeldung.com/java-reflection)
- [Guide to Java 8s Collectors](https://www.baeldung.com/java-8-collectors)
- [New Features in Java 11](https://www.baeldung.com/java-11-new-features)

View File

@ -28,6 +28,29 @@
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-junit-jupiter</artifactId>
<version>${mockserver.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -48,7 +71,9 @@
<maven.compiler.source.version>11</maven.compiler.source.version>
<maven.compiler.target.version>11</maven.compiler.target.version>
<guava.version>29.0-jre</guava.version>
<junit.jupiter.version>5.7.0</junit.jupiter.version>
<assertj.version>3.17.2</assertj.version>
<mockserver.version>5.11.1</mockserver.version>
</properties>
</project>

View File

@ -0,0 +1,17 @@
package com.baeldung.features;
public class MainClass {
private static boolean mainPrivateMethod() {
return true;
}
public static class NestedClass {
boolean nestedPublicMethod() {
return mainPrivateMethod();
}
}
}

View File

@ -0,0 +1,54 @@
package com.baeldung.features;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.model.HttpStatusCode;
import org.mockserver.socket.PortFactory;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
class HttpClientIntegrationTest {
private static ClientAndServer mockServer;
private static int port;
@BeforeAll
static void startServer() {
port = PortFactory.findFreePort();
mockServer = startClientAndServer(port);
mockServer.when(new org.mockserver.model.HttpRequest().withMethod("GET"))
.respond(new org.mockserver.model.HttpResponse()
.withStatusCode(HttpStatusCode.OK_200.code())
.withBody("Hello from the server!"));
}
@AfterAll
static void stopServer() {
mockServer.stop();
}
@Test
void givenSampleHttpRequest_whenRequestIsSent_thenServerResponseIsReceived() throws IOException, InterruptedException {
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(20))
.build();
HttpRequest httpRequest = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:" + port))
.build();
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
assertThat(httpResponse.body()).isEqualTo("Hello from the server!");
}
}

View File

@ -0,0 +1,61 @@
package com.baeldung.features;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
class JavaElevenFeaturesUnitTest {
@Test
void givenMultilineString_whenExtractingNonBlankStrippedLines_thenLinesAreReturned() {
String multilineString = "Baeldung helps \n \n developers \n explore Java.";
List<String> lines = multilineString.lines()
.filter(line -> !line.isBlank())
.map(String::strip)
.collect(Collectors.toList());
assertThat(lines).containsExactly("Baeldung helps", "developers", "explore Java.");
}
@Test
void givenTemporaryFile_whenReadingStringContent_thenContentIsReturned(@TempDir Path tempDir) throws IOException {
Path filePath = Files.writeString(Files.createTempFile(tempDir, "demo", ".txt"), "Sample text");
String fileContent = Files.readString(filePath);
assertThat(fileContent).isEqualTo("Sample text");
}
@Test
void givenSampleList_whenConvertingToArray_thenItemsRemainUnchanged() {
List<String> sampleList = Arrays.asList("Java", "Kotlin");
String[] sampleArray = sampleList.toArray(String[]::new);
assertThat(sampleArray).containsExactly("Java", "Kotlin");
}
@Test
void givenSampleList_whenConvertingToUppercaseString_thenUppercaseIsReturned() {
List<String> sampleList = Arrays.asList("Java", "Kotlin");
String resultString = sampleList.stream()
.map((@Nonnull var x) -> x.toUpperCase())
.collect(Collectors.joining(", "));
assertThat(resultString).isEqualTo("JAVA, KOTLIN");
}
@Test
void givenSampleList_whenExtractingNonBlankValues_thenOnlyNonBlanksAreReturned() {
List<String> sampleList = Arrays.asList("Java", "\n \n", "Kotlin", " ");
List<String> withoutBlanks = sampleList.stream()
.filter(Predicate.not(String::isBlank))
.collect(Collectors.toList());
assertThat(withoutBlanks).containsExactly("Java", "Kotlin");
}
}

View File

@ -0,0 +1,37 @@
package com.baeldung.features;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
class NestedClassesUnitTest {
@Test
public void giveNestedClass_whenCallingMainClassPrivateMethod_thenNoExceptionIsThrown() {
MainClass.NestedClass nestedInstance = new MainClass.NestedClass();
assertThat(nestedInstance.nestedPublicMethod()).isTrue();
}
@Test
public void giveNestedClass_whenCheckingNestmate_thenNestedClassIsReturned() {
assertThat(MainClass.class.isNestmateOf(MainClass.NestedClass.class)).isTrue();
}
@Test
public void giveNestedClass_whenCheckingNestHost_thenMainClassIsReturned() {
assertThat(MainClass.NestedClass.class.getNestHost()).isEqualTo(MainClass.class);
}
@Test
public void giveNestedClass_whenCheckingNestMembers_thenNestMembersAreReturned() {
Set<String> nestedMembers = Arrays.stream(MainClass.NestedClass.class.getNestMembers())
.map(Class::getName)
.collect(Collectors.toSet());
assertThat(nestedMembers).contains(MainClass.class.getName(), MainClass.NestedClass.class.getName());
}
}

View File

@ -2,3 +2,4 @@
- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)
- [Java 12 New Features](https://www.baeldung.com/java-12-new-features)

View File

@ -0,0 +1,21 @@
package java.com.baeldung.newfeatures;
import org.junit.Test;
import java.text.NumberFormat;
import java.util.Locale;
import static org.junit.Assert.assertEquals;
public class CompactNumbersUnitTest {
@Test
public void givenNumber_thenCompactValues() {
NumberFormat likesShort = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.SHORT);
likesShort.setMaximumFractionDigits(2);
assertEquals("2.59K", likesShort.format(2592));
NumberFormat likesLong = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.LONG);
likesLong.setMaximumFractionDigits(2);
assertEquals("2.59 thousand", likesShort.format(2592));
}
}

View File

@ -0,0 +1,32 @@
package java.com.baeldung.newfeatures;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.Assert.assertEquals;
public class FileMismatchUnitTest {
@Test
public void givenIdenticalFiles_thenShouldNotFindMismatch() throws IOException {
Path filePath1 = Files.createTempFile("file1", ".txt");
Path filePath2 = Files.createTempFile("file2", ".txt");
Files.writeString(filePath1, "Java 12 Article");
Files.writeString(filePath2, "Java 12 Article");
long mismatch = Files.mismatch(filePath1, filePath2);
assertEquals(-1, mismatch);
}
@Test
public void givenDifferentFiles_thenShouldFindMismatch() throws IOException {
Path filePath3 = Files.createTempFile("file3", ".txt");
Path filePath4 = Files.createTempFile("file4", ".txt");
Files.writeString(filePath3, "Java 12 Article");
Files.writeString(filePath4, "Java 12 Tutorial");
long mismatch = Files.mismatch(filePath3, filePath4);
assertEquals(8, mismatch);
}
}

View File

@ -0,0 +1,15 @@
package java.com.baeldung.newfeatures;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class StringUnitTest {
@Test
public void givenString_thenRevertValue() {
String text = "Baeldung";
String transformed = text.transform(value -> new StringBuilder(value).reverse().toString());
assertEquals("gnudleaB", transformed);
}
}

View File

@ -0,0 +1,18 @@
package java.com.baeldung.newfeatures;
import org.junit.Test;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
public class TeeingCollectorUnitTest {
@Test
public void givenSetOfNumbers_thenCalculateAverage() {
double mean = Stream.of(1, 2, 3, 4, 5)
.collect(Collectors.teeing(Collectors.summingDouble(i -> i), Collectors.counting(), (sum, count) -> sum / count));
assertEquals(3.0, mean);
}
}

View File

@ -20,7 +20,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache-commons-lang3.version}</version>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
@ -68,7 +68,6 @@
<properties>
<maven.compiler.release>15</maven.compiler.release>
<apache-commons-lang3.version>3.11</apache-commons-lang3.version>
<assertj.version>3.17.2</assertj.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<surefire.plugin.version>3.0.0-M3</surefire.plugin.version>

View File

@ -47,12 +47,12 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.7</version>
<version>${commons-io.version}</version>
</dependency>
</dependencies>

View File

@ -29,8 +29,6 @@
</dependencies>
<properties>
<commons-lang3.version>3.9</commons-lang3.version>
<assertj-core.version>3.10.0</assertj-core.version>
</properties>
</project>

View File

@ -68,11 +68,7 @@
<properties>
<shade.plugin.version>3.2.0</shade.plugin.version>
<commons-lang3.version>3.9</commons-lang3.version>
<jmh.version>1.19</jmh.version>
<assertj-core.version>3.10.0</assertj-core.version>
</properties>
</project>

View File

@ -76,12 +76,8 @@
<properties>
<shade.plugin.version>3.2.0</shade.plugin.version>
<commons-lang3.version>3.9</commons-lang3.version>
<guava.version>28.2-jre</guava.version>
<jmh.version>1.19</jmh.version>
<assertj-core.version>3.10.0</assertj-core.version>
</properties>
</project>

View File

@ -3,4 +3,4 @@
This module contains articles about Java Character Class
### Relevant Articles:
- Character#isAlphabetic vs Character#isLetter
- [Character#isAlphabetic vs Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic)

View File

@ -35,7 +35,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
<version>${commons-lang3.version}</version>
</dependency>
</dependencies>

View File

@ -36,7 +36,6 @@
<properties>
<commons-collections4.version>4.1</commons-collections4.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<assertj.version>3.11.1</assertj.version>
</properties>

View File

@ -10,11 +10,17 @@ import org.openjdk.jcstress.annotations.Outcome;
import org.openjdk.jcstress.annotations.State;
import org.openjdk.jcstress.infra.results.I_Result;
/**
* This is defined as a manual test because it tries to simulate the race conditions
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
* This will help the CI jobs to ignore these tests and a developer to run them manually.
*
*/
@JCStressTest
@Outcome(id = "1", expect = ACCEPTABLE_INTERESTING, desc = "One update lost.")
@Outcome(id = "2", expect = ACCEPTABLE, desc = "Both updates.")
@State
public class MyCounterJCStressUnitTest {
public class MyCounterJCStressManualTest {
private MyCounter counter;

View File

@ -1,12 +1,17 @@
package com.baeldung.concurrent;
import org.junit.Ignore;
import org.junit.Test;
import edu.umd.cs.mtc.MultithreadedTestCase;
import edu.umd.cs.mtc.TestFramework;
public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
/**
* This is defined as a manual test because it tries to simulate the race conditions
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
* This will help the CI jobs to ignore these tests and a developer to run them manually.
*
*/
public class MyCounterMultithreadedTCManualTest extends MultithreadedTestCase {
private MyCounter counter;
@ -29,9 +34,8 @@ public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
assertEquals(2, counter.getCount());
}
@Ignore
@Test
public void testCounter() throws Throwable {
TestFramework.runManyTimes(new MyCounterMultithreadedTCUnitTest(), 1000);
TestFramework.runManyTimes(new MyCounterMultithreadedTCManualTest(), 1000);
}
}

View File

@ -0,0 +1,63 @@
package com.baeldung.concurrent;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
/**
* This is defined as a manual test because it tries to simulate the race conditions
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
* This will help the CI jobs to ignore these tests and a developer to run them manually.
*
*/
public class MyCounterSimpleManualTest {
@Test
public void testCounter() {
MyCounter counter = new MyCounter();
for (int i = 0; i < 500; i++)
counter.increment();
assertEquals(500, counter.getCount());
}
@Test
public void testCounterWithConcurrency() throws InterruptedException {
int numberOfThreads = 100;
ExecutorService service = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(numberOfThreads);
MyCounter counter = new MyCounter();
for (int i = 0; i < numberOfThreads; i++) {
service.execute(() -> {
counter.increment();
latch.countDown();
});
}
latch.await();
assertEquals(numberOfThreads, counter.getCount());
}
@Test
public void testSummationWithConcurrencyAndWait() throws InterruptedException {
int numberOfThreads = 2;
ExecutorService service = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(numberOfThreads);
MyCounter counter = new MyCounter();
for (int i = 0; i < numberOfThreads; i++) {
service.submit(() -> {
try {
counter.incrementWithWait();
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
});
}
latch.await();
assertEquals(numberOfThreads, counter.getCount());
}
}

View File

@ -1,60 +0,0 @@
package com.baeldung.concurrent;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Ignore;
import org.junit.Test;
public class MyCounterSimpleUnitTest {
@Test
public void testCounter() {
MyCounter counter = new MyCounter();
for (int i = 0; i < 500; i++)
counter.increment();
assertEquals(500, counter.getCount());
}
@Ignore
@Test
public void testCounterWithConcurrency() throws InterruptedException {
int numberOfThreads = 100;
ExecutorService service = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(numberOfThreads);
MyCounter counter = new MyCounter();
for (int i = 0; i < numberOfThreads; i++) {
service.execute(() -> {
counter.increment();
latch.countDown();
});
}
latch.await();
assertEquals(numberOfThreads, counter.getCount());
}
@Ignore
@Test
public void testSummationWithConcurrencyAndWait() throws InterruptedException {
int numberOfThreads = 2;
ExecutorService service = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(numberOfThreads);
MyCounter counter = new MyCounter();
for (int i = 0; i < numberOfThreads; i++) {
service.submit(() -> {
try {
counter.incrementWithWait();
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
});
}
latch.await();
assertEquals(numberOfThreads, counter.getCount());
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.concurrent;
import static org.junit.Assert.assertEquals;
import org.junit.AfterClass;
import org.junit.Rule;
import org.junit.Test;
import com.google.code.tempusfugit.concurrency.ConcurrentRule;
import com.google.code.tempusfugit.concurrency.RepeatingRule;
import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
import com.google.code.tempusfugit.concurrency.annotations.Repeating;
/**
* This is defined as a manual test because it tries to simulate the race conditions
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
* This will help the CI jobs to ignore these tests and a developer to run them manually.
*
*/
public class MyCounterTempusFugitManualTest {
@Rule
public ConcurrentRule concurrently = new ConcurrentRule();
@Rule
public RepeatingRule rule = new RepeatingRule();
private static MyCounter counter = new MyCounter();
@Test
@Concurrent(count = 2)
@Repeating(repetition = 10)
public void runsMultipleTimes() {
counter.increment();
}
@AfterClass
public static void annotatedTestRunsMultipleTimes() throws InterruptedException {
assertEquals(counter.getCount(), 20);
}
}

View File

@ -1,37 +0,0 @@
package com.baeldung.concurrent;
import static org.junit.Assert.assertEquals;
import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import com.google.code.tempusfugit.concurrency.ConcurrentRule;
import com.google.code.tempusfugit.concurrency.RepeatingRule;
import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
import com.google.code.tempusfugit.concurrency.annotations.Repeating;
public class MyCounterTempusFugitUnitTest {
@Rule
public ConcurrentRule concurrently = new ConcurrentRule();
@Rule
public RepeatingRule rule = new RepeatingRule();
private static MyCounter counter = new MyCounter();
@Ignore
@Test
@Concurrent(count = 2)
@Repeating(repetition = 10)
public void runsMultipleTimes() {
counter.increment();
}
@AfterClass
public static void annotatedTestRunsMultipleTimes() throws InterruptedException {
assertEquals(counter.getCount(), 20);
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.concurrent;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.google.testing.threadtester.AnnotatedTestRunner;
import com.google.testing.threadtester.ThreadedAfter;
import com.google.testing.threadtester.ThreadedBefore;
import com.google.testing.threadtester.ThreadedMain;
import com.google.testing.threadtester.ThreadedSecondary;
/**
* This is defined as a manual test because it tries to simulate the race conditions
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
* This will help the CI jobs to ignore these tests and a developer to run them manually.
*
*/
public class MyCounterThreadWeaverManualTest {
private MyCounter counter;
@ThreadedBefore
public void before() {
counter = new MyCounter();
}
@ThreadedMain
public void mainThread() {
counter.increment();
}
@ThreadedSecondary
public void secondThread() {
counter.increment();
}
@ThreadedAfter
public void after() {
assertEquals(2, counter.getCount());
}
@Test
public void testCounter() {
new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
}
}

View File

@ -1,44 +0,0 @@
package com.baeldung.concurrent;
import static org.junit.Assert.assertEquals;
import org.junit.Ignore;
import org.junit.Test;
import com.google.testing.threadtester.AnnotatedTestRunner;
import com.google.testing.threadtester.ThreadedAfter;
import com.google.testing.threadtester.ThreadedBefore;
import com.google.testing.threadtester.ThreadedMain;
import com.google.testing.threadtester.ThreadedSecondary;
public class MyCounterThreadWeaverUnitTest {
private MyCounter counter;
@ThreadedBefore
public void before() {
counter = new MyCounter();
}
@ThreadedMain
public void mainThread() {
counter.increment();
}
@ThreadedSecondary
public void secondThread() {
counter.increment();
}
@ThreadedAfter
public void after() {
assertEquals(2, counter.getCount());
}
@Ignore
@Test
public void testCounter() {
new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
}
}

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [Binary Semaphore vs Reentrant Lock](https://www.baeldung.com/java-binary-semaphore-vs-reentrant-lock)

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
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">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-concurrency-advanced-4</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>core-java-concurrency-advanced-4</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
</dependencies>
<build>
<finalName>core-java-concurrency-advanced-4</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>

View File

@ -0,0 +1,35 @@
package com.baeldung.synchronizationbadpractices;
public class AnimalBadPractice {
private String name;
private String owner;
public String getName() {
return name;
}
public String getOwner() {
return owner;
}
public synchronized void setName(String name) {
this.name = name;
}
public void setOwner(String owner) {
synchronized(this) {
this.owner = owner;
}
}
public AnimalBadPractice() {
}
public AnimalBadPractice(String name, String owner) {
this.name = name;
this.owner = owner;
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.synchronizationbadpractices;
public class AnimalSolution {
private final Object objLock1 = new Object();
private final Object objLock2 = new Object();
private String name;
private String owner;
public String getName() {
return name;
}
public String getOwner() {
return owner;
}
public void setName(String name) {
synchronized(objLock1) {
this.name = name;
}
}
public void setOwner(String owner) {
synchronized(objLock2) {
this.owner = owner;
}
}
public AnimalSolution() {
}
public AnimalSolution(String name, String owner) {
this.name = name;
this.owner = owner;
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.synchronizationbadpractices;
public class SynchronizationBadPracticeExample {
public void stringBadPractice1() {
String stringLock = "LOCK_STRING";
synchronized (stringLock) {
// ...
}
}
private final String stringLock = "LOCK_STRING";
public void stringBadPractice2() {
synchronized (stringLock) {
// ...
}
}
private final String internedStringLock = new String("LOCK_STRING").intern();
public void stringBadPractice3() {
synchronized (internedStringLock) {
// ...
}
}
private final Boolean booleanLock = Boolean.FALSE;
public void booleanBadPractice() {
synchronized (booleanLock) {
// ...
}
}
private int count = 0;
private final Integer intLock = count;
public void boxedPrimitiveBadPractice() {
synchronized (intLock) {
count++;
// ...
}
}
public void classBadPractice() throws InterruptedException {
AnimalBadPractice animalObj = new AnimalBadPractice("Tommy", "John");
synchronized(animalObj) {
while (true) {
Thread.sleep(Integer.MAX_VALUE);
}
}
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.synchronizationbadpractices;
public class SynchronizationSolutionExample {
private final String stringLock = new String("LOCK_STRING");
public void stringSolution() {
synchronized (stringLock) {
// ...
}
}
private int count = 0;
private final Integer intLock = new Integer(count);
public void boxedPrimitiveSolution() {
synchronized(intLock) {
count++;
// ...
}
}
private static int staticCount = 0;
private static final Object staticObjLock = new Object();
public void staticVariableSolution() {
synchronized(staticObjLock) {
staticCount++;
// ...
}
}
}

View File

@ -0,0 +1,58 @@
package com.baeldung.binarysemaphorereentrantlock;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;
import org.junit.Test;
public class BinarySemaphoreVsReentrantLockUnitTest {
@Test
public void givenBinarySemaphore_whenAcquireAndRelease_thenCheckAvailablePermits() throws InterruptedException {
Semaphore binarySemaphore = new Semaphore(1);
try {
binarySemaphore.acquire();
assertEquals(0, binarySemaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
binarySemaphore.release();
assertEquals(1, binarySemaphore.availablePermits());
}
}
@Test
public void givenReentrantLock_whenLockAndUnlock_thenCheckHoldCountAndIsLocked() throws InterruptedException {
ReentrantLock reentrantLock = new ReentrantLock();
try {
reentrantLock.lock();
assertEquals(1, reentrantLock.getHoldCount());
assertEquals(true, reentrantLock.isLocked());
} finally {
reentrantLock.unlock();
assertEquals(0, reentrantLock.getHoldCount());
assertEquals(false, reentrantLock.isLocked());
}
}
@Test
public void givenReentrantLock_whenLockMultipleTimes_thenUnlockMultipleTimesToRelease() throws InterruptedException {
ReentrantLock reentrantLock = new ReentrantLock();
try {
reentrantLock.lock();
reentrantLock.lock();
assertEquals(2, reentrantLock.getHoldCount());
assertEquals(true, reentrantLock.isLocked());
} finally {
reentrantLock.unlock();
assertEquals(1, reentrantLock.getHoldCount());
assertEquals(true, reentrantLock.isLocked());
reentrantLock.unlock();
assertEquals(0, reentrantLock.getHoldCount());
assertEquals(false, reentrantLock.isLocked());
}
}
}

View File

@ -0,0 +1,2 @@
test-link*
0.*

View File

@ -0,0 +1,8 @@
## Core Java IO
This module contains articles about core Java input and output (IO)
### Relevant Articles:
- [Java File Separator vs File Path Separator](https://www.baeldung.com/java-file-vs-file-path-separator)
- [[<-- Prev]](/core-java-modules/core-java-io-3)

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
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">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-io-4</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>core-java-io-4</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<!-- utils -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!-- logging -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
</build>
<properties>
<assertj.version>3.6.1</assertj.version>
</properties>
</project>

View File

@ -0,0 +1,63 @@
package com.baeldung.fileseparator;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.io.IOException;
import java.util.StringJoiner;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
public class FilePathSeparatorUnitTest {
@Test
@EnabledOnOs(OS.WINDOWS)
public void whenCheckPathSeparator_thenResultIsAsExpectedOnWindows() throws IOException {
assertEquals(";", File.pathSeparator);
assertEquals(';', File.pathSeparatorChar);
}
@Test
@EnabledOnOs({ OS.LINUX, OS.MAC })
public void whenCheckPathSeparator_thenResultIsAsExpected() throws IOException {
assertEquals(":", File.pathSeparator);
assertEquals(':', File.pathSeparatorChar);
}
@Test
@EnabledOnOs(OS.WINDOWS)
public void whenBuildPathUsingString_thenResultIsAsExpectedOnWindows() throws IOException {
String[] pathNames = { "path1", "path2", "path3" };
String path = String.join(File.pathSeparator, pathNames);
assertEquals("path1;path2;path3",path);
}
@Test
@EnabledOnOs({ OS.LINUX, OS.MAC })
public void whenBuildPathUsingString_thenResultIsAsExpected() throws IOException {
String[] pathNames = { "path1", "path2", "path3" };
String path = String.join(File.pathSeparator, pathNames);
assertEquals("path1:path2:path3", path);
}
@Test
@EnabledOnOs(OS.WINDOWS)
public void whenbuildPathUsingStringJoiner_thenResultIsAsExpectedOnWindows() throws IOException {
assertEquals("path1;path2", buildPathUsingStringJoiner("path1", "path2"));
}
@Test
@EnabledOnOs({ OS.LINUX, OS.MAC })
public void whenbuildPathUsingStringJoiner_thenResultIsAsExpected() throws IOException {
assertEquals("path1:path2", buildPathUsingStringJoiner("path1", "path2"));
}
private String buildPathUsingStringJoiner(String path1, String path2) {
StringJoiner joiner = new StringJoiner(File.pathSeparator);
joiner.add(path1);
joiner.add(path2);
return joiner.toString();
}
}

View File

@ -0,0 +1,63 @@
package com.baeldung.fileseparator;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
public class FileSeparatorUnitTest {
@Test
@EnabledOnOs(OS.WINDOWS)
public void whenCheckFileSeparator_thenCorrectOnWindows() {
assertEquals("\\", File.separator);
assertEquals('\\', File.separatorChar);
String fileSeparator = FileSystems.getDefault().getSeparator();
assertEquals("\\",fileSeparator);
}
@Test
@EnabledOnOs({ OS.LINUX, OS.MAC })
public void whenCheckFileSeparator_thenCorrect() {
assertEquals("/", File.separator);
assertEquals('/', File.separatorChar);
String fileSeparator = FileSystems.getDefault().getSeparator();
assertEquals("/",fileSeparator);
}
@Test
@EnabledOnOs(OS.WINDOWS)
public void whenBuildFilePathUsingPathsClass_thenCorrectOnWindows() {
Path path = Paths.get("dir1", "dir2");
assertEquals("dir1\\dir2", path.toString());
}
@Test
@EnabledOnOs({ OS.LINUX, OS.MAC })
public void whenBuildFilePathUsingPathsClass_thenCorrect() {
Path path = Paths.get("dir1", "dir2");
assertEquals("dir1/dir2", path.toString());
}
@Test
@EnabledOnOs(OS.WINDOWS)
public void whenBuildFilePathUsingFileClass_thenOutputIsAsExpectedOnWindows() {
File file = new File("file1", "file2");
assertEquals("file1\\file2", file.toString());
}
@Test
@EnabledOnOs({ OS.LINUX, OS.MAC })
public void whenBuildFilePathUsingFileClass_thenOutputIsAsExpected() {
File file = new File("file1", "file2");
assertEquals("file1/file2", file.toString());
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.constantpool;
public class ConstantPool {
public void sayHello() {
System.out.println("Hello World");
}
}

View File

@ -69,7 +69,6 @@
<jmh-generator.version>1.19</jmh-generator.version>
<assertj.version>3.12.2</assertj.version>
<commons.beanutils.version>1.9.4</commons.beanutils.version>
<commons-lang3.version>3.10</commons-lang3.version>
<guava.version>29.0-jre</guava.version>
</properties>

View File

@ -14,4 +14,4 @@
- [Debugging with Eclipse](https://www.baeldung.com/eclipse-debugging)
- [Matrix Multiplication in Java](https://www.baeldung.com/java-matrix-multiplication)
- [Largest Power of 2 That Is Less Than the Given Number with Java](https://www.baeldung.com/java-largest-power-of-2-less-than-number)
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math)
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math)[[Next -->]](/core-java-modules/core-java-lang-math-3)

View File

@ -0,0 +1,9 @@
=========
## Core Java 8 Cookbooks and Examples - Part 3
### Relevant articles:
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
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">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-lang-math-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>core-java-lang-math-3</name>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>net.objecthunter</groupId>
<artifactId>exp4j</artifactId>
<version>0.4.8</version>
</dependency>
<dependency>
<groupId>com.fathzer</groupId>
<artifactId>javaluator</artifactId>
<version>3.0.3</version>
</dependency>
</dependencies>
<properties>
</properties>
</project>

View File

@ -0,0 +1,91 @@
package com.baeldung.math.evaluate;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.fathzer.soft.javaluator.DoubleEvaluator;
import com.fathzer.soft.javaluator.StaticVariableSet;
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
public class EvalauteMathExpressionsUnitTest {
@Test
public void givenSimpleExpression_whenCallEvaluateMethod_thenSuccess() {
Expression expression = new ExpressionBuilder("3+2").build();
double result = expression.evaluate();
Assertions.assertEquals(5, result);
}
@Test
public void givenTwoVariables_whenCallEvaluateMethod_thenSuccess() {
Expression expression = new ExpressionBuilder("3x+2y").variables("x", "y")
.build()
.setVariable("x", 2)
.setVariable("y", 3);
double result = expression.evaluate();
Assertions.assertEquals(12, result);
}
@Test
public void givenMathFunctions_whenCallEvaluateMethod_thenSuccess() {
Expression expression = new ExpressionBuilder("sin(x)*sin(x)+cos(x)*cos(x)").variables("x")
.build()
.setVariable("x", 0.5);
double result = expression.evaluate();
Assertions.assertEquals(1, result);
}
@Test
public void givenExpression_whenCallEvaluateMethod_thenSuccess() {
String expression = "3+2";
DoubleEvaluator eval = new DoubleEvaluator();
Double result = eval.evaluate(expression);
Assertions.assertEquals(5, result);
}
@Test
public void givenVariables_whenCallEvaluateMethod_thenSuccess() {
String expression = "3*x+2*y";
DoubleEvaluator eval = new DoubleEvaluator();
StaticVariableSet<Double> variables = new StaticVariableSet<Double>();
variables.set("x", 2.0);
variables.set("y", 3.0);
Double result = eval.evaluate(expression, variables);
Assertions.assertEquals(12, result);
}
@Test
public void givenMathFunction_whenCallEvaluateMethod_thenSuccess() {
String expression = "sin(x)*sin(x)+cos(x)*cos(x)";
DoubleEvaluator eval = new DoubleEvaluator();
StaticVariableSet<Double> variables = new StaticVariableSet<Double>();
variables.set("x", 0.5);
Double result = eval.evaluate(expression, variables);
Assertions.assertEquals(1, result);
}
@Test
public void givenJavaScriptingApiAndSimpleExpression_whenCallEvalMethod_thenSuccess() throws ScriptException {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
String expression = "3+2";
Integer result = (Integer) scriptEngine.eval(expression);
Assertions.assertEquals(5, result);
}
@Test
public void givenJavaScriptingApi_whenCallEvalMethod_thenSuccess() throws ScriptException {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
String expression = "x=2; y=3; 3*x+2*y;";
Double result = (Double) scriptEngine.eval(expression);
Assertions.assertEquals(12, result);
}
}

View File

@ -13,4 +13,32 @@
<name>core-java-lang-oop-generics</name>
<packaging>jar</packaging>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<compilerArguments>
<Xlint:unchecked/>
</compilerArguments>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>

View File

@ -0,0 +1,45 @@
package com.baeldung.uncheckedconversion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
public class UncheckedConversion {
public static List getRawList() {
List result = new ArrayList();
result.add("I am the 1st String.");
result.add("I am the 2nd String.");
result.add("I am the 3rd String.");
return result;
}
public static List getRawListWithMixedTypes() {
List result = new ArrayList();
result.add("I am the 1st String.");
result.add("I am the 2nd String.");
result.add("I am the 3rd String.");
result.add(new Date());
return result;
}
public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> rawCollection) {
List<T> result = new ArrayList<>(rawCollection.size());
for (Object o : rawCollection) {
try {
result.add(clazz.cast(o));
} catch (ClassCastException e) {
// log the exception or other error handling
}
}
return result;
}
public static <T> List<T> castList2(Class<? extends T> clazz, Collection<?> rawCollection) throws ClassCastException {
List<T> result = new ArrayList<>(rawCollection.size());
for (Object o : rawCollection) {
result.add(clazz.cast(o));
}
return result;
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.uncheckedconversion;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
public class UncheckedConversionUnitTest {
@Test
public void givenRawList_whenAssignToTypedList_shouldHaveCompilerWarning() {
List<String> fromRawList = UncheckedConversion.getRawList();
Assert.assertEquals(3, fromRawList.size());
Assert.assertEquals("I am the 1st String.", fromRawList.get(0));
}
@Test(expected = ClassCastException.class)
public void givenRawList_whenListHasMixedType_shouldThrowClassCastException() {
List<String> fromRawList = UncheckedConversion.getRawListWithMixedTypes();
Assert.assertEquals(4, fromRawList.size());
Assert.assertFalse(fromRawList.get(3).endsWith("String."));
}
@Test
public void givenRawList_whenAssignToTypedListAfterCallingCastList_shouldOnlyHaveElementsWithExpectedType() {
List rawList = UncheckedConversion.getRawListWithMixedTypes();
List<String> strList = UncheckedConversion.castList(String.class, rawList);
Assert.assertEquals(4, rawList.size());
Assert.assertEquals("One element with the wrong type has been filtered out.", 3, strList.size());
Assert.assertTrue(strList.stream().allMatch(el -> el.endsWith("String.")));
}
@Test(expected = ClassCastException.class)
public void givenRawListWithWrongType_whenAssignToTypedListAfterCallingCastList2_shouldThrowException() {
List rawList = UncheckedConversion.getRawListWithMixedTypes();
UncheckedConversion.castList2(String.class, rawList);
}
}

View File

@ -6,8 +6,7 @@ import java.util.logging.Logger;
public class OutputStreamExample {
public static void main(String[] args) {
Logger log = Logger.getLogger(OutputStreamExample.class.getName());
log.log(Level.INFO, Integer.toString(sum(1,2)));
System.out.println(sum(1,2));
}
public static int sum(int a, int b) {

View File

@ -5,10 +5,10 @@ import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.String;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.lang.Integer;
@ -88,4 +88,21 @@ class ProcessUnderstandingUnitTest {
.filter(ph -> (ph.pid() > 10000 && ph.pid() < 50000))
.count()) > 0);
}
@Test
public void givenSourceProgram_whenReadingInputStream_thenFirstLineEquals3() throws IOException {
Runtime.getRuntime()
.exec("javac -cp src src/main/java/com/baeldung/java9/process/OutputStreamExample.java"
.replace("/", File.separator));
Process process = Runtime.getRuntime()
.exec("java -cp src/main/java com.baeldung.java9.process.OutputStreamExample"
.replace("/", File.separator));
BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
int value = Integer.parseInt(output.readLine());
assertEquals(3, value);
}
}

View File

@ -9,11 +9,13 @@ import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.jupiter.api.Disabled;
import static org.junit.Assert.assertTrue;
@Ignore
public class ScreenshotUnitTest {
@Test
@ -43,7 +45,6 @@ public class ScreenshotUnitTest {
// This methods needs a component as a parameter and can only be run from an application with a GUI
@Test
@Disabled
public void givenComponent_whenTakeScreenshot_thenSaveToFile(Component component) throws Exception {
Rectangle componentRect = component.getBounds();
BufferedImage bufferedImage = new BufferedImage(componentRect.width, componentRect.height, BufferedImage.TYPE_INT_ARGB);

View File

@ -61,7 +61,6 @@
</build>
<properties>
<commons-lang3.version>3.8.1</commons-lang3.version>
<assertj.version>3.6.1</assertj.version>
<diff-match-path.version>1.2</diff-match-path.version>
</properties>

View File

@ -59,7 +59,6 @@
</build>
<properties>
<commons-lang3.version>3.8.1</commons-lang3.version>
<assertj.version>3.6.1</assertj.version>
<guava.version>28.1-jre</guava.version>
</properties>

View File

@ -65,7 +65,6 @@
</build>
<properties>
<commons-lang3.version>3.8.1</commons-lang3.version>
<guava.version>27.0.1-jre</guava.version>
<ahocorasick.version>0.4.0</ahocorasick.version>
<assertj.version>3.6.1</assertj.version>

View File

@ -112,7 +112,6 @@
<properties>
<assertj.version>3.6.1</assertj.version>
<validation-api.version>2.0.0.Final</validation-api.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<guava.version>28.2-jre</guava.version>
<hibernate-validator.version>6.0.2.Final</hibernate-validator.version>
<javax.el-api.version>3.0.0</javax.el-api.version>

View File

@ -60,7 +60,6 @@
</build>
<properties>
<commons-lang3.version>3.9</commons-lang3.version>
<assertj.version>3.6.1</assertj.version>
<commons-codec.version>1.10</commons-codec.version>
</properties>

View File

@ -18,15 +18,6 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic;
@PrepareForTest({ LocalDateTime.class })
public class LocalDateTimeUnitTest {
@Test
public void givenLocalDateTimeMock_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
String dateTimeExpected = "2014-12-22T10:15:30";
LocalDateTime now = LocalDateTime.now(clock);
assertThat(now).isEqualTo(dateTimeExpected);
}
@Test
public void givenFixedClock_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));

View File

@ -47,6 +47,7 @@
<module>core-java-concurrency-advanced</module>
<module>core-java-concurrency-advanced-2</module>
<module>core-java-concurrency-advanced-3</module>
<module>core-java-concurrency-advanced-4</module>
<module>core-java-concurrency-basic</module>
<module>core-java-concurrency-basic-2</module>
<module>core-java-concurrency-collections</module>
@ -67,6 +68,7 @@
<module>core-java-io</module>
<module>core-java-io-2</module>
<module>core-java-io-3</module>
<module>core-java-io-4</module>
<module>core-java-io-apis</module>
<module>core-java-io-conversions</module>
<module>core-java-io-conversions-2</module>
@ -82,6 +84,7 @@
<module>core-java-lang-3</module>
<module>core-java-lang-math</module>
<module>core-java-lang-math-2</module>
<module>core-java-lang-math-3</module>
<module>core-java-lang-oop-constructors</module>
<module>core-java-lang-oop-patterns</module>
<module>core-java-lang-oop-generics</module>

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [Kotlin vs Java](https://www.baeldung.com/kotlin/kotlin-vs-java)

View File

@ -9,4 +9,5 @@ This module contains articles about Jackson conversions.
- [Converting JSON to CSV in Java](https://www.baeldung.com/java-converting-json-to-csv)
- [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
- [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api)
- [Jackson: java.util.LinkedHashMap cannot be cast to X](https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast)
- More articles: [[<-- prev]](../jackson-conversions)

View File

@ -0,0 +1,70 @@
package com.baeldung.jackson.tocollection;
import java.util.Objects;
public class Book {
private Integer bookId;
private String title;
private String author;
public Book() {}
public Book(Integer bookId, String title, String author) {
this.bookId = bookId;
this.title = title;
this.author = author;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Book)) {
return false;
}
Book book = (Book) o;
if (!Objects.equals(bookId, book.bookId)) {
return false;
}
if (!Objects.equals(title, book.title)) {
return false;
}
return Objects.equals(author, book.author);
}
@Override
public int hashCode() {
int result = bookId != null ? bookId.hashCode() : 0;
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + (author != null ? author.hashCode() : 0);
return result;
}
public Integer getBookId() {
return bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.jackson.tocollection;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class JsonToCollectionUtil {
private JsonToCollectionUtil(){}
public static <T> List<T> jsonArrayToList(String json, Class<T> elementClass) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, elementClass);
return objectMapper.readValue(json, listType);
}
public static <T> List<T> jsonArrayToList2(String json, Class<T> elementClass) throws IOException {
return new ObjectMapper().readValue(json, new TypeReference<List<T>>() {});
}
}

View File

@ -0,0 +1,13 @@
[ {
"bookId" : 1,
"title" : "A Song of Ice and Fire",
"author" : "George R. R. Martin"
}, {
"bookId" : 2,
"title" : "The Hitchhiker's Guide to the Galaxy",
"author" : "Douglas Adams"
}, {
"bookId" : 3,
"title" : "Hackers And Painters",
"author" : "Paul Graham"
} ]

View File

@ -0,0 +1,17 @@
<ArrayList>
<item>
<bookId>1</bookId>
<title>A Song of Ice and Fire</title>
<author>George R. R. Martin</author>
</item>
<item>
<bookId>2</bookId>
<title>The Hitchhiker's Guide to the Galaxy</title>
<author>Douglas Adams</author>
</item>
<item>
<bookId>3</bookId>
<title>Hackers And Painters</title>
<author>Paul Graham</author>
</item>
</ArrayList>

View File

@ -0,0 +1,130 @@
package com.baeldung.jackson.tocollection;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
public class DeserializeToJavaCollectionUnitTest {
private ObjectMapper objectMapper;
private XmlMapper xmlMapper;
private List<Book> expectedBookList;
@BeforeEach
void setup() {
objectMapper = new ObjectMapper();
xmlMapper = new XmlMapper();
expectedBookList = Lists.newArrayList(
new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
new Book(3, "Hackers And Painters", "Paul Graham"));
}
private String readFile(String path) {
try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
return scanner.useDelimiter("\\A").next();
}
}
/*====================
* JSON tests
*====================
*/
@Test
void givenJsonString_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
String jsonString = readFile("/to-java-collection/books.json");
List<Book> bookList = objectMapper.readValue(jsonString, ArrayList.class);
assertThat(bookList).size().isEqualTo(3);
assertThatExceptionOfType(ClassCastException.class)
.isThrownBy(() -> bookList.get(0).getBookId())
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
}
@Test
void givenJsonString_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
String jsonString = readFile("/to-java-collection/books.json");
List<Book> bookList = objectMapper.readValue(jsonString, new TypeReference<List<Book>>() {});
assertThat(bookList.get(0)).isInstanceOf(Book.class);
assertThat(bookList).isEqualTo(expectedBookList);
}
@Test
void givenJsonString_whenDeserializingWithJavaType_thenGetExpectedList() throws JsonProcessingException {
String jsonString = readFile("/to-java-collection/books.json");
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class);
List<Book> bookList = objectMapper.readValue(jsonString, listType);
assertThat(bookList.get(0)).isInstanceOf(Book.class);
assertThat(bookList).isEqualTo(expectedBookList);
}
@Test
void givenJsonString_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
String jsonString = readFile("/to-java-collection/books.json");
JsonNode jsonNode = objectMapper.readTree(jsonString);
List<Book> bookList = objectMapper.convertValue(jsonNode, new TypeReference<List<Book>>() {});
assertThat(bookList.get(0)).isInstanceOf(Book.class);
assertThat(bookList).isEqualTo(expectedBookList);
}
@Test
void givenJsonString_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
String jsonString = readFile("/to-java-collection/books.json");
JsonNode jsonNode = objectMapper.readTree(jsonString);
List<Book> bookList = objectMapper.convertValue(jsonNode, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
assertThat(bookList.get(0)).isInstanceOf(Book.class);
assertThat(bookList).isEqualTo(expectedBookList);
}
/*====================
* XML tests
*====================
*/
@Test
void givenXml_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
String xml = readFile("/to-java-collection/books.xml");
List<Book> bookList = xmlMapper.readValue(xml, ArrayList.class);
assertThat(bookList).size().isEqualTo(3);
assertThatExceptionOfType(ClassCastException.class)
.isThrownBy(() -> bookList.get(0).getBookId())
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
}
@Test
void givenXml_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
String xml = readFile("/to-java-collection/books.xml");
List<Book> bookList = xmlMapper.readValue(xml, new TypeReference<List<Book>>() {});
assertThat(bookList.get(0)).isInstanceOf(Book.class);
assertThat(bookList).isEqualTo(expectedBookList);
}
@Test
void givenXml_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
String xml = readFile("/to-java-collection/books.xml");
List node = xmlMapper.readValue(xml, List.class);
List<Book> bookList = xmlMapper.convertValue(node, new TypeReference<List<Book>>() {});
assertThat(bookList.get(0)).isInstanceOf(Book.class);
assertThat(bookList).isEqualTo(expectedBookList);
}
@Test
void givenXml_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
String xml = readFile("/to-java-collection/books.xml");
List node = xmlMapper.readValue(xml, List.class);
List<Book> bookList = xmlMapper.convertValue(node, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
assertThat(bookList.get(0)).isInstanceOf(Book.class);
assertThat(bookList).isEqualTo(expectedBookList);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.jackson.tocollection;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
class JsonToCollectionUtilUnitTest {
private List<Book> expectedBookList;
@BeforeEach
void setup() {
expectedBookList = Lists.newArrayList(
new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
new Book(3, "Hackers And Painters", "Paul Graham"));
}
private String readFile(String path) {
try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
return scanner.useDelimiter("\\A").next();
}
}
@Test
void givenJsonString_whenCalljsonArrayToList_thenGetExpectedList() throws IOException {
String jsonString = readFile("/to-java-collection/books.json");
List<Book> bookList = JsonToCollectionUtil.jsonArrayToList(jsonString, Book.class);
assertThat(bookList.get(0)).isInstanceOf(Book.class);
assertThat(bookList).isEqualTo(expectedBookList);
}
@Test
void givenJsonString_whenCalljsonArrayToList2_thenGetException() throws IOException {
String jsonString = readFile("/to-java-collection/books.json");
List<Book> bookList = JsonToCollectionUtil.jsonArrayToList2(jsonString, Book.class);
assertThat(bookList).size().isEqualTo(3);
assertThatExceptionOfType(ClassCastException.class)
.isThrownBy(() -> bookList.get(0).getBookId())
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
}
}

View File

@ -1,3 +1,4 @@
### Relevant Articles:
- [Java Map With Case-Insensitive Keys](https://www.baeldung.com/java-map-with-case-insensitive-keys)
- [Using a Byte Array as Map Key in Java](https://www.baeldung.com/java-map-key-byte-array)

View File

@ -0,0 +1,35 @@
package com.baeldung.map.entry;
public class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", author='" + author + '\'' +
'}';
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.map.entry;
import java.util.HashMap;
import java.util.Map;
public class MapEntryEfficiencyExample {
public static void main(String[] args) {
MapEntryEfficiencyExample mapEntryEfficiencyExample = new MapEntryEfficiencyExample();
Map<String, String> map = new HashMap<>();
map.put("Robert C. Martin", "Clean Code");
map.put("Joshua Bloch", "Effective Java");
System.out.println("Iterating Using Map.KeySet - 2 operations");
mapEntryEfficiencyExample.usingKeySet(map);
System.out.println("Iterating Using Map.Entry - 1 operation");
mapEntryEfficiencyExample.usingEntrySet(map);
}
public void usingKeySet(Map<String, String> bookMap) {
for (String key : bookMap.keySet()) {
System.out.println("key: " + key + " value: " + bookMap.get(key));
}
}
public void usingEntrySet(Map<String, String> bookMap) {
for (Map.Entry<String, String> book: bookMap.entrySet()) {
System.out.println("key: " + book.getKey() + " value: " + book.getValue());
}
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.map.entry;
import java.util.*;
public class MapEntryTupleExample {
public static void main(String[] args) {
Map.Entry<String, Book> tuple1;
Map.Entry<String, Book> tuple2;
Map.Entry<String, Book> tuple3;
tuple1 = new AbstractMap.SimpleEntry<>("9780134685991", new Book("Effective Java 3d Edition", "Joshua Bloch"));
tuple2 = new AbstractMap.SimpleEntry<>("9780132350884", new Book("Clean Code", "Robert C Martin"));
tuple3 = new AbstractMap.SimpleEntry<>("9780132350884", new Book("Clean Code", "Robert C Martin"));
List<Map.Entry<String, Book>> orderedTuples = new ArrayList<>();
orderedTuples.add(tuple1);
orderedTuples.add(tuple2);
orderedTuples.add(tuple3);
for (Map.Entry<String, Book> tuple : orderedTuples) {
System.out.println("key: " + tuple.getKey() + " value: " + tuple.getValue());
}
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.map.entry;
import org.junit.Test;
import java.util.*;
import static org.junit.Assert.assertEquals;
public class MapEntryUnitTest {
@Test
public void givenSimpleEntryList_whenAddDuplicateKey_thenDoesNotOverwriteExistingKey() {
List<Map.Entry<String, Book>> orderedTuples = new ArrayList<>();
orderedTuples.add(new AbstractMap.SimpleEntry<>("9780134685991", new Book("Effective Java 3d Edition", "Joshua Bloch")));
orderedTuples.add(new AbstractMap.SimpleEntry<>("9780132350884", new Book("Clean Code", "Robert C Martin")));
orderedTuples.add(new AbstractMap.SimpleEntry<>("9780132350884", new Book("Clean Code", "Robert C Martin")));
assertEquals(3, orderedTuples.size());
assertEquals("9780134685991", orderedTuples.get(0).getKey());
assertEquals("9780132350884", orderedTuples.get(1).getKey());
assertEquals("9780132350884", orderedTuples.get(2).getKey());
}
@Test
public void givenRegularMap_whenAddDuplicateKey_thenOverwritesExistingKey() {
Map<String, Book> entries = new HashMap<>();
entries.put("9780134685991", new Book("Effective Java 3d Edition", "Joshua Bloch"));
entries.put("9780132350884", new Book("Clean Code", "Robert C Martin"));
entries.put("9780132350884", new Book("Clean Code", "Robert C Martin"));
assertEquals(2, entries.size());
}
}

View File

@ -27,7 +27,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons.version}</version>
<version>${commons-lang3.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@ -51,7 +51,6 @@
<properties>
<dsiutils.version>2.6.0</dsiutils.version>
<vavr.version>0.10.2</vavr.version>
<commons.version>3.9</commons.version>
<assertj.version>3.6.1</assertj.version>
</properties>

View File

@ -2,3 +2,4 @@
- [Probability in Java](https://www.baeldung.com/java-probability)
- [Understanding the & 0xff Value in Java](https://www.baeldung.com/java-and-0xff)
- [Determine if an Integers Square Root Is an Integer in Java](https://www.baeldung.com/java-find-if-square-root-is-integer)

View File

@ -22,7 +22,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons.version}</version>
<version>${commons-lang3.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@ -45,7 +45,6 @@
<properties>
<vavr.version>0.10.2</vavr.version>
<commons.version>3.9</commons.version>
<assertj.version>3.6.1</assertj.version>
</properties>

View File

@ -59,7 +59,6 @@
<org.apache.httpcomponents.version>4.5.3</org.apache.httpcomponents.version>
<gson.version>2.8.2</gson.version>
<assertj.version>3.9.1</assertj.version>
<commons-fileupload.version>1.3.3</commons-fileupload.version>
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
</properties>

View File

@ -21,8 +21,6 @@
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
<assertj.version>3.6.2</assertj.version>
<awaitility.version>2.0.0</awaitility.version>
<commons-io.version>2.5</commons-io.version>
<commons-lang.version>3.5</commons-lang.version>
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
<hibernate.version>5.2.8.Final</hibernate.version>
@ -267,7 +265,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>

View File

@ -20,8 +20,6 @@
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
<assertj.version>3.6.2</assertj.version>
<awaitility.version>2.0.0</awaitility.version>
<commons-io.version>2.5</commons-io.version>
<commons-lang.version>3.5</commons-lang.version>
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
<hibernate.version>5.2.8.Final</hibernate.version>
@ -266,7 +264,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>

View File

@ -22,8 +22,6 @@
<awaitility.version>2.0.0</awaitility.version>
<cassandra-driver.version>3.6.0</cassandra-driver.version>
<commons-codec.version>1.10</commons-codec.version>
<commons-io.version>2.5</commons-io.version>
<commons-lang.version>3.5</commons-lang.version>
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
@ -299,7 +297,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>

View File

@ -171,7 +171,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
@ -887,8 +887,6 @@
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
<assertj.version>3.6.2</assertj.version>
<awaitility.version>2.0.0</awaitility.version>
<commons-io.version>2.5</commons-io.version>
<commons-lang.version>3.5</commons-lang.version>
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
<gatling-maven-plugin.version>2.2.1</gatling-maven-plugin.version>

View File

@ -114,7 +114,6 @@
<jsoniter.version>0.9.23</jsoniter.version>
<assertj-core.version>3.11.1</assertj-core.version>
<moshi.version>1.9.2</moshi.version>
<commons-lang3.version>3.9</commons-lang3.version>
</properties>
<build>
<pluginManagement>

View File

@ -94,7 +94,7 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commonsio.version}</version>
<version>${commons-io.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@ -157,7 +157,6 @@
<protonpack.version>1.15</protonpack.version>
<commons-net.version>3.6</commons-net.version>
<assertj.version>3.6.2</assertj.version>
<commonsio.version>2.6</commonsio.version>
<renjin.version>RELEASE</renjin.version>
<rcaller.version>3.0</rcaller.version>
<rserve.version>1.8.1</rserve.version>

View File

@ -65,7 +65,6 @@
</dependencies>
<properties>
<commons-lang3.version>3.6</commons-lang3.version>
<commons-text.version>1.1</commons-text.version>
<commons-beanutils.version>1.9.3</commons-beanutils.version>
<commons-chain.version>1.2</commons-chain.version>

View File

@ -80,7 +80,7 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
<version>${commons-io.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -165,7 +165,6 @@
<properties>
<assembly.plugin.version>2.3</assembly.plugin.version>
<commons.cli.version>1.2</commons.cli.version>
<commons.io.version>2.1</commons.io.version>
<httpclient.version>3.0.1</httpclient.version>
<storm.version>1.2.2</storm.version>
<kafka.version>1.0.0</kafka.version>

View File

@ -74,7 +74,6 @@
<commons-compress-version>1.15</commons-compress-version>
<commons-io.version>2.3</commons-io.version>
<commons-collections4.version>4.0</commons-collections4.version>
<commons-lang3.version>3.0</commons-lang3.version>
<commons-beanutils.version>1.9.1</commons-beanutils.version>
<versions.plugin.version>2.7</versions.plugin.version>
</properties>

View File

@ -74,8 +74,8 @@
<commons.io.version>2.3</commons.io.version>
<versions.plugin.version>2.7</versions.plugin.version>
<commons.beanutils.version>1.9.1</commons.beanutils.version>
<commons.lang3.version>3.0</commons.lang3.version>
<commons.collections4.version>4.0</commons.collections4.version>
<commons.lang3.version>3.11</commons.lang3.version>
</properties>
</project>

View File

@ -27,7 +27,7 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
@ -43,7 +43,6 @@
<properties>
<guava.version>29.0-jre</guava.version>
<commons.io.version>2.6</commons.io.version>
<jmh.version>1.19</jmh.version>
<modelmapper.version>2.3.7</modelmapper.version>
<hamcrest.version>2.2</hamcrest.version>

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [Clean Architecture with Spring Boot](https://www.baeldung.com/spring-boot-clean-architecture)

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>clean-architecture</artifactId>
<version>1.0</version>
<name>clean-architecture</name>
<description>Project for clean architecture in java</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,40 @@
package com.baeldung.pattern.cleanarchitecture;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
@SpringBootApplication
public class CleanArchitectureApplication {
public static void main(String[] args) {
SpringApplication.run(CleanArchitectureApplication.class);
}
@Bean
BeanFactoryPostProcessor beanFactoryPostProcessor(ApplicationContext beanRegistry) {
return beanFactory -> {
genericApplicationContext((BeanDefinitionRegistry) ((AnnotationConfigServletWebServerApplicationContext) beanRegistry).getBeanFactory());
};
}
void genericApplicationContext(BeanDefinitionRegistry beanRegistry) {
ClassPathBeanDefinitionScanner beanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanRegistry);
beanDefinitionScanner.addIncludeFilter(removeModelAndEntitiesFilter());
beanDefinitionScanner.scan("com.baeldung.pattern.cleanarchitecture");
}
static TypeFilter removeModelAndEntitiesFilter() {
return (MetadataReader mr, MetadataReaderFactory mrf) -> !mr.getClassMetadata()
.getClassName()
.endsWith("Model");
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
class CommonUser implements User {
String name;
String password;
CommonUser(String name, String password) {
this.name = name;
this.password = password;
}
CommonUser() {
}
@Override
public boolean passwordIsValid() {
return password != null && password.length() > 5;
}
@Override
public String getName() {
return name;
}
@Override
public String getPassword() {
return password;
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
class CommonUserFactory implements UserFactory {
@Override
public User create(String name, String password) {
return new CommonUser(name, password);
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
class JpaUser implements UserRegisterDsGateway {
final JpaUserRepository repository;
JpaUser(JpaUserRepository repository) {
this.repository = repository;
}
@Override
public boolean existsByName(String name) {
return repository.existsById(name);
}
@Override
public void save(UserDsRequestModel requestModel) {
UserDataMapper accountDataMapper = new UserDataMapper(requestModel.getName(), requestModel.getPassword(), requestModel.getCreationTime());
repository.save(accountDataMapper);
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
interface JpaUserRepository extends JpaRepository<UserDataMapper, String> {
}

View File

@ -0,0 +1,9 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
interface User {
boolean passwordIsValid();
String getName();
String getPassword();
}

View File

@ -0,0 +1,53 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
import java.time.LocalDateTime;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "user")
class UserDataMapper {
@Id
String name;
String password;
LocalDateTime creationTime;
public UserDataMapper() {
}
public UserDataMapper(String name, String password, LocalDateTime creationTime) {
super();
this.name = name;
this.password = password;
this.creationTime = creationTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public LocalDateTime getCreationTime() {
return creationTime;
}
public void setCreationTime(LocalDateTime creationTime) {
this.creationTime = creationTime;
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
import java.time.LocalDateTime;
class UserDsRequestModel {
String name;
String password;
LocalDateTime creationTime;
public UserDsRequestModel(String name, String password, LocalDateTime creationTime) {
this.name = name;
this.password = password;
this.creationTime = creationTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public LocalDateTime getCreationTime() {
return creationTime;
}
public void setCreationTime(LocalDateTime creationTime) {
this.creationTime = creationTime;
}
}

View File

@ -0,0 +1,5 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
interface UserFactory {
User create(String name, String password);
}

View File

@ -0,0 +1,5 @@
package com.baeldung.pattern.cleanarchitecture.usercreation;
public interface UserInputBoundary {
UserResponseModel create(UserRequestModel requestModel);
}

Some files were not shown because too many files have changed in this diff Show More