commit
39c0b3811a
|
@ -89,7 +89,6 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<json-simple.version>1.1.1</json-simple.version>
|
<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-events.version>1.3.0</aws-lambda-java-events.version>
|
||||||
<aws-lambda-java-core.version>1.2.0</aws-lambda-java-core.version>
|
<aws-lambda-java-core.version>1.2.0</aws-lambda-java-core.version>
|
||||||
<gson.version>2.8.2</gson.version>
|
<gson.version>2.8.2</gson.version>
|
||||||
|
|
|
@ -154,7 +154,6 @@
|
||||||
<properties>
|
<properties>
|
||||||
<blade-mvc.version>2.0.14.RELEASE</blade-mvc.version>
|
<blade-mvc.version>2.0.14.RELEASE</blade-mvc.version>
|
||||||
<bootstrap.version>4.2.1</bootstrap.version>
|
<bootstrap.version>4.2.1</bootstrap.version>
|
||||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
|
||||||
<lombok.version>1.18.4</lombok.version>
|
<lombok.version>1.18.4</lombok.version>
|
||||||
<httpclient.version>4.5.6</httpclient.version>
|
<httpclient.version>4.5.6</httpclient.version>
|
||||||
<httpmime.version>4.5.6</httpmime.version>
|
<httpmime.version>4.5.6</httpmime.version>
|
||||||
|
|
|
@ -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 8 Optional](https://www.baeldung.com/java-optional)
|
||||||
- [Guide to Java Reflection](http://www.baeldung.com/java-reflection)
|
- [Guide to Java Reflection](http://www.baeldung.com/java-reflection)
|
||||||
- [Guide to Java 8’s Collectors](https://www.baeldung.com/java-8-collectors)
|
- [Guide to Java 8’s Collectors](https://www.baeldung.com/java-8-collectors)
|
||||||
|
- [New Features in Java 11](https://www.baeldung.com/java-11-new-features)
|
||||||
|
|
|
@ -28,6 +28,29 @@
|
||||||
<version>${assertj.version}</version>
|
<version>${assertj.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -48,7 +71,9 @@
|
||||||
<maven.compiler.source.version>11</maven.compiler.source.version>
|
<maven.compiler.source.version>11</maven.compiler.source.version>
|
||||||
<maven.compiler.target.version>11</maven.compiler.target.version>
|
<maven.compiler.target.version>11</maven.compiler.target.version>
|
||||||
<guava.version>29.0-jre</guava.version>
|
<guava.version>29.0-jre</guava.version>
|
||||||
|
<junit.jupiter.version>5.7.0</junit.jupiter.version>
|
||||||
<assertj.version>3.17.2</assertj.version>
|
<assertj.version>3.17.2</assertj.version>
|
||||||
|
<mockserver.version>5.11.1</mockserver.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
|
|
||||||
- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)
|
- [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)
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${apache-commons-lang3.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
|
@ -68,7 +68,6 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.release>15</maven.compiler.release>
|
<maven.compiler.release>15</maven.compiler.release>
|
||||||
<apache-commons-lang3.version>3.11</apache-commons-lang3.version>
|
|
||||||
<assertj.version>3.17.2</assertj.version>
|
<assertj.version>3.17.2</assertj.version>
|
||||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||||
<surefire.plugin.version>3.0.0-M3</surefire.plugin.version>
|
<surefire.plugin.version>3.0.0-M3</surefire.plugin.version>
|
||||||
|
|
|
@ -47,12 +47,12 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.11</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.7</version>
|
<version>${commons-io.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-lang3.version>3.9</commons-lang3.version>
|
|
||||||
|
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -68,11 +68,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<shade.plugin.version>3.2.0</shade.plugin.version>
|
<shade.plugin.version>3.2.0</shade.plugin.version>
|
||||||
|
|
||||||
<commons-lang3.version>3.9</commons-lang3.version>
|
|
||||||
|
|
||||||
<jmh.version>1.19</jmh.version>
|
<jmh.version>1.19</jmh.version>
|
||||||
|
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -76,12 +76,8 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<shade.plugin.version>3.2.0</shade.plugin.version>
|
<shade.plugin.version>3.2.0</shade.plugin.version>
|
||||||
|
|
||||||
<commons-lang3.version>3.9</commons-lang3.version>
|
|
||||||
<guava.version>28.2-jre</guava.version>
|
<guava.version>28.2-jre</guava.version>
|
||||||
|
|
||||||
<jmh.version>1.19</jmh.version>
|
<jmh.version>1.19</jmh.version>
|
||||||
|
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -3,4 +3,4 @@
|
||||||
This module contains articles about Java Character Class
|
This module contains articles about Java Character Class
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- Character#isAlphabetic vs Character#isLetter
|
- [Character#isAlphabetic vs Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic)
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.10</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-collections4.version>4.1</commons-collections4.version>
|
<commons-collections4.version>4.1</commons-collections4.version>
|
||||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
|
||||||
<assertj.version>3.11.1</assertj.version>
|
<assertj.version>3.11.1</assertj.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,17 @@ import org.openjdk.jcstress.annotations.Outcome;
|
||||||
import org.openjdk.jcstress.annotations.State;
|
import org.openjdk.jcstress.annotations.State;
|
||||||
import org.openjdk.jcstress.infra.results.I_Result;
|
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
|
@JCStressTest
|
||||||
@Outcome(id = "1", expect = ACCEPTABLE_INTERESTING, desc = "One update lost.")
|
@Outcome(id = "1", expect = ACCEPTABLE_INTERESTING, desc = "One update lost.")
|
||||||
@Outcome(id = "2", expect = ACCEPTABLE, desc = "Both updates.")
|
@Outcome(id = "2", expect = ACCEPTABLE, desc = "Both updates.")
|
||||||
@State
|
@State
|
||||||
public class MyCounterJCStressUnitTest {
|
public class MyCounterJCStressManualTest {
|
||||||
|
|
||||||
private MyCounter counter;
|
private MyCounter counter;
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
package com.baeldung.concurrent;
|
package com.baeldung.concurrent;
|
||||||
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import edu.umd.cs.mtc.MultithreadedTestCase;
|
import edu.umd.cs.mtc.MultithreadedTestCase;
|
||||||
import edu.umd.cs.mtc.TestFramework;
|
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;
|
private MyCounter counter;
|
||||||
|
|
||||||
|
@ -29,9 +34,8 @@ public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
|
||||||
assertEquals(2, counter.getCount());
|
assertEquals(2, counter.getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Test
|
@Test
|
||||||
public void testCounter() throws Throwable {
|
public void testCounter() throws Throwable {
|
||||||
TestFramework.runManyTimes(new MyCounterMultithreadedTCUnitTest(), 1000);
|
TestFramework.runManyTimes(new MyCounterMultithreadedTCManualTest(), 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Binary Semaphore vs Reentrant Lock](https://www.baeldung.com/java-binary-semaphore-vs-reentrant-lock)
|
|
@ -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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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++;
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
test-link*
|
||||||
|
0.*
|
|
@ -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)
|
|
@ -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>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.constantpool;
|
||||||
|
|
||||||
|
public class ConstantPool {
|
||||||
|
|
||||||
|
public void sayHello() {
|
||||||
|
System.out.println("Hello World");
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,7 +69,6 @@
|
||||||
<jmh-generator.version>1.19</jmh-generator.version>
|
<jmh-generator.version>1.19</jmh-generator.version>
|
||||||
<assertj.version>3.12.2</assertj.version>
|
<assertj.version>3.12.2</assertj.version>
|
||||||
<commons.beanutils.version>1.9.4</commons.beanutils.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>
|
<guava.version>29.0-jre</guava.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -14,4 +14,4 @@
|
||||||
- [Debugging with Eclipse](https://www.baeldung.com/eclipse-debugging)
|
- [Debugging with Eclipse](https://www.baeldung.com/eclipse-debugging)
|
||||||
- [Matrix Multiplication in Java](https://www.baeldung.com/java-matrix-multiplication)
|
- [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)
|
- [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)
|
||||||
|
|
|
@ -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)
|
|
@ -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>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,4 +13,32 @@
|
||||||
<name>core-java-lang-oop-generics</name>
|
<name>core-java-lang-oop-generics</name>
|
||||||
<packaging>jar</packaging>
|
<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>
|
</project>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,8 +6,7 @@ import java.util.logging.Logger;
|
||||||
public class OutputStreamExample {
|
public class OutputStreamExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Logger log = Logger.getLogger(OutputStreamExample.class.getName());
|
System.out.println(sum(1,2));
|
||||||
log.log(Level.INFO, Integer.toString(sum(1,2)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int sum(int a, int b) {
|
public static int sum(int a, int b) {
|
||||||
|
|
|
@ -5,10 +5,10 @@ import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
@ -88,4 +88,21 @@ class ProcessUnderstandingUnitTest {
|
||||||
.filter(ph -> (ph.pid() > 10000 && ph.pid() < 50000))
|
.filter(ph -> (ph.pid() > 10000 && ph.pid() < 50000))
|
||||||
.count()) > 0);
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,13 @@ import java.awt.Robot;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
public class ScreenshotUnitTest {
|
public class ScreenshotUnitTest {
|
||||||
|
|
||||||
@Test
|
@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
|
// This methods needs a component as a parameter and can only be run from an application with a GUI
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
|
||||||
public void givenComponent_whenTakeScreenshot_thenSaveToFile(Component component) throws Exception {
|
public void givenComponent_whenTakeScreenshot_thenSaveToFile(Component component) throws Exception {
|
||||||
Rectangle componentRect = component.getBounds();
|
Rectangle componentRect = component.getBounds();
|
||||||
BufferedImage bufferedImage = new BufferedImage(componentRect.width, componentRect.height, BufferedImage.TYPE_INT_ARGB);
|
BufferedImage bufferedImage = new BufferedImage(componentRect.width, componentRect.height, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
<diff-match-path.version>1.2</diff-match-path.version>
|
<diff-match-path.version>1.2</diff-match-path.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
<guava.version>28.1-jre</guava.version>
|
<guava.version>28.1-jre</guava.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -65,7 +65,6 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
|
||||||
<guava.version>27.0.1-jre</guava.version>
|
<guava.version>27.0.1-jre</guava.version>
|
||||||
<ahocorasick.version>0.4.0</ahocorasick.version>
|
<ahocorasick.version>0.4.0</ahocorasick.version>
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
|
|
@ -112,7 +112,6 @@
|
||||||
<properties>
|
<properties>
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
<validation-api.version>2.0.0.Final</validation-api.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>
|
<guava.version>28.2-jre</guava.version>
|
||||||
<hibernate-validator.version>6.0.2.Final</hibernate-validator.version>
|
<hibernate-validator.version>6.0.2.Final</hibernate-validator.version>
|
||||||
<javax.el-api.version>3.0.0</javax.el-api.version>
|
<javax.el-api.version>3.0.0</javax.el-api.version>
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-lang3.version>3.9</commons-lang3.version>
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
<commons-codec.version>1.10</commons-codec.version>
|
<commons-codec.version>1.10</commons-codec.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -18,15 +18,6 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic;
|
||||||
@PrepareForTest({ LocalDateTime.class })
|
@PrepareForTest({ LocalDateTime.class })
|
||||||
public class LocalDateTimeUnitTest {
|
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
|
@Test
|
||||||
public void givenFixedClock_whenNow_thenGetFixedLocalDateTime() {
|
public void givenFixedClock_whenNow_thenGetFixedLocalDateTime() {
|
||||||
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
|
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
<module>core-java-concurrency-advanced</module>
|
<module>core-java-concurrency-advanced</module>
|
||||||
<module>core-java-concurrency-advanced-2</module>
|
<module>core-java-concurrency-advanced-2</module>
|
||||||
<module>core-java-concurrency-advanced-3</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</module>
|
||||||
<module>core-java-concurrency-basic-2</module>
|
<module>core-java-concurrency-basic-2</module>
|
||||||
<module>core-java-concurrency-collections</module>
|
<module>core-java-concurrency-collections</module>
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
<module>core-java-io</module>
|
<module>core-java-io</module>
|
||||||
<module>core-java-io-2</module>
|
<module>core-java-io-2</module>
|
||||||
<module>core-java-io-3</module>
|
<module>core-java-io-3</module>
|
||||||
|
<module>core-java-io-4</module>
|
||||||
<module>core-java-io-apis</module>
|
<module>core-java-io-apis</module>
|
||||||
<module>core-java-io-conversions</module>
|
<module>core-java-io-conversions</module>
|
||||||
<module>core-java-io-conversions-2</module>
|
<module>core-java-io-conversions-2</module>
|
||||||
|
@ -82,6 +84,7 @@
|
||||||
<module>core-java-lang-3</module>
|
<module>core-java-lang-3</module>
|
||||||
<module>core-java-lang-math</module>
|
<module>core-java-lang-math</module>
|
||||||
<module>core-java-lang-math-2</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-constructors</module>
|
||||||
<module>core-java-lang-oop-patterns</module>
|
<module>core-java-lang-oop-patterns</module>
|
||||||
<module>core-java-lang-oop-generics</module>
|
<module>core-java-lang-oop-generics</module>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Kotlin vs Java](https://www.baeldung.com/kotlin/kotlin-vs-java)
|
|
@ -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)
|
- [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)
|
- [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
|
||||||
- [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api)
|
- [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)
|
- More articles: [[<-- prev]](../jackson-conversions)
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>>() {});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
||||||
|
} ]
|
|
@ -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>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.*");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Java Map With Case-Insensitive Keys](https://www.baeldung.com/java-map-with-case-insensitive-keys)
|
- [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)
|
||||||
|
|
|
@ -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 + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -51,7 +51,6 @@
|
||||||
<properties>
|
<properties>
|
||||||
<dsiutils.version>2.6.0</dsiutils.version>
|
<dsiutils.version>2.6.0</dsiutils.version>
|
||||||
<vavr.version>0.10.2</vavr.version>
|
<vavr.version>0.10.2</vavr.version>
|
||||||
<commons.version>3.9</commons.version>
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
- [Probability in Java](https://www.baeldung.com/java-probability)
|
- [Probability in Java](https://www.baeldung.com/java-probability)
|
||||||
- [Understanding the & 0xff Value in Java](https://www.baeldung.com/java-and-0xff)
|
- [Understanding the & 0xff Value in Java](https://www.baeldung.com/java-and-0xff)
|
||||||
|
- [Determine if an Integer’s Square Root Is an Integer in Java](https://www.baeldung.com/java-find-if-square-root-is-integer)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -45,7 +45,6 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<vavr.version>0.10.2</vavr.version>
|
<vavr.version>0.10.2</vavr.version>
|
||||||
<commons.version>3.9</commons.version>
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
<org.apache.httpcomponents.version>4.5.3</org.apache.httpcomponents.version>
|
<org.apache.httpcomponents.version>4.5.3</org.apache.httpcomponents.version>
|
||||||
<gson.version>2.8.2</gson.version>
|
<gson.version>2.8.2</gson.version>
|
||||||
<assertj.version>3.9.1</assertj.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>
|
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
||||||
<assertj.version>3.6.2</assertj.version>
|
<assertj.version>3.6.2</assertj.version>
|
||||||
<awaitility.version>2.0.0</awaitility.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>
|
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
|
||||||
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
||||||
<hibernate.version>5.2.8.Final</hibernate.version>
|
<hibernate.version>5.2.8.Final</hibernate.version>
|
||||||
|
@ -267,7 +265,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
||||||
<assertj.version>3.6.2</assertj.version>
|
<assertj.version>3.6.2</assertj.version>
|
||||||
<awaitility.version>2.0.0</awaitility.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>
|
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
|
||||||
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
||||||
<hibernate.version>5.2.8.Final</hibernate.version>
|
<hibernate.version>5.2.8.Final</hibernate.version>
|
||||||
|
@ -266,7 +264,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
<awaitility.version>2.0.0</awaitility.version>
|
<awaitility.version>2.0.0</awaitility.version>
|
||||||
<cassandra-driver.version>3.6.0</cassandra-driver.version>
|
<cassandra-driver.version>3.6.0</cassandra-driver.version>
|
||||||
<commons-codec.version>1.10</commons-codec.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>
|
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
|
||||||
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
|
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
|
||||||
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
||||||
|
@ -299,7 +297,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
|
|
|
@ -171,7 +171,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
|
@ -887,8 +887,6 @@
|
||||||
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
||||||
<assertj.version>3.6.2</assertj.version>
|
<assertj.version>3.6.2</assertj.version>
|
||||||
<awaitility.version>2.0.0</awaitility.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>
|
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
|
||||||
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
|
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
|
||||||
<gatling-maven-plugin.version>2.2.1</gatling-maven-plugin.version>
|
<gatling-maven-plugin.version>2.2.1</gatling-maven-plugin.version>
|
||||||
|
|
|
@ -114,7 +114,6 @@
|
||||||
<jsoniter.version>0.9.23</jsoniter.version>
|
<jsoniter.version>0.9.23</jsoniter.version>
|
||||||
<assertj-core.version>3.11.1</assertj-core.version>
|
<assertj-core.version>3.11.1</assertj-core.version>
|
||||||
<moshi.version>1.9.2</moshi.version>
|
<moshi.version>1.9.2</moshi.version>
|
||||||
<commons-lang3.version>3.9</commons-lang3.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
<build>
|
<build>
|
||||||
<pluginManagement>
|
<pluginManagement>
|
||||||
|
|
|
@ -94,7 +94,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>${commonsio.version}</version>
|
<version>${commons-io.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -157,7 +157,6 @@
|
||||||
<protonpack.version>1.15</protonpack.version>
|
<protonpack.version>1.15</protonpack.version>
|
||||||
<commons-net.version>3.6</commons-net.version>
|
<commons-net.version>3.6</commons-net.version>
|
||||||
<assertj.version>3.6.2</assertj.version>
|
<assertj.version>3.6.2</assertj.version>
|
||||||
<commonsio.version>2.6</commonsio.version>
|
|
||||||
<renjin.version>RELEASE</renjin.version>
|
<renjin.version>RELEASE</renjin.version>
|
||||||
<rcaller.version>3.0</rcaller.version>
|
<rcaller.version>3.0</rcaller.version>
|
||||||
<rserve.version>1.8.1</rserve.version>
|
<rserve.version>1.8.1</rserve.version>
|
||||||
|
|
|
@ -65,7 +65,6 @@
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-lang3.version>3.6</commons-lang3.version>
|
|
||||||
<commons-text.version>1.1</commons-text.version>
|
<commons-text.version>1.1</commons-text.version>
|
||||||
<commons-beanutils.version>1.9.3</commons-beanutils.version>
|
<commons-beanutils.version>1.9.3</commons-beanutils.version>
|
||||||
<commons-chain.version>1.2</commons-chain.version>
|
<commons-chain.version>1.2</commons-chain.version>
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>${commons.io.version}</version>
|
<version>${commons-io.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -165,7 +165,6 @@
|
||||||
<properties>
|
<properties>
|
||||||
<assembly.plugin.version>2.3</assembly.plugin.version>
|
<assembly.plugin.version>2.3</assembly.plugin.version>
|
||||||
<commons.cli.version>1.2</commons.cli.version>
|
<commons.cli.version>1.2</commons.cli.version>
|
||||||
<commons.io.version>2.1</commons.io.version>
|
|
||||||
<httpclient.version>3.0.1</httpclient.version>
|
<httpclient.version>3.0.1</httpclient.version>
|
||||||
<storm.version>1.2.2</storm.version>
|
<storm.version>1.2.2</storm.version>
|
||||||
<kafka.version>1.0.0</kafka.version>
|
<kafka.version>1.0.0</kafka.version>
|
||||||
|
|
|
@ -74,7 +74,6 @@
|
||||||
<commons-compress-version>1.15</commons-compress-version>
|
<commons-compress-version>1.15</commons-compress-version>
|
||||||
<commons-io.version>2.3</commons-io.version>
|
<commons-io.version>2.3</commons-io.version>
|
||||||
<commons-collections4.version>4.0</commons-collections4.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>
|
<commons-beanutils.version>1.9.1</commons-beanutils.version>
|
||||||
<versions.plugin.version>2.7</versions.plugin.version>
|
<versions.plugin.version>2.7</versions.plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -74,8 +74,8 @@
|
||||||
<commons.io.version>2.3</commons.io.version>
|
<commons.io.version>2.3</commons.io.version>
|
||||||
<versions.plugin.version>2.7</versions.plugin.version>
|
<versions.plugin.version>2.7</versions.plugin.version>
|
||||||
<commons.beanutils.version>1.9.1</commons.beanutils.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.collections4.version>4.0</commons.collections4.version>
|
||||||
|
<commons.lang3.version>3.11</commons.lang3.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -27,7 +27,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>${commons.io.version}</version>
|
<version>${commons-io.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjdk.jmh</groupId>
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
@ -43,7 +43,6 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<guava.version>29.0-jre</guava.version>
|
<guava.version>29.0-jre</guava.version>
|
||||||
<commons.io.version>2.6</commons.io.version>
|
|
||||||
<jmh.version>1.19</jmh.version>
|
<jmh.version>1.19</jmh.version>
|
||||||
<modelmapper.version>2.3.7</modelmapper.version>
|
<modelmapper.version>2.3.7</modelmapper.version>
|
||||||
<hamcrest.version>2.2</hamcrest.version>
|
<hamcrest.version>2.2</hamcrest.version>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Clean Architecture with Spring Boot](https://www.baeldung.com/spring-boot-clean-architecture)
|
|
@ -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>
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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> {
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
boolean passwordIsValid();
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
String getPassword();
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||||
|
|
||||||
|
interface UserFactory {
|
||||||
|
User create(String name, String password);
|
||||||
|
}
|
|
@ -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
Loading…
Reference in New Issue