Merge remote-tracking branch 'upstream/master'

This commit is contained in:
mcasari 2023-09-17 21:05:23 +02:00
commit 7ca9e6c383
501 changed files with 8727 additions and 3175 deletions

View File

@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory;
public class KadaneAlgorithm { public class KadaneAlgorithm {
private Logger logger = LoggerFactory.getLogger(BruteForceAlgorithm.class.getName()); private Logger logger = LoggerFactory.getLogger(KadaneAlgorithm.class.getName());
public int maxSubArraySum(int[] arr) { public int maxSubArraySum(int[] arr) {
@ -14,15 +14,15 @@ public class KadaneAlgorithm {
int end = 0; int end = 0;
int maxSoFar = arr[0], maxEndingHere = arr[0]; int maxSoFar = arr[0], maxEndingHere = arr[0];
for (int i = 1; i < size; i++) { for (int i = 1; i < size; i++) {
maxEndingHere = maxEndingHere + arr[i];
if (arr[i] > maxEndingHere + arr[i]) { if (arr[i] > maxEndingHere) {
start = i;
maxEndingHere = arr[i]; maxEndingHere = arr[i];
} else { if (maxSoFar < maxEndingHere) {
maxEndingHere = maxEndingHere + arr[i]; start = i;
}
} }
if (maxSoFar < maxEndingHere) { if (maxSoFar < maxEndingHere) {
maxSoFar = maxEndingHere; maxSoFar = maxEndingHere;
end = i; end = i;

View File

@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
class KadaneAlgorithmUnitTest { class KadaneAlgorithmUnitTest {
@Test @Test
void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturns6() { void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturnsExpectedResult() {
//given //given
int[] arr = new int[] { -3, 1, -8, 4, -1, 2, 1, -5, 5 }; int[] arr = new int[] { -3, 1, -8, 4, -1, 2, 1, -5, 5 };
//when //when
@ -27,7 +27,7 @@ class KadaneAlgorithmUnitTest {
//then //then
assertEquals(-1, maxSum); assertEquals(-1, maxSum);
} }
@Test @Test
void givenArrayWithAllPosiitveNumbersWhenMaximumSubarrayThenReturnsExpectedResult() { void givenArrayWithAllPosiitveNumbersWhenMaximumSubarrayThenReturnsExpectedResult() {
//given //given
@ -39,4 +39,15 @@ class KadaneAlgorithmUnitTest {
assertEquals(10, maxSum); assertEquals(10, maxSum);
} }
@Test
void givenArrayToTestStartIndexWhenMaximumSubarrayThenReturnsExpectedResult() {
//given
int[] arr = new int[] { 1, 2, -1, 3, -6, -2 };
//when
KadaneAlgorithm algorithm = new KadaneAlgorithm();
int maxSum = algorithm.maxSubArraySum(arr);
//then
assertEquals(5, maxSum);
}
} }

View File

@ -3,4 +3,5 @@
- [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number) - [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number)
- [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array) - [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array)
- [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image) - [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image)
- [Calculate Distance Between Two Coordinates in Java](https://www.baeldung.com/java-find-distance-between-points)
- More articles: [[<-- prev]](/algorithms-miscellaneous-6) - More articles: [[<-- prev]](/algorithms-miscellaneous-6)

View File

@ -1,7 +0,0 @@
## Annotations
This module contains articles about Java annotations
### Relevant Articles:
- [Java Annotation Processing and Creating a Builder](https://www.baeldung.com/java-annotation-processing-builder)

View File

@ -1,21 +0,0 @@
<?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>annotations</artifactId>
<name>annotations</name>
<packaging>pom</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modules>
<module>annotation-processing</module>
<module>annotation-user</module>
</modules>
</project>

View File

@ -43,19 +43,19 @@
<dependency> <dependency>
<groupId>com.sun.xml.ws</groupId> <groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId> <artifactId>jaxws-ri</artifactId>
<version>2.3.3</version> <version>${jaxws-ri.version}</version>
<type>pom</type> <type>pom</type>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version> <version>${javax.servlet-api.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId> <artifactId>jstl</artifactId>
<version>1.2</version> <version>${jstl.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
@ -117,7 +117,9 @@
<properties> <properties>
<spring.version>5.3.25</spring.version> <spring.version>5.3.25</spring.version>
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version> <cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version> <jstl.version>1.2</jstl.version>
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
<jaxws-ri.version>2.3.3</jaxws-ri.version>
</properties> </properties>
</project> </project>

View File

@ -14,6 +14,7 @@ import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie; import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.http.cookie.ClientCookie;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -51,8 +52,8 @@ class HttpClientGettingCookieValueUnitTest {
private BasicCookieStore createCustomCookieStore() { private BasicCookieStore createCustomCookieStore() {
BasicCookieStore cookieStore = new BasicCookieStore(); BasicCookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("custom_cookie", "test_value"); BasicClientCookie cookie = new BasicClientCookie("custom_cookie", "test_value");
cookie.setDomain("baeldung.com"); cookie.setDomain("github.com");
cookie.setAttribute("domain", "true"); cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "github.com");
cookie.setPath("/"); cookie.setPath("/");
cookieStore.addCookie(cookie); cookieStore.addCookie(cookie);
return cookieStore; return cookieStore;

View File

@ -16,7 +16,7 @@ public class ApacheHttpClient5UnitTest {
public static final String DUMMY_URL = "https://postman-echo.com/get"; public static final String DUMMY_URL = "https://postman-echo.com/get";
@Test @Test
public void whenUseApacheHttpClient_thenCorrect() throws IOException { void whenUseApacheHttpClient_thenCorrect() throws IOException {
HttpGet request = new HttpGet(DUMMY_URL); HttpGet request = new HttpGet(DUMMY_URL);
try (CloseableHttpClient client = HttpClients.createDefault()) { try (CloseableHttpClient client = HttpClients.createDefault()) {

View File

@ -1,6 +1,5 @@
package com.baeldung.httpclient.readresponsebodystring; package com.baeldung.httpclient.readresponsebodystring;
import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -8,11 +7,13 @@ import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
public class HttpClientUnitTest { import org.junit.jupiter.api.Test;
class HttpClientUnitTest {
public static final String DUMMY_URL = "https://postman-echo.com/get"; public static final String DUMMY_URL = "https://postman-echo.com/get";
@Test @Test
public void whenUseHttpClient_thenCorrect() throws IOException, InterruptedException { void whenUseHttpClient_thenCorrect() throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(DUMMY_URL)).build(); HttpRequest request = HttpRequest.newBuilder().uri(URI.create(DUMMY_URL)).build();

View File

@ -1,7 +1,7 @@
package com.baeldung.httpclient.readresponsebodystring; package com.baeldung.httpclient.readresponsebodystring;
import org.junit.Assert;
import org.junit.Test; import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
@ -10,12 +10,14 @@ import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import org.junit.jupiter.api.Test;
public class HttpUrlConnectionUnitTest { public class HttpUrlConnectionUnitTest {
public static final String DUMMY_URL = "https://postman-echo.com/get"; public static final String DUMMY_URL = "https://postman-echo.com/get";
@Test @Test
public void whenUseHttpUrlConnection_thenCorrect() throws IOException { void whenUseHttpUrlConnection_thenCorrect() throws IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(DUMMY_URL).openConnection(); HttpURLConnection connection = (HttpURLConnection) new URL(DUMMY_URL).openConnection();
InputStream inputStream = connection.getInputStream(); InputStream inputStream = connection.getInputStream();
@ -28,7 +30,7 @@ public class HttpUrlConnectionUnitTest {
response.append(currentLine); response.append(currentLine);
in.close(); in.close();
Assert.assertNotNull(response.toString()); assertNotNull(response.toString());
System.out.println("Response -> " + response.toString()); System.out.println("Response -> " + response.toString());
} }
} }

View File

@ -1,6 +1,6 @@
package com.baeldung.httpclient.readresponsebodystring; package com.baeldung.httpclient.readresponsebodystring;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
public class SpringRestTemplateUnitTest { public class SpringRestTemplateUnitTest {

View File

@ -1,6 +1,6 @@
package com.baeldung.httpclient.readresponsebodystring; package com.baeldung.httpclient.readresponsebodystring;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -8,7 +8,7 @@ public class SpringWebClientUnitTest {
public static final String DUMMY_URL = "https://postman-echo.com/get"; public static final String DUMMY_URL = "https://postman-echo.com/get";
@Test @Test
public void whenUseWebClientRetrieve_thenCorrect() { void whenUseWebClientRetrieve_thenCorrect() {
WebClient webClient = WebClient.create(DUMMY_URL); WebClient webClient = WebClient.create(DUMMY_URL);
Mono<String> body = webClient.get().retrieve().bodyToMono(String.class); Mono<String> body = webClient.get().retrieve().bodyToMono(String.class);
String s = body.block(); String s = body.block();

View File

@ -4,6 +4,7 @@
<pattern>%date [%level] %logger - %msg %n</pattern> <pattern>%date [%level] %logger - %msg %n</pattern>
</encoder> </encoder>
</appender> </appender>
<logger name="com.baeldung.httpclient.cookies" level="info"/>
<logger name="com.baeldung.httpclient.readresponsebodystring" level="debug"/> <logger name="com.baeldung.httpclient.readresponsebodystring" level="debug"/>
<logger name="org.apache.http" level="debug"/> <logger name="org.apache.http" level="debug"/>

View File

@ -15,45 +15,6 @@
</parent> </parent>
<dependencies> <dependencies>
<!-- http client -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>${httpclient.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>${httpasyncclient.version}</version> <!-- 4.0.2 --> <!-- 4.1-beta1 -->
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents.core5</groupId> <groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5</artifactId> <artifactId>httpcore5</artifactId>
@ -115,12 +76,8 @@
</build> </build>
<properties> <properties>
<!-- util -->
<httpasyncclient.version>4.1.4</httpasyncclient.version>
<!-- testing -->
<mockserver.version>5.6.1</mockserver.version> <mockserver.version>5.6.1</mockserver.version>
<wiremock.version>2.5.1</wiremock.version> <wiremock.version>2.5.1</wiremock.version>
<httpclient.version>4.5.8</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 -->
<!-- http client & core 5 --> <!-- http client & core 5 -->
<httpcore5.version>5.2</httpcore5.version> <httpcore5.version>5.2</httpcore5.version>
<httpclient5.version>5.2</httpclient5.version> <httpclient5.version>5.2</httpclient5.version>

View File

@ -4,10 +4,10 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.hc.core5.http.ParseException;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.FileBody; import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.HttpMultipartMode; import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
@ -19,6 +19,7 @@ import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpStatus; import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.ParseException;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
@ -30,9 +31,6 @@ import java.net.URL;
class HttpClientMultipartLiveTest extends GetRequestMockServer { class HttpClientMultipartLiveTest extends GetRequestMockServer {
// No longer available
// private static final String SERVER = "http://echo.200please.com";
private static final String SERVER = "http://localhost:8080/spring-mvc-java/stub/multipart"; private static final String SERVER = "http://localhost:8080/spring-mvc-java/stub/multipart";
private static final String TEXTFILENAME = "temp.txt"; private static final String TEXTFILENAME = "temp.txt";
private static final String IMAGEFILENAME = "image.jpg"; private static final String IMAGEFILENAME = "image.jpg";

View File

@ -1,15 +1,16 @@
package com.baeldung.httpclient; package com.baeldung.httpclient;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import org.junit.jupiter.api.Test;
import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.DefaultRedirectStrategy; import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.io.IOException; import java.io.IOException;

View File

@ -8,7 +8,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException; import java.io.IOException;
@ -29,21 +29,34 @@ import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.io.entity.StringEntity; import org.apache.hc.core5.http.io.entity.StringEntity;
import org.junit.Rule;
import org.junit.Test;
import com.github.tomakehurst.wiremock.junit.WireMockRule; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class HttpClientAdvancedConfigurationIntegrationTest { import com.github.tomakehurst.wiremock.WireMockServer;
@Rule class HttpClientAdvancedConfigurationIntegrationTest {
public WireMockRule serviceMock = new WireMockRule(8089);
@Rule public WireMockServer serviceMock;
public WireMockRule proxyMock = new WireMockRule(8090); public WireMockServer proxyMock;
@BeforeEach
public void before () {
serviceMock = new WireMockServer(8089);
serviceMock.start();
proxyMock = new WireMockServer(8090);
proxyMock.start();
}
@AfterEach
public void after () {
serviceMock.stop();
proxyMock.stop();
}
@Test @Test
public void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException { void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException {
//given //given
String userAgent = "BaeldungAgent/1.0"; String userAgent = "BaeldungAgent/1.0";
serviceMock.stubFor(get(urlEqualTo("/detail")) serviceMock.stubFor(get(urlEqualTo("/detail"))
@ -59,11 +72,11 @@ public class HttpClientAdvancedConfigurationIntegrationTest {
HttpResponse response = httpClient.execute(httpGet); HttpResponse response = httpClient.execute(httpGet);
//then //then
assertEquals(response.getCode(), 200); assertEquals(200, response.getCode());
} }
@Test @Test
public void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException { void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException {
//given //given
String xmlBody = "<xml><id>1</id></xml>"; String xmlBody = "<xml><id>1</id></xml>";
serviceMock.stubFor(post(urlEqualTo("/person")) serviceMock.stubFor(post(urlEqualTo("/person"))
@ -82,12 +95,12 @@ public class HttpClientAdvancedConfigurationIntegrationTest {
HttpResponse response = httpClient.execute(httpPost); HttpResponse response = httpClient.execute(httpPost);
//then //then
assertEquals(response.getCode(), 200); assertEquals(200, response.getCode());
} }
@Test @Test
public void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException {
//given //given
proxyMock.stubFor(get(urlMatching(".*")) proxyMock.stubFor(get(urlMatching(".*"))
.willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); .willReturn(aResponse().proxiedFrom("http://localhost:8089/")));
@ -107,7 +120,7 @@ public class HttpClientAdvancedConfigurationIntegrationTest {
HttpResponse response = httpclient.execute(httpGet); HttpResponse response = httpclient.execute(httpGet);
//then //then
assertEquals(response.getCode(), 200); assertEquals(200, response.getCode());
proxyMock.verify(getRequestedFor(urlEqualTo("/private"))); proxyMock.verify(getRequestedFor(urlEqualTo("/private")));
serviceMock.verify(getRequestedFor(urlEqualTo("/private"))); serviceMock.verify(getRequestedFor(urlEqualTo("/private")));
} }
@ -151,7 +164,7 @@ public class HttpClientAdvancedConfigurationIntegrationTest {
HttpResponse response = httpclient.execute(httpGet, context); HttpResponse response = httpclient.execute(httpGet, context);
//then //then
assertEquals(response.getCode(), 200); assertEquals(200, response.getCode());
proxyMock.verify(getRequestedFor(urlEqualTo("/private")).withHeader("Authorization", containing("Basic"))); proxyMock.verify(getRequestedFor(urlEqualTo("/private")).withHeader("Authorization", containing("Basic")));
serviceMock.verify(getRequestedFor(urlEqualTo("/private"))); serviceMock.verify(getRequestedFor(urlEqualTo("/private")));
} }

View File

@ -1,59 +0,0 @@
package com.baeldung.httpclient.base;
import com.baeldung.httpclient.ResponseUtil;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class HttpClientBasicPostLiveTest {
private static final String SAMPLE_URL = "http://www.github.com";
private CloseableHttpClient instance;
private CloseableHttpResponse response;
@Before
public final void before() {
instance = HttpClientBuilder.create().build();
}
@After
public final void after() throws IllegalStateException, IOException {
ResponseUtil.closeResponse(response);
}
// tests - non-GET
@Test
public final void whenExecutingPostRequest_thenNoExceptions() throws IOException {
instance.execute(new HttpPost(SAMPLE_URL));
}
@Test
public final void whenExecutingPostRequestWithBody_thenNoExceptions() throws IOException {
final HttpPost request = new HttpPost(SAMPLE_URL);
request.setEntity(new StringEntity("in the body of the POST"));
instance.execute(request);
}
@Test
public final void givenAuth_whenExecutingPostRequestWithBody_thenNoExceptions() throws IOException, AuthenticationException {
final HttpPost request = new HttpPost(SAMPLE_URL);
request.setEntity(new StringEntity("in the body of the POST"));
final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("username", "password");
request.addHeader(new BasicScheme().authenticate(creds, request, null));
instance.execute(request);
}
}

View File

@ -1,75 +0,0 @@
package com.baeldung.httpclient.base;
import com.baeldung.httpclient.ResponseUtil;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import static org.hamcrest.Matchers.emptyArray;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
public class HttpClientLiveTest {
private static final String SAMPLE_URL = "http://www.github.com";
private CloseableHttpClient instance;
private CloseableHttpResponse response;
@Before
public final void before() {
instance = HttpClientBuilder.create().build();
}
@After
public final void after() throws IllegalStateException, IOException {
ResponseUtil.closeResponse(response);
}
// tests
@Test(expected = ConnectTimeoutException.class)
public final void givenLowTimeout_whenExecutingRequestWithTimeout_thenException() throws IOException {
final RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(5).setConnectTimeout(5).setSocketTimeout(2).build();
final HttpGet request = new HttpGet(SAMPLE_URL);
request.setConfig(requestConfig);
response = instance.execute(request);
}
// tests - configs
@Test
public final void givenHttpClientIsConfiguredWithCustomConnectionManager_whenExecutingRequest_thenNoExceptions() throws IOException {
instance = HttpClientBuilder.create().setConnectionManager(new BasicHttpClientConnectionManager()).build();
response = instance.execute(new HttpGet(SAMPLE_URL));
}
@Test
public final void givenCustomHeaderIsSet_whenSendingRequest_thenNoExceptions() throws IOException {
final HttpGet request = new HttpGet(SAMPLE_URL);
request.addHeader(HttpHeaders.ACCEPT, "application/xml");
response = instance.execute(request);
}
@Test
public final void givenRequestWasSet_whenAnalyzingTheHeadersOfTheResponse_thenCorrect() throws IOException {
response = instance.execute(new HttpGet(SAMPLE_URL));
final Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE);
assertThat(headers, not(emptyArray()));
}
}

View File

@ -1,5 +1,6 @@
package com.baeldung.httpclient.conn; package com.baeldung.httpclient.conn;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@ -34,14 +35,13 @@ import org.apache.hc.core5.pool.PoolStats;
import org.apache.hc.core5.util.Args; import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout; import org.apache.hc.core5.util.Timeout;
import org.junit.Assert; import org.junit.jupiter.api.Test;
import org.junit.Test;
public class HttpClientConnectionManagementLiveTest { class HttpClientConnectionManagementLiveTest {
// Example 2.1. Getting a Connection Request for a Low Level Connection (HttpClientConnection) // Example 2.1. Getting a Connection Request for a Low Level Connection (HttpClientConnection)
@Test @Test
public final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ExecutionException, InterruptedException, TimeoutException { final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ExecutionException, InterruptedException, TimeoutException {
BasicHttpClientConnectionManager connMgr = new BasicHttpClientConnectionManager(); BasicHttpClientConnectionManager connMgr = new BasicHttpClientConnectionManager();
HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 443)); HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 443));
final LeaseRequest connRequest = connMgr.lease("some-id", route, null); final LeaseRequest connRequest = connMgr.lease("some-id", route, null);
@ -51,7 +51,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 3.1. Setting the PoolingHttpClientConnectionManager on a HttpClient // Example 3.1. Setting the PoolingHttpClientConnectionManager on a HttpClient
@Test @Test
public final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws IOException { final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws IOException {
PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom() CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(poolingConnManager) .setConnectionManager(poolingConnManager)
@ -65,7 +65,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 3.2. Using Two HttpClients to Connect to One Target Host Each // Example 3.2. Using Two HttpClients to Connect to One Target Host Each
@Test @Test
public final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException, IOException { final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException, IOException {
HttpGet get1 = new HttpGet("https://www.baeldung.com"); HttpGet get1 = new HttpGet("https://www.baeldung.com");
HttpGet get2 = new HttpGet("https://www.google.com"); HttpGet get2 = new HttpGet("https://www.google.com");
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
@ -83,8 +83,7 @@ public class HttpClientConnectionManagementLiveTest {
thread1.join(); thread1.join();
thread2.join(); thread2.join();
Assert.assertTrue(connManager.getTotalStats() assertEquals(0, connManager.getTotalStats().getLeased());
.getLeased() == 0);
client1.close(); client1.close();
client2.close(); client2.close();
connManager.close(); connManager.close();
@ -92,7 +91,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 4.1. Increasing the Number of Connections that Can be Open and Managed Beyond the default Limits // Example 4.1. Increasing the Number of Connections that Can be Open and Managed Beyond the default Limits
@Test @Test
public final void whenIncreasingConnectionPool_thenNoExceptions() { final void whenIncreasingConnectionPool_thenNoExceptions() {
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(5); connManager.setMaxTotal(5);
connManager.setDefaultMaxPerRoute(4); connManager.setDefaultMaxPerRoute(4);
@ -103,7 +102,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 4.2. Using Threads to Execute Connections // Example 4.2. Using Threads to Execute Connections
@Test @Test
public final void whenExecutingSameRequestsInDifferentThreads_thenExecuteRequest() throws InterruptedException, IOException { final void whenExecutingSameRequestsInDifferentThreads_thenExecuteRequest() throws InterruptedException, IOException {
HttpGet get = new HttpGet("http://www.baeldung.com"); HttpGet get = new HttpGet("http://www.baeldung.com");
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom() CloseableHttpClient client = HttpClients.custom()
@ -133,7 +132,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 5.1. A Custom Keep Alive Strategy // Example 5.1. A Custom Keep Alive Strategy
@Test @Test
public final void whenCustomizingKeepAliveStrategy_thenNoExceptions() { final void whenCustomizingKeepAliveStrategy_thenNoExceptions() {
final ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() { final ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
@Override @Override
public TimeValue getKeepAliveDuration(HttpResponse response, HttpContext context) { public TimeValue getKeepAliveDuration(HttpResponse response, HttpContext context) {
@ -162,7 +161,7 @@ public class HttpClientConnectionManagementLiveTest {
//Example 6.1. BasicHttpClientConnectionManager Connection Reuse //Example 6.1. BasicHttpClientConnectionManager Connection Reuse
@Test @Test
public final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws InterruptedException, ExecutionException, TimeoutException, IOException, URISyntaxException { final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws InterruptedException, ExecutionException, TimeoutException, IOException, URISyntaxException {
BasicHttpClientConnectionManager connMgr = new BasicHttpClientConnectionManager(); BasicHttpClientConnectionManager connMgr = new BasicHttpClientConnectionManager();
HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 443)); HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 443));
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();
@ -184,7 +183,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 6.2. PoolingHttpClientConnectionManager: Re-Using Connections with Threads // Example 6.2. PoolingHttpClientConnectionManager: Re-Using Connections with Threads
@Test @Test
public final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException, IOException { final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException, IOException {
HttpGet get = new HttpGet("http://www.baeldung.com"); HttpGet get = new HttpGet("http://www.baeldung.com");
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setDefaultMaxPerRoute(6); connManager.setDefaultMaxPerRoute(6);
@ -208,7 +207,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 7.1. Setting Socket Timeout to 5 Seconds // Example 7.1. Setting Socket Timeout to 5 Seconds
@Test @Test
public final void whenConfiguringTimeOut_thenNoExceptions() throws ExecutionException, InterruptedException, TimeoutException, IOException { final void whenConfiguringTimeOut_thenNoExceptions() throws ExecutionException, InterruptedException, TimeoutException, IOException {
final HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); final HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80));
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();
final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
@ -227,7 +226,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 8.1. Setting the HttpClient to Check for Stale Connections // Example 8.1. Setting the HttpClient to Check for Stale Connections
@Test @Test
public final void whenEvictIdealConn_thenNoExceptions() throws InterruptedException, IOException { final void whenEvictIdealConn_thenNoExceptions() throws InterruptedException, IOException {
final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(100); connManager.setMaxTotal(100);
try (final CloseableHttpClient httpclient = HttpClients.custom() try (final CloseableHttpClient httpclient = HttpClients.custom()
@ -266,7 +265,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 9.1. Closing Connection and Releasing Resources // Example 9.1. Closing Connection and Releasing Resources
@Test @Test
public final void whenClosingConnectionsandManager_thenCloseWithNoExceptions1() throws IOException { final void whenClosingConnectionsAndManager_thenCloseWithNoExceptions1() throws IOException {
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom() CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connManager) .setConnectionManager(connManager)
@ -282,7 +281,7 @@ public class HttpClientConnectionManagementLiveTest {
@Test @Test
// Example 3.2. TESTER VERSION // Example 3.2. TESTER VERSION
public final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException, IOException { final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException, IOException {
HttpGet get1 = new HttpGet("https://www.baeldung.com"); HttpGet get1 = new HttpGet("https://www.baeldung.com");
HttpGet get2 = new HttpGet("https://www.google.com"); HttpGet get2 = new HttpGet("https://www.google.com");
@ -300,8 +299,7 @@ public class HttpClientConnectionManagementLiveTest {
thread2.start(); thread2.start();
thread1.join(); thread1.join();
thread2.join(1000); thread2.join(1000);
Assert.assertTrue(poolingConnManager.getTotalStats() assertEquals(2, poolingConnManager.getTotalStats().getLeased());
.getLeased() == 2);
client1.close(); client1.close();
client2.close(); client2.close();

View File

@ -1,41 +0,0 @@
package com.baeldung.httpclient.conn;
import java.util.concurrent.TimeUnit;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
public class IdleConnectionMonitorThread extends Thread {
private final HttpClientConnectionManager connMgr;
private volatile boolean shutdown;
IdleConnectionMonitorThread(final PoolingHttpClientConnectionManager connMgr) {
super();
this.connMgr = connMgr;
}
// API
@Override
public final void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(1000);
connMgr.closeExpiredConnections();
connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
}
}
} catch (final InterruptedException ex) {
shutdown();
}
}
private void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}

View File

@ -6,7 +6,6 @@ import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -241,8 +241,6 @@
<httpcore.version>4.4.16</httpcore.version> <httpcore.version>4.4.16</httpcore.version>
<httpclient.version>4.5.14</httpclient.version> <httpclient.version>4.5.14</httpclient.version>
<mockserver.version>5.11.2</mockserver.version> <mockserver.version>5.11.2</mockserver.version>
<!-- maven plugins -->
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -1,7 +1,7 @@
package com.baeldung.httpclient.base; package com.baeldung.client;
import java.io.IOException;
import com.baeldung.httpclient.GetRequestMockServer;
import com.baeldung.httpclient.ResponseUtil;
import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider; import org.apache.http.client.CredentialsProvider;
@ -12,15 +12,16 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException; import com.baeldung.GetRequestMockServer;
import com.baeldung.httpclient.ResponseUtil;
/* /*
* NOTE : Need module spring-security-rest-basic-auth to be running * NOTE : Need module spring-security-rest-basic-auth to be running
*/ */
public class HttpClientSandboxLiveTest extends GetRequestMockServer { class HttpClientSandboxLiveTest extends GetRequestMockServer {
@Test @Test
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws IOException { final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws IOException {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
final AuthScope authscp = new AuthScope("localhost", 8080); final AuthScope authscp = new AuthScope("localhost", 8080);
credentialsProvider.setCredentials(authscp, new UsernamePasswordCredentials("user1", "user1Pass")); credentialsProvider.setCredentials(authscp, new UsernamePasswordCredentials("user1", "user1Pass"));

View File

@ -35,7 +35,7 @@ import org.springframework.web.client.RestTemplate;
* This test requires a localhost server over HTTPS <br> * This test requires a localhost server over HTTPS <br>
* It should only be manually run, not part of the automated build * It should only be manually run, not part of the automated build
* */ * */
public class RestClientV4LiveManualTest { class RestClientV4LiveManualTest {
final String urlOverHttps = "http://localhost:8082/httpclient-simple/api/bars/1"; final String urlOverHttps = "http://localhost:8082/httpclient-simple/api/bars/1";
@ -81,7 +81,7 @@ public class RestClientV4LiveManualTest {
} }
@Test @Test
public void whenHttpsUrlIsConsumed_thenException() throws ClientProtocolException, IOException { void whenHttpsUrlIsConsumed_thenException() throws ClientProtocolException, IOException {
CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpClient httpClient = HttpClients.createDefault();
String urlOverHttps = "https://localhost:8082/httpclient-simple"; String urlOverHttps = "https://localhost:8082/httpclient-simple";
HttpGet getMethod = new HttpGet(urlOverHttps); HttpGet getMethod = new HttpGet(urlOverHttps);

View File

@ -2,8 +2,6 @@ package com.baeldung.httpclient;
import java.io.IOException; import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
public final class ClientUtil { public final class ClientUtil {

View File

@ -1,4 +1,5 @@
package com.baeldung.httpclient; package com.baeldung.httpclient;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;

View File

@ -9,11 +9,11 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.junit.After; import org.junit.jupiter.api.AfterEach;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
public class HttpClientCancelRequestV4LiveTest { class HttpClientCancelRequestV4LiveTest {
private static final String SAMPLE_URL = "http://www.github.com"; private static final String SAMPLE_URL = "http://www.github.com";
@ -21,18 +21,18 @@ public class HttpClientCancelRequestV4LiveTest {
private CloseableHttpResponse response; private CloseableHttpResponse response;
@Before @BeforeEach
public final void before() { public final void before() {
instance = HttpClientBuilder.create().build(); instance = HttpClientBuilder.create().build();
} }
@After @AfterEach
public final void after() throws IllegalStateException, IOException { public final void after() throws IllegalStateException, IOException {
ResponseUtil.closeResponse(response); ResponseUtil.closeResponse(response);
} }
@Test @Test
public final void whenRequestIsCanceled_thenCorrect() throws IOException { final void whenRequestIsCanceled_thenCorrect() throws IOException {
instance = HttpClients.custom().build(); instance = HttpClients.custom().build();
final HttpGet request = new HttpGet(SAMPLE_URL); final HttpGet request = new HttpGet(SAMPLE_URL);
response = instance.execute(request); response = instance.execute(request);

View File

@ -1,5 +1,9 @@
package com.baeldung.httpclient; package com.baeldung.httpclient;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -181,4 +185,20 @@ class HttpClientCookBookV4LiveTest {
} }
} }
@Test
final void whenExecutingPostRequestWithBody_thenNoExceptions() throws IOException {
final HttpPost request = new HttpPost(SAMPLE_POST_URL);
request.setEntity(new StringEntity("in the body of the POST"));
client.execute(request);
}
@Test
final void givenAuth_whenExecutingPostRequestWithBody_thenNoExceptions() throws IOException, AuthenticationException {
final HttpPost request = new HttpPost(SAMPLE_POST_URL);
request.setEntity(new StringEntity("in the body of the POST"));
final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("username", "password");
request.addHeader(new BasicScheme().authenticate(creds, request, null));
client.execute(request);
}
} }

View File

@ -1,12 +1,12 @@
package com.baeldung.httpclient; package com.baeldung.httpclient;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.io.IOException; import java.io.IOException;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;

View File

@ -92,6 +92,26 @@ class HttpClientTimeoutV4LiveTest extends GetRequestMockServer {
} }
@Test
final void givenLowTimeout_whenExecutingRequestWithTimeout_thenException() {
final RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(5)
.setConnectTimeout(5)
.setSocketTimeout(2)
.build();
final CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.build();
final HttpGet request = new HttpGet("http://www.github.com");
assertThrows(ConnectTimeoutException.class, () -> {
response = client.execute(request);
});
}
@Test @Test
void whenSecuredRestApiIsConsumed_then200OK() throws IOException { void whenSecuredRestApiIsConsumed_then200OK() throws IOException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build(); CloseableHttpClient httpClient = HttpClientBuilder.create().build();

View File

@ -1,7 +1,7 @@
package com.baeldung.httpclient.advancedconfig; package com.baeldung.httpclient.advancedconfig;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
@ -19,8 +19,10 @@ import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner; import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.junit.Rule;
import org.junit.Test; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException; import java.io.IOException;
@ -32,18 +34,29 @@ import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
public class HttpClientAdvancedConfigurationIntegrationTest { class HttpClientAdvancedConfigurationIntegrationTest {
@Rule public WireMockServer serviceMock;
public WireMockRule serviceMock = new WireMockRule(8089); public WireMockServer proxyMock;
@Rule @BeforeEach
public WireMockRule proxyMock = new WireMockRule(8090); public void before () {
serviceMock = new WireMockServer(8089);
serviceMock.start();
proxyMock = new WireMockServer(8090);
proxyMock.start();
}
@AfterEach
public void after () {
serviceMock.stop();
proxyMock.stop();
}
@Test @Test
public void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException { void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException {
//given //given
String userAgent = "BaeldungAgent/1.0"; String userAgent = "BaeldungAgent/1.0";
serviceMock.stubFor(get(urlEqualTo("/detail")) serviceMock.stubFor(get(urlEqualTo("/detail"))
@ -59,11 +72,11 @@ public class HttpClientAdvancedConfigurationIntegrationTest {
HttpResponse response = httpClient.execute(httpGet); HttpResponse response = httpClient.execute(httpGet);
//then //then
assertEquals(response.getStatusLine().getStatusCode(), 200); assertEquals(200, response.getStatusLine().getStatusCode());
} }
@Test @Test
public void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException { void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException {
//given //given
String xmlBody = "<xml><id>1</id></xml>"; String xmlBody = "<xml><id>1</id></xml>";
serviceMock.stubFor(post(urlEqualTo("/person")) serviceMock.stubFor(post(urlEqualTo("/person"))
@ -82,12 +95,11 @@ public class HttpClientAdvancedConfigurationIntegrationTest {
HttpResponse response = httpClient.execute(httpPost); HttpResponse response = httpClient.execute(httpPost);
//then //then
assertEquals(response.getStatusLine().getStatusCode(), 200); assertEquals(200, response.getStatusLine().getStatusCode());
} }
@Test @Test
public void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException {
//given //given
proxyMock.stubFor(get(urlMatching(".*")) proxyMock.stubFor(get(urlMatching(".*"))
.willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); .willReturn(aResponse().proxiedFrom("http://localhost:8089/")));
@ -107,13 +119,13 @@ public class HttpClientAdvancedConfigurationIntegrationTest {
HttpResponse response = httpclient.execute(httpGet); HttpResponse response = httpclient.execute(httpGet);
//then //then
assertEquals(response.getStatusLine().getStatusCode(), 200); assertEquals(200, response.getStatusLine().getStatusCode());
proxyMock.verify(getRequestedFor(urlEqualTo("/private"))); proxyMock.verify(getRequestedFor(urlEqualTo("/private")));
serviceMock.verify(getRequestedFor(urlEqualTo("/private"))); serviceMock.verify(getRequestedFor(urlEqualTo("/private")));
} }
@Test @Test
public void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException {
//given //given
proxyMock.stubFor(get(urlMatching("/private")) proxyMock.stubFor(get(urlMatching("/private"))
.willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); .willReturn(aResponse().proxiedFrom("http://localhost:8089/")));
@ -152,7 +164,7 @@ public class HttpClientAdvancedConfigurationIntegrationTest {
HttpResponse response = httpclient.execute(httpGet, context); HttpResponse response = httpclient.execute(httpGet, context);
//then //then
assertEquals(response.getStatusLine().getStatusCode(), 200); assertEquals(200, response.getStatusLine().getStatusCode());
proxyMock.verify(getRequestedFor(urlEqualTo("/private")).withHeader("Authorization", containing("Basic"))); proxyMock.verify(getRequestedFor(urlEqualTo("/private")).withHeader("Authorization", containing("Basic")));
serviceMock.verify(getRequestedFor(urlEqualTo("/private"))); serviceMock.verify(getRequestedFor(urlEqualTo("/private")));
} }

View File

@ -12,34 +12,35 @@ import org.apache.http.client.methods.HttpHead;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
public class HttpClientExpandUrlLiveTest {
class HttpClientExpandUrlLiveTest {
private CloseableHttpClient client; private CloseableHttpClient client;
@Before @BeforeEach
public final void before() { public final void beforeEach() {
client = HttpClientBuilder.create().disableRedirectHandling().build(); client = HttpClientBuilder.create().disableRedirectHandling().build();
} }
@Test @Test
public final void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException { final void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException {
final String expectedResult = "https://www.baeldung.com/rest-versioning"; final String expectedResult = "https://www.baeldung.com/rest-versioning";
final String actualResult = expandSingleLevel("http://bit.ly/3LScTri"); final String actualResult = expandSingleLevel("http://bit.ly/3LScTri");
assertThat(actualResult, equalTo(expectedResult)); assertThat(actualResult, equalTo(expectedResult));
} }
@Test @Test
public final void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException { final void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException {
final String expectedResult = "https://www.baeldung.com/rest-versioning"; final String expectedResult = "https://www.baeldung.com/rest-versioning";
final String actualResult = expand("http://t.co/e4rDDbnzmk"); final String actualResult = expand("http://t.co/e4rDDbnzmk");
assertThat(actualResult, equalTo(expectedResult)); assertThat(actualResult, equalTo(expectedResult));

View File

@ -17,7 +17,6 @@ import com.baeldung.GetRequestMockServer;
class ApacheHttpClientUnitTest extends GetRequestMockServer { class ApacheHttpClientUnitTest extends GetRequestMockServer {
@Test @Test
void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException { void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {

View File

@ -1,7 +1,9 @@
package com.baeldung.httpclient.httpclient.conn; package com.baeldung.httpclient.httpclient.conn;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -24,6 +26,7 @@ import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.ConnectionRequest;
import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
@ -33,14 +36,14 @@ import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpCoreContext;
import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.junit.Ignore; import org.junit.jupiter.api.Disabled;
import org.junit.Test; import org.junit.jupiter.api.Test;
public class HttpClientConnectionManagementLiveTest { class HttpClientConnectionManagementLiveTest {
// Example 2.1. Getting a Connection Request for a Low Level Connection (HttpClientConnection) // Example 2.1. Getting a Connection Request for a Low Level Connection (HttpClientConnection)
@Test @Test
public final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ConnectionPoolTimeoutException, InterruptedException, ExecutionException { final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ConnectionPoolTimeoutException, InterruptedException, ExecutionException {
try (BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager()) { try (BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager()) {
HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80));
final ConnectionRequest connRequest = connManager.requestConnection(route, null); final ConnectionRequest connRequest = connManager.requestConnection(route, null);
@ -50,20 +53,20 @@ public class HttpClientConnectionManagementLiveTest {
// Example 3.1. Setting the PoolingHttpClientConnectionManager on a HttpClient // Example 3.1. Setting the PoolingHttpClientConnectionManager on a HttpClient
@Test @Test
public final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws ClientProtocolException, IOException { final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws ClientProtocolException, IOException {
PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom() CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(poolingConnManager) .setConnectionManager(poolingConnManager)
.build(); .build();
client.execute(new HttpGet("https://www.baeldung.com")); client.execute(new HttpGet("https://www.baeldung.com"));
assertTrue(poolingConnManager.getTotalStats() assertEquals(1, poolingConnManager.getTotalStats()
.getLeased() == 1); .getLeased());
} }
// Example 3.2. Using Two HttpClients to Connect to One Target Host Each // Example 3.2. Using Two HttpClients to Connect to One Target Host Each
@Test @Test
public final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException { final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException {
HttpGet get1 = new HttpGet("https://www.baeldung.com"); HttpGet get1 = new HttpGet("https://www.baeldung.com");
HttpGet get2 = new HttpGet("https://www.google.com"); HttpGet get2 = new HttpGet("https://www.google.com");
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
@ -81,13 +84,13 @@ public class HttpClientConnectionManagementLiveTest {
thread1.join(); thread1.join();
thread2.join(); thread2.join();
assertTrue(connManager.getTotalStats() assertEquals(0, connManager.getTotalStats()
.getLeased() == 0); .getLeased());
} }
// Example 4.1. Increasing the Number of Connections that Can be Open and Managed Beyond the default Limits // Example 4.1. Increasing the Number of Connections that Can be Open and Managed Beyond the default Limits
@Test @Test
public final void whenIncreasingConnectionPool_thenNoEceptions() { final void whenIncreasingConnectionPool_thenNoEceptions() {
try (PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager()) { try (PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager()) {
connManager.setMaxTotal(5); connManager.setMaxTotal(5);
connManager.setDefaultMaxPerRoute(4); connManager.setDefaultMaxPerRoute(4);
@ -98,7 +101,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 4.2. Using Threads to Execute Connections // Example 4.2. Using Threads to Execute Connections
@Test @Test
public final void whenExecutingSameRequestsInDifferentThreads_thenExecuteReuqest() throws InterruptedException { final void whenExecutingSameRequestsInDifferentThreads_thenExecuteReuqest() throws InterruptedException {
HttpGet get = new HttpGet("http://www.baeldung.com"); HttpGet get = new HttpGet("http://www.baeldung.com");
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom() CloseableHttpClient client = HttpClients.custom()
@ -117,7 +120,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 5.1. A Custom Keep Alive Strategy // Example 5.1. A Custom Keep Alive Strategy
@Test @Test
public final void whenCustomizingKeepAliveStrategy_thenNoExceptions() { final void whenCustomizingKeepAliveStrategy_thenNoExceptions() {
final ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() { final ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
@Override @Override
public long getKeepAliveDuration(final HttpResponse myResponse, final HttpContext myContext) { public long getKeepAliveDuration(final HttpResponse myResponse, final HttpContext myContext) {
@ -148,7 +151,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 6.1. BasicHttpClientConnectionManager Connection Reuse // Example 6.1. BasicHttpClientConnectionManager Connection Reuse
@Test @Test
public final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws IOException, HttpException, InterruptedException, ExecutionException { final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws IOException, HttpException, InterruptedException, ExecutionException {
BasicHttpClientConnectionManager basicConnManager = new BasicHttpClientConnectionManager(); BasicHttpClientConnectionManager basicConnManager = new BasicHttpClientConnectionManager();
HttpClientContext context = HttpClientContext.create(); HttpClientContext context = HttpClientContext.create();
@ -175,7 +178,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 6.2. PoolingHttpClientConnectionManager: Re-Using Connections with Threads // Example 6.2. PoolingHttpClientConnectionManager: Re-Using Connections with Threads
@Test @Test
public final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException { final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException {
HttpGet get = new HttpGet("http://echo.200please.com"); HttpGet get = new HttpGet("http://echo.200please.com");
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setDefaultMaxPerRoute(5); connManager.setDefaultMaxPerRoute(5);
@ -197,20 +200,20 @@ public class HttpClientConnectionManagementLiveTest {
// Example 7.1. Setting Socket Timeout to 5 Seconds // Example 7.1. Setting Socket Timeout to 5 Seconds
@Test @Test
public final void whenConfiguringTimeOut_thenNoExceptions() { final void whenConfiguringTimeOut_thenNoExceptions() {
HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80));
try (PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager()) { try (PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager()) {
connManager.setSocketConfig(route.getTargetHost(), SocketConfig.custom() connManager.setSocketConfig(route.getTargetHost(), SocketConfig.custom()
.setSoTimeout(5000) .setSoTimeout(5000)
.build()); .build());
assertTrue(connManager.getSocketConfig(route.getTargetHost()) assertEquals(5000, connManager.getSocketConfig(route.getTargetHost())
.getSoTimeout() == 5000); .getSoTimeout());
} }
} }
// Example 8.1. Setting the HttpClient to Check for Stale Connections // Example 8.1. Setting the HttpClient to Check for Stale Connections
@Test @Test
public final void whenHttpClientChecksStaleConns_thenNoExceptions() { final void whenHttpClientChecksStaleConns_thenNoExceptions() {
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
HttpClients.custom() HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom() .setDefaultRequestConfig(RequestConfig.custom()
@ -222,7 +225,7 @@ public class HttpClientConnectionManagementLiveTest {
// Example 8.2. Using a Stale Connection Monitor Thread // Example 8.2. Using a Stale Connection Monitor Thread
@Test @Test
public final void whenCustomizedIdleConnMonitor_thenNoExceptions() throws InterruptedException { final void whenCustomizedIdleConnMonitor_thenNoExceptions() throws InterruptedException {
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
HttpClients.custom() HttpClients.custom()
.setConnectionManager(connManager) .setConnectionManager(connManager)
@ -233,8 +236,8 @@ public class HttpClientConnectionManagementLiveTest {
} }
// Example 9.1. Closing Connection and Releasing Resources // Example 9.1. Closing Connection and Releasing Resources
@Test(expected = IllegalStateException.class) @Test
public final void whenClosingConnectionsandManager_thenCloseWithNoExceptions1() throws InterruptedException, ExecutionException, IOException, HttpException { final void whenClosingConnectionsAndManager_thenCloseWithNoExceptions1() throws IOException {
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom() CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connManager) .setConnectionManager(connManager)
@ -248,14 +251,14 @@ public class HttpClientConnectionManagementLiveTest {
connManager.close(); connManager.close();
connManager.shutdown(); connManager.shutdown();
client.execute(get); assertThrows(IllegalStateException.class, () -> {
client.execute(get);
assertTrue(response.getEntity() == null); });
} }
@Test @Test
// Example 3.2. TESTER VERSION // Example 3.2. TESTER VERSION
public final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException { final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException {
HttpGet get1 = new HttpGet("https://www.baeldung.com"); HttpGet get1 = new HttpGet("https://www.baeldung.com");
HttpGet get2 = new HttpGet("https://www.google.com"); HttpGet get2 = new HttpGet("https://www.google.com");
@ -273,13 +276,13 @@ public class HttpClientConnectionManagementLiveTest {
thread2.start(); thread2.start();
thread1.join(); thread1.join();
thread2.join(1000); thread2.join(1000);
assertTrue(poolingConnManager.getTotalStats() assertEquals(2, poolingConnManager.getTotalStats()
.getLeased() == 2); .getLeased());
} }
@Test @Test
// Example 4.2 Tester Version // Example 4.2 Tester Version
public final void whenExecutingSameRequestsInDifferentThreads_thenUseDefaultConnLimit() throws InterruptedException { final void whenExecutingSameRequestsInDifferentThreads_thenUseDefaultConnLimit() throws InterruptedException {
PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom() CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(poolingConnManager) .setConnectionManager(poolingConnManager)
@ -297,7 +300,7 @@ public class HttpClientConnectionManagementLiveTest {
@Test @Test
// 6.2 TESTER VERSION // 6.2 TESTER VERSION
public final void whenConnectionsNeededGreaterThanMaxTotal_thenReuseConnections() throws InterruptedException { final void whenConnectionsNeededGreaterThanMaxTotal_thenReuseConnections() throws InterruptedException {
PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
poolingConnManager.setDefaultMaxPerRoute(5); poolingConnManager.setDefaultMaxPerRoute(5);
poolingConnManager.setMaxTotal(5); poolingConnManager.setMaxTotal(5);
@ -316,15 +319,15 @@ public class HttpClientConnectionManagementLiveTest {
thread.join(10000); thread.join(10000);
countConnMade++; countConnMade++;
if (countConnMade == 0) { if (countConnMade == 0) {
assertTrue(thread.getLeasedConn() == 5); assertEquals(5, thread.getLeasedConn());
} }
} }
} }
@Test @Test
@Ignore("Very Long Running") @Disabled("Very Long Running")
// 8.2 TESTER VERSION // 8.2 TESTER VERSION
public final void whenCustomizedIdleConnMonitor_thenEliminateIdleConns() throws InterruptedException { final void whenCustomizedIdleConnMonitor_thenEliminateIdleConns() throws InterruptedException {
PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom() CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(poolingConnManager) .setConnectionManager(poolingConnManager)
@ -340,10 +343,10 @@ public class HttpClientConnectionManagementLiveTest {
thread2.start(); thread2.start();
thread2.join(); thread2.join();
thread3.start(); thread3.start();
assertTrue(poolingConnManager.getTotalStats() assertEquals(1, poolingConnManager.getTotalStats()
.getAvailable() == 1); .getAvailable());
thread3.join(32000); thread3.join(32000);
assertTrue(poolingConnManager.getTotalStats() assertEquals(0, poolingConnManager.getTotalStats()
.getAvailable() == 0); .getAvailable());
} }
} }

View File

@ -3,7 +3,6 @@ package com.baeldung.httpclient.httpclient.conn;
import java.io.IOException; import java.io.IOException;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

View File

@ -2,7 +2,6 @@ package com.baeldung.httpclient.httpclient.conn;
import java.io.IOException; import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

View File

@ -6,18 +6,19 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
public class ApacheHttpClientUnitTest { class ApacheHttpClientUnitTest {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String DUMMY_URL = "https://postman-echo.com/get"; public static final String DUMMY_URL = "https://postman-echo.com/get";
@Test @Test
public void whenUseApacheHttpClient_thenCorrect() throws IOException { void whenUseApacheHttpClient_thenCorrect() throws IOException {
HttpGet request = new HttpGet(DUMMY_URL); HttpGet request = new HttpGet(DUMMY_URL);
try (CloseableHttpClient client = HttpClients.createDefault(); CloseableHttpResponse response = client.execute(request)) { try (CloseableHttpClient client = HttpClients.createDefault(); CloseableHttpResponse response = client.execute(request)) {

View File

@ -24,7 +24,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class ApacheHttpClientRetryLiveTest { class ApacheHttpClientRetryLiveTest {
private Integer requestCounter; private Integer requestCounter;
private CloseableHttpClient httpClient; private CloseableHttpClient httpClient;
@ -93,14 +93,14 @@ public class ApacheHttpClientRetryLiveTest {
} }
@Test @Test
public void givenDefaultConfiguration_whenReceivedIOException_thenRetriesPerformed() { void givenDefaultConfiguration_whenReceivedIOException_thenRetriesPerformed() {
createFailingHttpClient(); createFailingHttpClient();
assertThrows(IOException.class, () -> httpClient.execute(new HttpGet("https://httpstat.us/200"))); assertThrows(IOException.class, () -> httpClient.execute(new HttpGet("https://httpstat.us/200")));
assertThat(requestCounter).isEqualTo(4); assertThat(requestCounter).isEqualTo(4);
} }
@Test @Test
public void givenDefaultConfiguration_whenDomainNameNotResolved_thenNoRetryApplied() { void givenDefaultConfiguration_whenDomainNameNotResolved_thenNoRetryApplied() {
createDefaultApacheHttpClient(); createDefaultApacheHttpClient();
HttpGet request = new HttpGet(URI.create("http://domain.that.does.not.exist:80/api/v1")); HttpGet request = new HttpGet(URI.create("http://domain.that.does.not.exist:80/api/v1"));
@ -109,7 +109,7 @@ public class ApacheHttpClientRetryLiveTest {
} }
@Test @Test
public void givenDefaultConfiguration_whenGotInternalServerError_thenNoRetryLogicApplied() throws IOException { void givenDefaultConfiguration_whenGotInternalServerError_thenNoRetryLogicApplied() throws IOException {
createDefaultApacheHttpClient(); createDefaultApacheHttpClient();
HttpGet request = new HttpGet(URI.create("https://httpstat.us/500")); HttpGet request = new HttpGet(URI.create("https://httpstat.us/500"));
@ -120,7 +120,7 @@ public class ApacheHttpClientRetryLiveTest {
} }
@Test @Test
public void givenDefaultConfiguration_whenHttpPatchRequest_thenRetryIsNotApplied() { void givenDefaultConfiguration_whenHttpPatchRequest_thenRetryIsNotApplied() {
createFailingHttpClient(); createFailingHttpClient();
HttpPatch request = new HttpPatch(URI.create("https://httpstat.us/500")); HttpPatch request = new HttpPatch(URI.create("https://httpstat.us/500"));
@ -129,7 +129,7 @@ public class ApacheHttpClientRetryLiveTest {
} }
@Test @Test
public void givenDefaultConfiguration_whenHttpPutRequest_thenRetryIsNotApplied() { void givenDefaultConfiguration_whenHttpPutRequest_thenRetryIsNotApplied() {
createFailingHttpClient(); createFailingHttpClient();
HttpPut request = new HttpPut(URI.create("https://httpstat.us/500")); HttpPut request = new HttpPut(URI.create("https://httpstat.us/500"));
@ -138,7 +138,7 @@ public class ApacheHttpClientRetryLiveTest {
} }
@Test @Test
public void givenConfiguredRetryHandler_whenHttpPostRequest_thenRetriesPerformed() { void givenConfiguredRetryHandler_whenHttpPostRequest_thenRetriesPerformed() {
createHttpClientWithRetryHandler(); createHttpClientWithRetryHandler();
HttpPost request = new HttpPost(URI.create("https://httpstat.us/200")); HttpPost request = new HttpPost(URI.create("https://httpstat.us/200"));
@ -148,7 +148,7 @@ public class ApacheHttpClientRetryLiveTest {
} }
@Test @Test
public void givenCustomRetryHandler_whenUnknownHostException_thenRetryAnyway() { void givenCustomRetryHandler_whenUnknownHostException_thenRetryAnyway() {
createHttpClientWithCustomRetryHandler(); createHttpClientWithCustomRetryHandler();
HttpGet request = new HttpGet(URI.create("https://domain.that.does.not.exist/200")); HttpGet request = new HttpGet(URI.create("https://domain.that.does.not.exist/200"));
@ -158,7 +158,7 @@ public class ApacheHttpClientRetryLiveTest {
} }
@Test @Test
public void givenDisabledRetries_whenExecutedHttpRequestEndUpWithIOException_thenRetryIsNotApplied() { void givenDisabledRetries_whenExecutedHttpRequestEndUpWithIOException_thenRetryIsNotApplied() {
createHttpClientWithRetriesDisabled(); createHttpClientWithRetriesDisabled();
HttpGet request = new HttpGet(URI.create("https://httpstat.us/200")); HttpGet request = new HttpGet(URI.create("https://httpstat.us/200"));

View File

@ -0,0 +1,2 @@
## Relevant Articles
- [Understanding XSLT Processing in Java](https://www.baeldung.com/java-extensible-stylesheet-language-transformations)

View File

@ -21,7 +21,6 @@
</dependency> </dependency>
</dependencies> </dependencies>
<properties> <properties>
<javax.validation.validation-api.version>2.0.1.Final</javax.validation.validation-api.version> <javax.validation.validation-api.version>2.0.1.Final</javax.validation.validation-api.version>
</properties> </properties>

View File

@ -0,0 +1,31 @@
package com.baeldung.xsltProcessing;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
public class XSLTProcessorWithParametersAndOption {
public static void transformXMLWithParametersAndOption(
String inputXMLPath,
String xsltPath,
String outputHTMLPath,
String companyName,
boolean enableIndentation
) throws TransformerException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Source xsltSource = new StreamSource(new File(xsltPath));
Transformer transformer = transformerFactory.newTransformer(xsltSource);
transformer.setParameter("companyName", companyName);
if (enableIndentation) {
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
}
Source xmlSource = new StreamSource(new File(inputXMLPath));
Result outputResult = new StreamResult(new File(outputHTMLPath));
transformer.transform(xmlSource, outputResult);
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.xsltProcessing;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
public class XSLTProcessorWithTemplate {
public static void transformXMLUsingTemplate(String inputXMLPath, String xsltPath, String outputHTMLPath) throws TransformerException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Source xsltSource = new StreamSource(new File(xsltPath));
Templates templates = transformerFactory.newTemplates(xsltSource);
Transformer transformer = templates.newTransformer();
Source xmlSource = new StreamSource(new File(inputXMLPath));
Result outputResult = new StreamResult(new File(outputHTMLPath));
transformer.transform(xmlSource, outputResult);
}
}

View File

@ -63,7 +63,6 @@
<org.apache.httpcomponents.version>4.5.2</org.apache.httpcomponents.version> <org.apache.httpcomponents.version>4.5.2</org.apache.httpcomponents.version>
<velocity-version>1.7</velocity-version> <velocity-version>1.7</velocity-version>
<velocity-tools-version>2.0</velocity-tools-version> <velocity-tools-version>2.0</velocity-tools-version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -49,7 +49,6 @@
<properties> <properties>
<asm.version>5.2</asm.version> <asm.version>5.2</asm.version>
<maven-jar-plugin.version>2.4</maven-jar-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?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" <project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 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> <modelVersion>4.0.0</modelVersion>
<artifactId>aws-s3-update-object</artifactId> <artifactId>aws-s3-update-object</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>

View File

@ -8,4 +8,6 @@ This module contains articles about Simple Storage Service (S3) on AWS
- [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload) - [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload)
- [Using the JetS3t Java Client With Amazon S3](https://www.baeldung.com/jets3t-amazon-s3) - [Using the JetS3t Java Client With Amazon S3](https://www.baeldung.com/jets3t-amazon-s3)
- [Check if a Specified Key Exists in a Given S3 Bucket Using Java](https://www.baeldung.com/java-aws-s3-check-specified-key-exists) - [Check if a Specified Key Exists in a Given S3 Bucket Using Java](https://www.baeldung.com/java-aws-s3-check-specified-key-exists)
- [Listing All AWS S3 Objects in a Bucket Using Java](https://www.baeldung.com/java-aws-s3-list-bucket-objects) - [Listing All AWS S3 Objects in a Bucket Using Java](https://www.baeldung.com/java-aws-s3-list-bucket-objects)
- [Update an Existing Amazon S3 Object Using Java](https://www.baeldung.com/java-update-amazon-s3-object)
- [How To Rename Files and Folders in Amazon S3](https://www.baeldung.com/java-amazon-s3-rename-files-folders)

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> 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> <modelVersion>4.0.0</modelVersion>
<artifactId>aws-s3</artifactId> <artifactId>aws-s3</artifactId>
<version>0.1.0-SNAPSHOT</version> <version>0.1.0-SNAPSHOT</version>

View File

@ -0,0 +1,79 @@
package com.baeldung.s3;
import java.util.List;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Object;
public class RenameObjectService {
private S3Client s3Client;
public RenameObjectService(S3Client s3Client) {
this.s3Client = s3Client;
}
public RenameObjectService() {
init();
}
public void init() {
this.s3Client = S3Client.builder()
.region(Region.US_EAST_1)
.credentialsProvider(ProfileCredentialsProvider.create("default"))
.build();
}
public void renameFile(String bucketName, String keyName, String destinationKeyName) {
CopyObjectRequest copyObjRequest = CopyObjectRequest.builder()
.sourceBucket(bucketName)
.sourceKey(keyName)
.destinationBucket(destinationKeyName)
.destinationKey(bucketName)
.build();
s3Client.copyObject(copyObjRequest);
DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.build();
s3Client.deleteObject(deleteRequest);
}
public void renameFolder(String bucketName, String sourceFolderKey, String destinationFolderKey) {
ListObjectsV2Request listRequest = ListObjectsV2Request.builder()
.bucket(bucketName)
.prefix(sourceFolderKey)
.build();
ListObjectsV2Response listResponse = s3Client.listObjectsV2(listRequest);
List<S3Object> objects = listResponse.contents();
for (S3Object s3Object : objects) {
String newKey = destinationFolderKey + s3Object.key()
.substring(sourceFolderKey.length());
// Copy object to destination folder
CopyObjectRequest copyRequest = CopyObjectRequest.builder()
.sourceBucket(bucketName)
.sourceKey(s3Object.key())
.destinationBucket(bucketName)
.destinationKey(newKey)
.build();
s3Client.copyObject(copyRequest);
// Delete object from source folder
DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(s3Object.key())
.build();
s3Client.deleteObject(deleteRequest);
}
}
}

View File

@ -122,7 +122,6 @@
<docker.image.prefix>${azure.containerRegistry}.azurecr.io</docker.image.prefix> <docker.image.prefix>${azure.containerRegistry}.azurecr.io</docker.image.prefix>
<docker-maven-plugin.version>1.1.0</docker-maven-plugin.version> <docker-maven-plugin.version>1.1.0</docker-maven-plugin.version>
<azure-webapp-maven-plugin.version>1.1.0</azure-webapp-maven-plugin.version> <azure-webapp-maven-plugin.version>1.1.0</azure-webapp-maven-plugin.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -27,6 +27,7 @@
<hsqldb.version>2.7.1</hsqldb.version> <hsqldb.version>2.7.1</hsqldb.version>
<spock-core.version>2.3-groovy-3.0</spock-core.version> <spock-core.version>2.3-groovy-3.0</spock-core.version>
<gmavenplus-plugin.version>2.1.0</gmavenplus-plugin.version> <gmavenplus-plugin.version>2.1.0</gmavenplus-plugin.version>
<maven-failsafe-plugin.version>2.21.0</maven-failsafe-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -1,15 +0,0 @@
package reminderapplication;
import java.awt.GridBagConstraints;
import java.awt.Insets;
public class ConstraintsBuilder {
static GridBagConstraints constraint(int x, int y) {
final GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = x;
gridBagConstraints.gridy = y;
gridBagConstraints.insets = new Insets(5, 5, 5, 5);
return gridBagConstraints;
}
}

View File

@ -1,194 +0,0 @@
package reminderapplication;
import static reminderapplication.ConstraintsBuilder.*;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.lang.reflect.InvocationTargetException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class EditReminderFrame extends JFrame {
private static Timer TIMER = new Timer();
private final TimeReminderApplication reminderApplication;
private final JLabel reminderTextLabel;
private final JLabel repeatPeriodLabel;
private final JLabel setDelayLabel;
private final JComboBox<Integer> delay;
private final JComboBox<Integer> period;
private final JButton cancelButton;
private final JButton okButton;
private final JTextField textField;
private final JLabel delaysLabel;
private final JLabel periodLabel;
private final int reminderIndex;
public EditReminderFrame(TimeReminderApplication reminderApp, String reminderText, int delayInSeconds, int periodInSeconds, int index) throws HeadlessException {
this.reminderApplication = reminderApp;
reminderIndex = index;
textField = createTextField(reminderText);
delay = createDelayComboBox(delayInSeconds);
period = createPeriodComboBox(periodInSeconds);
cancelButton = createCancelButton();
okButton = createOkButton();
reminderTextLabel = createReminderTextLabel();
repeatPeriodLabel = createRepeatPeriodLabel();
setDelayLabel = createSetDelayLabel();
delaysLabel = createDelaysLabel();
periodLabel = createPeriodLabel();
configureVisualRepresentation();
configureActions();
}
private void configureActions() {
updateReminder();
}
private void configureVisualRepresentation() {
configureFrame();
setLocationRelativeTo(null);
setLayout(new GridBagLayout());
add(reminderTextLabel, constraint(0,0));
add(repeatPeriodLabel, constraint(1,0));
add(setDelayLabel, constraint(2,0));
add(textField, constraint(0, 1));
add(delay, constraint(1, 1));
add(period, constraint(2, 1));
add(delaysLabel, constraint(1,3));
add(periodLabel, constraint(2,3));
add(okButton, constraint(1, 4));
add(cancelButton, constraint(2, 4));
pack();
setVisible(true);
}
private void configureFrame() {
setTitle("Set Reminder");
setName("Set Reminder");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
private static JLabel createSetDelayLabel() {
return createLabel("Set Delay", "Set Delay Label");
}
private static JLabel createRepeatPeriodLabel() {
return createLabel("Set Period", "Set Repeat Period Label");
}
private static JLabel createReminderTextLabel() {
return createLabel("Reminder Text", "Reminder Text Label");
}
private JLabel createPeriodLabel() {
return createLabel("0", "Period label");
}
private JLabel createDelaysLabel() {
return createLabel("30", "Delays Label");
}
private JComboBox<Integer> createPeriodComboBox(final int periodInSeconds) {
final JComboBox<Integer> comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{0, 5, 10, 20}));
comboBox.setSelectedItem(periodInSeconds);
comboBox.setName("set Period");
comboBox.addActionListener(e -> periodLabel.setText(comboBox.getSelectedItem().toString()));
return comboBox;
}
private JComboBox<Integer> createDelayComboBox(final int delayInSeconds) {
final JComboBox<Integer> comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{30, 25, 15, 5}));
comboBox.setSelectedItem(delayInSeconds);
comboBox.setName("set Delay");
comboBox.addActionListener(e -> delaysLabel.setText(comboBox.getSelectedItem().toString()));
return comboBox;
}
private JTextField createTextField(final String reminderText) {
final JTextField textField = new JTextField(20);
textField.setName("Field");
textField.setText(reminderText);
return textField;
}
private JButton createOkButton() {
final JButton button = new JButton("ok");
button.setName("OK");
return button;
}
private void updateReminder() {
okButton.addActionListener(e -> this.dispose());
okButton.addActionListener(e -> {
final int periodInSeconds = getTimeInSeconds(period);
final int delayInSeconds = getTimeInSeconds(delay);
final Reminder reminder = new Reminder(textField.getText(), delayInSeconds, periodInSeconds);
((DefaultListModel<Reminder>) reminderApplication.getReminders()).set(reminderIndex, reminder);
});
okButton.addActionListener(e -> scheduleReminder(textField, delay, period));
}
private void scheduleReminder(final JTextField textField, final JComboBox<Integer> delay, final JComboBox<Integer> period) {
final int periodInSeconds = getTimeInSeconds(period);
if (periodInSeconds == 0)
scheduleNonRepeatedReminder(textField, delay);
else
scheduleRepeatedReminder(textField, delay, period);
}
private void scheduleRepeatedReminder(final JTextField textField, final JComboBox<Integer> delay, final JComboBox<Integer> period) {
final int delayInSeconds = getTimeInSeconds(delay);
final int periodInSeconds = getTimeInSeconds(period);
final TimerTask timerTask = getTimerTask(textField.getText(), delayInSeconds, periodInSeconds);
TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(delayInSeconds), TimeUnit.SECONDS.toMillis(periodInSeconds));
}
private void scheduleNonRepeatedReminder(final JTextField textField, final JComboBox<Integer> delay) {
final int delayInSeconds = getTimeInSeconds(delay);
final int periodInSeconds = 0;
final TimerTask timerTask = getTimerTask(textField.getText(), delayInSeconds, periodInSeconds);
TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(delayInSeconds));
}
private int getTimeInSeconds(final JComboBox<Integer> comboBox) {
if (comboBox != null && comboBox.getSelectedItem() != null)
return ((Integer) comboBox.getSelectedItem());
else
return 0;
}
private TimerTask getTimerTask(final String reminderText, final Integer delayInSeconds, final Integer periodInSeconds) {
return new TimerTask() {
@Override
public void run() {
new ReminderPopupFrame(reminderApplication, reminderText, delayInSeconds, periodInSeconds);
}
};
}
private JButton createCancelButton() {
final JButton button = new JButton("cancel");
button.setName("Cancel");
button.addActionListener(e -> this.dispose());
return button;
}
private static JLabel createLabel(final String text, final String name) {
JLabel label = new JLabel(text);
label.setName(name);
return label;
}
}

View File

@ -1,33 +0,0 @@
package reminderapplication;
public class Reminder {
private static String REMINDER_FORMAT = "Reminder Text: %s; Delay: %d; Period: %d;";
private final String name;
private final int delay;
private final int period;
public Reminder(final String name, final int delay, final int period) {
this.name = name;
this.delay = delay;
this.period = period;
}
public String getName() {
return name;
}
public int getDelay() {
return delay;
}
public int getPeriod() {
return period;
}
@Override
public String toString() {
return REMINDER_FORMAT.formatted(name, delay, period);
}
}

View File

@ -1,186 +0,0 @@
package reminderapplication;
import static reminderapplication.ConstraintsBuilder.*;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class ReminderFrame extends JFrame {
private static Timer TIMER = new Timer();
private final TimeReminderApplication reminderApplication;
private final JLabel reminderTextLabel;
private final JLabel repeatPeriodLabel;
private final JLabel setDelayLabel;
private final JComboBox<Integer> delay;
private final JComboBox<Integer> period;
private final JButton cancelButton;
private final JButton okButton;
private final JTextField textField;
private final JLabel delaysLabel;
private final JLabel periodLabel;
public ReminderFrame(TimeReminderApplication reminderApp) throws HeadlessException {
this.reminderApplication = reminderApp;
textField = createTextField();
delay = createDelayComboBox();
period = createPeriodComboBox();
cancelButton = createCancelButton();
okButton = createOkButton();
reminderTextLabel = createReminderTextLabel();
repeatPeriodLabel = createRepeatPeriodLabel();
setDelayLabel = createSetDelayLabel();
delaysLabel = createDelaysLabel();
periodLabel = createPeriodLabel();
configureVisualRepresentation();
configureActions();
}
private void configureActions() {
createNewReminder();
}
private void configureVisualRepresentation() {
configureFrame();
setLocationRelativeTo(null);
setLayout(new GridBagLayout());
add(reminderTextLabel, constraint(0,0));
add(repeatPeriodLabel, constraint(1,0));
add(setDelayLabel, constraint(2,0));
add(textField, constraint(0, 1));
add(delay, constraint(1, 1));
add(period, constraint(2, 1));
add(delaysLabel, constraint(1,3));
add(periodLabel, constraint(2,3));
add(okButton, constraint(1, 4));
add(cancelButton, constraint(2, 4));
pack();
setVisible(true);
}
private void configureFrame() {
setTitle("Set Reminder");
setName("Set Reminder");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
private static JLabel createSetDelayLabel() {
return createLabel("Set Delay", "Set Delay Label");
}
private static JLabel createRepeatPeriodLabel() {
return createLabel("Set Period", "Set Repeat Period Label");
}
private static JLabel createReminderTextLabel() {
return createLabel("Reminder Text", "Reminder Text Label");
}
private JLabel createPeriodLabel() {
return createLabel("0", "Period label");
}
private JLabel createDelaysLabel() {
return createLabel("30", "Delays Label");
}
private JComboBox<Integer> createPeriodComboBox() {
final JComboBox<Integer> comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{0, 5, 10, 20}));
comboBox.setName("set Period");
comboBox.addActionListener(e -> periodLabel.setText(comboBox.getSelectedItem().toString()));
return comboBox;
}
private JComboBox<Integer> createDelayComboBox() {
final JComboBox<Integer> comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{30, 25, 15, 5}));
comboBox.setName("set Delay");
comboBox.addActionListener(e -> delaysLabel.setText(comboBox.getSelectedItem().toString()));
return comboBox;
}
private JTextField createTextField() {
final JTextField textField = new JTextField(20);
textField.setName("Field");
return textField;
}
private JButton createOkButton() {
final JButton button = new JButton("ok");
button.setName("OK");
return button;
}
private void createNewReminder() {
okButton.addActionListener(e -> this.dispose());
okButton.addActionListener(e -> {
final int periodInSeconds = getTimeInSeconds(period);
final int delayInSeconds = getTimeInSeconds(delay);
final Reminder reminder = new Reminder(textField.getText(), delayInSeconds, periodInSeconds);
((DefaultListModel<Reminder>) reminderApplication.getReminders()).addElement(reminder);
});
okButton.addActionListener(e -> scheduleReminder(textField, delay, period));
}
private void scheduleReminder(final JTextField textField, final JComboBox<Integer> delay, final JComboBox<Integer> period) {
final int periodInSeconds = getTimeInSeconds(period);
if (periodInSeconds == 0)
scheduleNonRepeatedReminder(textField, delay);
else
scheduleRepeatedReminder(textField, delay, period);
}
private void scheduleRepeatedReminder(final JTextField textField, final JComboBox<Integer> delay, final JComboBox<Integer> period) {
final int delayInSeconds = getTimeInSeconds(delay) + 200;
final int periodInSeconds = getTimeInSeconds(period);
final TimerTask timerTask = getTimerTask(textField.getText(), delayInSeconds, periodInSeconds);
TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(delayInSeconds), TimeUnit.SECONDS.toMillis(periodInSeconds));
}
private void scheduleNonRepeatedReminder(final JTextField textField, final JComboBox<Integer> delay) {
final int delayInSeconds = getTimeInSeconds(delay);
final int periodInSeconds = 0;
final TimerTask timerTask = getTimerTask(textField.getText(), delayInSeconds, periodInSeconds);
TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(delayInSeconds));
}
private int getTimeInSeconds(final JComboBox<Integer> comboBox) {
if (comboBox != null && comboBox.getSelectedItem() != null)
return ((Integer) comboBox.getSelectedItem());
else
return 0;
}
private TimerTask getTimerTask(final String reminderText, final Integer delayInSeconds, final Integer periodInSeconds) {
return new TimerTask() {
@Override
public void run() {
new ReminderPopupFrame(reminderApplication, reminderText, delayInSeconds, periodInSeconds);
}
};
}
private JButton createCancelButton() {
final JButton button = new JButton("cancel");
button.setName("Cancel");
button.addActionListener(e -> this.dispose());
return button;
}
private static JLabel createLabel(final String text, final String name) {
JLabel label = new JLabel(text);
label.setName(name);
return label;
}
}

View File

@ -1,151 +0,0 @@
package reminderapplication;
import static reminderapplication.ConstraintsBuilder.*;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class ReminderPopupFrame extends JFrame {
private static final Timer TIMER = new Timer();
private final int AUTOMATIC_CLOSE_TIME_IN_SECONDS = 10;
private final TimeReminderApplication reminderApplication;
private final JLabel reminderTextLabel;
private final JLabel repeatPeriodLabel;
private final JLabel setDelayLabel;
private final JComboBox<Integer> delay;
private final JComboBox<Integer> period;
private final JButton cancelButton;
private final JButton okButton;
private final JTextField textField;
private final JLabel delaysLabel;
private final JLabel periodLabel;
public ReminderPopupFrame(TimeReminderApplication reminderApp, final String text, final Integer delayInSeconds, final Integer periodInSeconds) throws HeadlessException {
this.reminderApplication = reminderApp;
textField = createTextField(text);
delay = createDelayComboBox(delayInSeconds);
period = createPeriodComboBox(periodInSeconds);
cancelButton = createCancelButton();
okButton = createDisabledOkButton();
reminderTextLabel = createReminderTextLabel();
repeatPeriodLabel = createRepeatPeriodLabel();
setDelayLabel = createSetDelayLabel();
delaysLabel = createDelaysLabel();
periodLabel = createPeriodLabel();
configureVisualRepresentation();
configureActions();
}
private void configureActions() {
scheduleClosing();
}
private void scheduleClosing() {
final TimerTask timerTask = new TimerTask() {
@Override
public void run() {
ReminderPopupFrame.this.dispose();
}
};
TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(AUTOMATIC_CLOSE_TIME_IN_SECONDS));
}
private void configureVisualRepresentation() {
configureFrame();
setLocationRelativeTo(null);
setLayout(new GridBagLayout());
add(reminderTextLabel, constraint(0,0));
add(repeatPeriodLabel, constraint(1,0));
add(setDelayLabel, constraint(2,0));
add(textField, constraint(0, 1));
add(delay, constraint(1, 1));
add(period, constraint(2, 1));
add(delaysLabel, constraint(1,3));
add(periodLabel, constraint(2,3));
add(okButton, constraint(1, 4));
add(cancelButton, constraint(2, 4));
pack();
setVisible(true);
}
private void configureFrame() {
setTitle("Set Reminder");
setName("Set Reminder");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
private static JLabel createSetDelayLabel() {
return createLabel("Set Delay", "Set Delay Label");
}
private static JLabel createRepeatPeriodLabel() {
return createLabel("Set Period", "Set Repeat Period Label");
}
private static JLabel createReminderTextLabel() {
return createLabel("Reminder Text", "Reminder Text Label");
}
private JLabel createPeriodLabel() {
return createLabel("0", "Period label");
}
private JLabel createDelaysLabel() {
return createLabel("30", "Delays Label");
}
private JComboBox<Integer> createPeriodComboBox(final Integer periodInSeconds) {
final JComboBox<Integer> comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{0, 5, 10, 20}));
comboBox.setName("set Period");
comboBox.setSelectedItem(periodInSeconds);
comboBox.addActionListener(e -> periodLabel.setText(comboBox.getSelectedItem().toString()));
return comboBox;
}
private JComboBox<Integer> createDelayComboBox(Integer delay) {
final JComboBox<Integer> comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{30, 25, 15, 5}));
comboBox.setSelectedItem(delay);
comboBox.setName("set Delay");
comboBox.addActionListener(e -> delaysLabel.setText(comboBox.getSelectedItem().toString()));
return comboBox;
}
private JTextField createTextField(final String text) {
final JTextField textField = new JTextField(20);
textField.setName("Field");
textField.setText(text);
return textField;
}
private JButton createDisabledOkButton() {
final JButton button = new JButton("ok");
button.setName("OK");
button.setEnabled(false);
return button;
}
private JButton createCancelButton() {
final JButton button = new JButton("cancel");
button.setName("Cancel");
button.addActionListener(e -> this.dispose());
return button;
}
private static JLabel createLabel(final String text, final String name) {
JLabel label = new JLabel(text);
label.setName(name);
return label;
}
}

View File

@ -48,7 +48,6 @@
<properties> <properties>
<maven.compiler.release>14</maven.compiler.release> <maven.compiler.release>14</maven.compiler.release>
<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>
</properties> </properties>

View File

@ -53,7 +53,6 @@
<properties> <properties>
<maven.compiler.release>15</maven.compiler.release> <maven.compiler.release>15</maven.compiler.release>
<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>
</properties> </properties>

View File

@ -7,3 +7,4 @@
- [Random Number Generators in Java 17](https://www.baeldung.com/java-17-random-number-generators) - [Random Number Generators in Java 17](https://www.baeldung.com/java-17-random-number-generators)
- [Sealed Classes and Interfaces in Java](https://www.baeldung.com/java-sealed-classes-interfaces) - [Sealed Classes and Interfaces in Java](https://www.baeldung.com/java-sealed-classes-interfaces)
- [Migrate From Java 8 to Java 17](https://www.baeldung.com/java-migrate-8-to-17) - [Migrate From Java 8 to Java 17](https://www.baeldung.com/java-migrate-8-to-17)
- [Format Multiple or Conditions in an If Statement in Java](https://www.baeldung.com/java-multiple-or-conditions-if-statement)

View File

@ -0,0 +1,126 @@
package com.baeldung.multipleorwithif;
import static java.time.Month.DECEMBER;
import static java.time.Month.NOVEMBER;
import static java.time.Month.OCTOBER;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.in;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.Month;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.function.Predicate;
import org.junit.jupiter.api.Test;
class MultipleOrWithIfUnitTest {
private final Random rand = new Random();
final Set<Month> months = Set.of(OCTOBER, NOVEMBER, DECEMBER);
@Test
public void givenIfStatement_whenMultipleOrOperator_thenAssert() {
assertTrue(multipleOrOperatorIf(monthIn()));
assertFalse(multipleOrOperatorIf(monthNotIn()));
}
boolean multipleOrOperatorIf(Month month) {
if (month == OCTOBER || month == NOVEMBER || month == DECEMBER) {
return true;
}
return false;
}
@Test
public void givenSwitch_whenMultipleCase_thenBreakAndAssert() {
assertTrue(switchMonth(monthIn()));
assertFalse(switchMonth(monthNotIn()));
}
boolean switchMonth(Month month) {
return switch (month) {
case OCTOBER, NOVEMBER, DECEMBER -> true;
default -> false;
};
}
@Test
public void givenAllowedValuesList_whenContains_thenAssert() {
assertTrue(contains(monthIn()));
assertFalse(contains(monthNotIn()));
}
@Test
public void givenPredicates_whenTestMultipleOr_thenAssert() {
assertTrue(predicateWithIf(monthIn()));
assertFalse(predicateWithIf(monthNotIn()));
}
@Test
public void givenInputList_whenFilterWithPredicate_thenAssert() {
List<Month> list = List.of(monthIn(), monthIn(), monthNotIn());
list.stream()
.filter(this::predicateWithIf)
.forEach(m -> assertThat(m, is(in(months))));
}
Predicate<Month> orPredicate() {
Predicate<Month> predicate = x -> x == OCTOBER;
Predicate<Month> predicate1 = x -> x == NOVEMBER;
Predicate<Month> predicate2 = x -> x == DECEMBER;
return predicate.or(predicate1)
.or(predicate2);
}
boolean predicateWithIf(Month month) {
if (orPredicate().test(month)) {
return true;
}
return false;
}
@Test
public void givenContainsInSetPredicate_whenTestPredicate_thenAssert() {
Predicate<Month> collectionPredicate = this::contains;
assertTrue(collectionPredicate.test(monthIn()));
assertFalse(collectionPredicate.test(monthNotIn()));
}
@Test
public void givenInputList_whenFilterWithContains_thenAssert() {
List<Month> monthList = List.of(monthIn(), monthIn(), monthNotIn());
monthList.stream()
.filter(this::contains)
.forEach(m -> assertThat(m, is(in(months))));
}
private boolean contains(Month month) {
if (months.contains(month)) {
return true;
}
return false;
}
private Month monthIn() {
return Month.of(rand.ints(10, 13)
.findFirst()
.orElse(10));
}
private Month monthNotIn() {
return Month.of(rand.ints(1, 10)
.findFirst()
.orElse(1));
}
}

View File

@ -0,0 +1 @@
## Relevant Articles

View File

@ -0,0 +1,34 @@
<?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-21</artifactId>
<name>core-java-21</name>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<!-- <build>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-compiler-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <source>{maven.compiler.source.version}</source>-->
<!-- <target>{maven.compiler.target.version}</target>-->
<!-- </configuration>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- </build>-->
<!-- <properties>-->
<!-- <maven.compiler.source.version>21</maven.compiler.source.version>-->
<!-- <maven.compiler.target.version>21</maven.compiler.target.version>-->
<!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
<!-- </properties>-->
</project>

View File

@ -0,0 +1,15 @@
package com.baeldung.sequenced.collections;
/*
interface SequencedCollection<E> extends Collection<E> {
// new method
SequencedCollection<E> reversed();
// methods promoted from Deque
void addFirst(E);
void addLast(E);
E getFirst();
E getLast();
E removeFirst();
E removeLast();
}
*/

View File

@ -0,0 +1,18 @@
package com.baeldung.sequenced.collections;
/*
interface SequencedMap<K,V> extends Map<K,V> {
// new methods
SequencedMap<K,V> reversed();
SequencedSet<K> sequencedKeySet();
SequencedCollection<V> sequencedValues();
SequencedSet<Entry<K,V>> sequencedEntrySet();
V putFirst(K, V);
V putLast(K, V);
// methods promoted from NavigableMap
Entry<K, V> firstEntry();
Entry<K, V> lastEntry();
Entry<K, V> pollFirstEntry();
Entry<K, V> pollLastEntry();
}
*/

View File

@ -0,0 +1,7 @@
package com.baeldung.sequenced.collections;
/*
interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {
SequencedSet<E> reversed(); // covariant override
}
*/

View File

@ -0,0 +1,37 @@
package com.baeldung.stringtime;
import static org.junit.jupiter.api.Assertions.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.Calendar;
import java.util.Date;
import org.junit.jupiter.api.Test;
public class AddMinuteStringTimeUnitTest {
@Test
public void givenTimeStringUsingSimpleDateFormat_whenIncrementedWith10Minutes_thenResultShouldBeCorrect() throws ParseException {
String timeString = "23:45";
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
Date date = timeFormat.parse(timeString);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.MINUTE, 10);
String result = timeFormat.format(cal.getTime());
assertEquals("23:55", result);
}
@Test
public void givenTimeStringUsingLocalTime_whenIncrementedWith10Minutes_thenResultShouldBeCorrect() {
String timeString = "23:45";
LocalTime time = LocalTime.parse(timeString);
LocalTime newTime = time.plusMinutes(10);
String result = newTime.toString();
assertEquals("23:55", result);
}
}

View File

@ -10,7 +10,7 @@
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId> <artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../../</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<dependencies> <dependencies>

View File

@ -4,9 +4,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 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> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-9-jigsaw</artifactId> <artifactId>core-java-9-jigsaw</artifactId>
<version>0.2-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
</parent> </parent>
<artifactId>library-core</artifactId> <artifactId>library-core</artifactId>

View File

@ -11,10 +11,9 @@
</modules> </modules>
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung.core-java-modules</groupId>
<artifactId>parent-modules</artifactId> <artifactId>core-java-modules</artifactId>
<version>1.0.0-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent> </parent>
<build> <build>

View File

@ -152,7 +152,6 @@
<awaitility.version>4.0.2</awaitility.version> <awaitility.version>4.0.2</awaitility.version>
<maven.compiler.source>1.9</maven.compiler.source> <maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target> <maven.compiler.target>1.9</maven.compiler.target>
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,16 @@
package com.baeldung.streams.regexmatches;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class StreamFromRegexUtil {
public static Stream<String> getStream(String input, String regex) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
return matcher.results().map(MatchResult::group);
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.streams.regexmatches;
import org.junit.Test;
import java.util.List;
import java.util.stream.Collectors;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
public class StreamFromRegexUnitTest {
@Test
public void whenInputStringIncludeLettersAndNumbersAndRegex_ThenReturnStreamOfNumbers() {
List<String> result = StreamFromRegexUtil.getStream("There are 3 apples and 2 bananas on the table.", "\\d+")
.collect(Collectors.toList());
assertEquals(asList("3", "2"), result);
}
@Test
public void whenInputStringsAndRegex_ThenReturnStreamOfJavaWords() {
List<String> result = StreamFromRegexUtil.getStream("sample sentence with some words Java Java", "\\bJava\\b")
.collect(Collectors.toList());
assertEquals(asList("Java", "Java"), result);
}
}

View File

@ -13,3 +13,5 @@ This module contains articles about advanced operations on arrays in Java. They
- [Performance of System.arraycopy() vs. Arrays.copyOf()](https://www.baeldung.com/java-system-arraycopy-arrays-copyof-performance) - [Performance of System.arraycopy() vs. Arrays.copyOf()](https://www.baeldung.com/java-system-arraycopy-arrays-copyof-performance)
- [Slicing Arrays in Java](https://www.baeldung.com/java-slicing-arrays) - [Slicing Arrays in Java](https://www.baeldung.com/java-slicing-arrays)
- [Combining Two or More Byte Arrays](https://www.baeldung.com/java-concatenate-byte-arrays) - [Combining Two or More Byte Arrays](https://www.baeldung.com/java-concatenate-byte-arrays)
- [Calculating the Sum of Two Arrays in Java](https://www.baeldung.com/java-sum-arrays-element-wise)
- [Find the Middle Element of an Array in Java](https://www.baeldung.com/java-array-middle-item)

View File

@ -0,0 +1,65 @@
package com.baeldung.arraymiddle;
import java.util.Arrays;
import org.apache.commons.lang3.ObjectUtils;
public class MiddleOfArray {
int[] middleOfArray(int[] array) {
if (ObjectUtils.isEmpty(array) || array.length < 3)
return array;
int n = array.length;
int mid = n / 2;
if (n % 2 == 0) {
int mid2 = mid - 1;
return new int[] { array[mid2], array[mid] };
} else {
return new int[] { array[mid] };
}
}
int[] middleOfArrayWithStartEndNaive(int[] array, int start, int end) {
int mid = (start + end) / 2;
int n = end - start;
if (n % 2 == 0) {
int mid2 = mid - 1;
return new int[] { array[mid2], array[mid] };
} else {
return new int[] { array[mid] };
}
}
int[] middleOfArrayWithStartEnd(int[] array, int start, int end) {
int mid = start + (end - start) / 2;
int n = end - start;
if (n % 2 == 0) {
int mid2 = mid - 1;
return new int[] { array[mid2], array[mid] };
} else {
return new int[] { array[mid] };
}
}
int[] middleOfArrayWithStartEndBitwise(int[] array, int start, int end) {
int mid = (start + end) >>> 1;
int n = end - start;
if (n % 2 == 0) {
int mid2 = mid - 1;
return new int[] { array[mid2], array[mid] };
} else {
return new int[] { array[mid] };
}
}
int medianOfArray(int[] array, int start, int end) {
Arrays.sort(array); // for safety. This can be ignored
int mid = (start + end) >>> 1;
int n = end - start;
if (n % 2 == 0) {
int mid2 = mid - 1;
return (array[mid2] + array[mid]) / 2;
} else {
return array[mid];
}
}
}

View File

@ -0,0 +1,89 @@
package com.baeldung.arraymiddle;
import org.junit.Assert;
import org.junit.Test;
public class MiddleOfArrayUnitTest {
@Test
public void givenArrayOfEvenLength_whenMiddleOfArray_thenReturn2Values() {
int[] array = new int[100];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
int[] expectedMidArray = { 50, 51 };
MiddleOfArray middleOfArray = new MiddleOfArray();
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array));
}
@Test
public void givenArrayOfEdgeCaseLength_whenMiddleOfArray_thenReturn2Values() {
int[] array = new int[0];
int[] expectedMidArray = new int[0];
MiddleOfArray middleOfArray = new MiddleOfArray();
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array));
array = new int[] { 1, 2 };
expectedMidArray = new int[] { 1, 2 };
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array));
}
@Test
public void givenArrayOfOddLength_whenMiddleOfArray_thenReturnMid() {
int[] array = new int[99];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
int[] expectedMidArray = { 50 };
MiddleOfArray middleOfArray = new MiddleOfArray();
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array));
}
@Test
public void givenArrayWithStartAndEnd_whenMiddleOfArray_thenReturnMid() {
int[] array = new int[100];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
int[] expectedMidArray = { 58 };
MiddleOfArray middleOfArray = new MiddleOfArray();
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArrayWithStartEndNaive(array, 55, 60));
expectedMidArray = new int[] { 58, 59 };
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArrayWithStartEndNaive(array, 56, 60));
}
@Test
public void givenArrayWithStartAndEndOptimized_whenMiddleOfArray_thenReturnMid() {
int[] array = new int[100];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
int[] expectedMidArray = { 78 };
MiddleOfArray middleOfArray = new MiddleOfArray();
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArrayWithStartEnd(array, 55, 100));
}
@Test
public void givenArrayWithStartAndEndBitwise_whenMiddleOfArray_thenReturnMid() {
int[] array = new int[100];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
int[] expectedMidArray = { 78 };
MiddleOfArray middleOfArray = new MiddleOfArray();
Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArrayWithStartEndBitwise(array, 55, 100));
}
@Test
public void givenArrayWithStartAndEnd_whenMedianOfArray_thenReturnMid() {
int[] array = new int[100];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
int expectMedian = 50;
MiddleOfArray middleOfArray = new MiddleOfArray();
Assert.assertEquals(expectMedian, middleOfArray.medianOfArray(array, 0, 100));
}
}

View File

@ -13,4 +13,5 @@ This module contains articles about conversions among Collection types and array
- [Combining Two Lists Into a Map in Java](https://www.baeldung.com/java-combine-two-lists-into-map) - [Combining Two Lists Into a Map in Java](https://www.baeldung.com/java-combine-two-lists-into-map)
- [Convert a List of Strings to a List of Integers](https://www.baeldung.com/java-convert-list-strings-to-integers) - [Convert a List of Strings to a List of Integers](https://www.baeldung.com/java-convert-list-strings-to-integers)
- [Convert List to Long[] Array in Java](https://www.baeldung.com/java-convert-list-object-to-long-array) - [Convert List to Long[] Array in Java](https://www.baeldung.com/java-convert-list-object-to-long-array)
- [Get the First n Elements of a List Into an Array](https://www.baeldung.com/java-take-start-elements-list-array)
- More articles: [[<-- prev]](../core-java-collections-conversions) - More articles: [[<-- prev]](../core-java-collections-conversions)

View File

@ -12,3 +12,4 @@ This module contains articles about the Java List collection
- [Get Unique Values From an ArrayList in Java](https://www.baeldung.com/java-unique-values-arraylist) - [Get Unique Values From an ArrayList in Java](https://www.baeldung.com/java-unique-values-arraylist)
- [Converting a Java List to a Json Array](https://www.baeldung.com/java-converting-list-to-json-array) - [Converting a Java List to a Json Array](https://www.baeldung.com/java-converting-list-to-json-array)
- [Whats the Difference Between Iterator and ListIterator?](https://www.baeldung.com/java-iterator-vs-listiterator) - [Whats the Difference Between Iterator and ListIterator?](https://www.baeldung.com/java-iterator-vs-listiterator)
- [Create List of Object From Another Type Using Java 8](https://www.baeldung.com/java-generate-list-different-type)

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> 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> <modelVersion>4.0.0</modelVersion>
<artifactId>core-java-collections-list-5</artifactId> <artifactId>core-java-collections-list-5</artifactId>
<name>core-java-collections-list-5</name> <name>core-java-collections-list-5</name>

View File

@ -0,0 +1,114 @@
package com.baeldung.java.streamtoanotherlist;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;
import lombok.Getter;
@Getter
class Employee {
private final String name;
private final Set<String> hobbies = new HashSet<>();
private final String email;
private String department;
public Employee(String name, String email, Collection<String> hobbies) {
this.name = name;
this.email = email;
this.hobbies.addAll(hobbies);
}
}
class TennisPlayerCandidate {
private final String name;
private final String email;
private final Boolean confirmed = Boolean.FALSE;
public TennisPlayerCandidate(String name, String email) {
this.name = name;
this.email = email;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof TennisPlayerCandidate))
return false;
TennisPlayerCandidate that = (TennisPlayerCandidate) o;
if (!Objects.equals(name, that.name))
return false;
return Objects.equals(email, that.email);
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (email != null ? email.hashCode() : 0);
return result;
}
}
public class CreateListOfDifferentTypeUsingStreamUnitTest {
private final static List<Employee> EMPLOYEES = Lists.newArrayList(
// @formatter:off
new Employee("Kai", "kai@company.com", Lists.newArrayList("Football", "Reading", "Chess")),
new Employee("Eric", "eric@company.com", Lists.newArrayList("Tennis", "Baseball", "Singing")),
new Employee("Saajan", "saajan@company.com", Lists.newArrayList("Tennis", "Baseball", "Singing")),
new Employee("Kevin", "kevin@company.com", Lists.newArrayList("Dancing", "Computer Games", "Tennis")),
new Employee("Amanda", "amanda@company.com", Lists.newArrayList("Painting", "Yoga", "Dancing"))
//@formatter:on
);
private final static List<TennisPlayerCandidate> EXPECTED = Lists.newArrayList(
// @formatter:off
new TennisPlayerCandidate("Eric", "eric@company.com"),
new TennisPlayerCandidate("Saajan", "saajan@company.com"),
new TennisPlayerCandidate("Kevin", "kevin@company.com")
//@formatter:on
);
@Test
void whenUsingStreamForEachFillingAnotherList_thenGetExpectedResult() {
List<TennisPlayerCandidate> result = new ArrayList<>();
EMPLOYEES.forEach(e -> {
if (e.getHobbies()
.contains("Tennis")) {
result.add(new TennisPlayerCandidate(e.getName(), e.getEmail()));
}
});
assertEquals(EXPECTED, result);
}
@Test
void whenUsingStreamMap_thenGetExpectedResult() {
List<TennisPlayerCandidate> result = EMPLOYEES.stream()
.filter(e -> e.getHobbies()
.contains("Tennis"))
.map(e -> new TennisPlayerCandidate(e.getName(), e.getEmail()))
.collect(Collectors.toList());
assertEquals(EXPECTED, result);
}
@Test
void whenUsingCollectorMapping_thenGetExpectedResult() {
List<TennisPlayerCandidate> result = EMPLOYEES.stream()
.filter(e -> e.getHobbies()
.contains("Tennis"))
.collect(Collectors.mapping(e -> new TennisPlayerCandidate(e.getName(), e.getEmail()), Collectors.toList()));
assertEquals(EXPECTED, result);
}
}

View File

@ -9,4 +9,5 @@ This module contains articles about Map data structures in Java.
- [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap) - [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap)
- [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor) - [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor)
- [Converting Java Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap) - [Converting Java Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap)
- [Get Values and Keys as ArrayList From a HashMap](https://www.baeldung.com/java-values-keys-arraylists-hashmap)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)

View File

@ -0,0 +1,49 @@
package com.baeldung.map;
import java.util.HashMap;
import java.util.Map;
public class MapClear {
public static Map returnCopyAndClearMap() {
// Create a HashMap
Map<String, Integer> scores = new HashMap<>();
Map<String, Integer> scores_copy;
// Add some key-value pairs
scores.put("Alice", 90);
scores.put("Bob", 85);
scores.put("Charlie", 95);
scores_copy = scores;
System.out.println("Before clearing: " + scores);
// Clear the map
scores.clear();
System.out.println("After clearing: " + scores);
return scores_copy;
}
public static Map returnCopyAndRewriteMap() {
// Create a HashMap
Map<String, Integer> scores = new HashMap<>();
Map<String, Integer> scores_copy;
// Add some key-value pairs
scores.put("Alice", 90);
scores.put("Bob", 85);
scores.put("Charlie", 95);
scores_copy = scores;
System.out.println("Before clearing: " + scores);
// Create a new map
scores = new HashMap<>();
System.out.println("After clearing: " + scores);
return scores_copy;
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.map;
import java.util.Map;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class MapClearUnitTest {
@Test
public void givenMap_returnEntryAndClearContent() {
Map entry = MapClear.returnCopyAndClearMap();
assertTrue(entry.isEmpty());
}
@Test public void givenMap_returnEntryAndRewriteContent() {
Map entry = MapClear.returnCopyAndRewriteMap();
assertTrue(!entry.isEmpty());
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.map;
import org.junit.Test;
import java.util.HashMap;
import static org.junit.Assert.assertEquals;
public class UsingtoStringUnitTest {
@Test
public void given_HashMapString_whenUsingtoString_thenConvertToHashMapObject() {
// Example string representation of a HashMap
String hashMapString = "{key1=value1, key2=value2, key3=value3}";
// Remove unnecessary characters
String keyValuePairs = hashMapString.replaceAll("[{}\\s]", "");
// Split into individual key-value pairs
String[] pairs = keyValuePairs.split(",");
// Create a new HashMap
HashMap<String, String> expectedHashMap = new HashMap<>();
expectedHashMap.put("key1", "value1");
expectedHashMap.put("key2", "value2");
expectedHashMap.put("key3", "value3");
HashMap<String, String> actualHashMap = new HashMap<>();
// Parse and populate the HashMap
for (String pair : pairs) {
String[] keyValue = pair.split("=");
if (keyValue.length == 2) {
actualHashMap.put(keyValue[0], keyValue[1]);
}
}
// Assert that the converted HashMap matches the expected one
assertEquals(expectedHashMap, actualHashMap);
}
}

View File

@ -4,4 +4,5 @@
- [A Guide to LinkedHashSet in Java](https://www.baeldung.com/java-linkedhashset) - [A Guide to LinkedHashSet in Java](https://www.baeldung.com/java-linkedhashset)
- [Sorting a HashSet in Java](https://www.baeldung.com/java-sort-hashset) - [Sorting a HashSet in Java](https://www.baeldung.com/java-sort-hashset)
- [How to Get First Item From a Java Set](https://www.baeldung.com/first-item-set) - [How to Get First Item From a Java Set](https://www.baeldung.com/first-item-set)
- [Cartesian Product of Any Number of Sets in Java](https://www.baeldung.com/java-cartesian-product-sets)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-set) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-set)

View File

@ -20,6 +20,23 @@
<version>${junit-platform.version}</version> <version>${junit-platform.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.1-jre</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -0,0 +1,75 @@
package com.baeldung.cartesianproduct;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.Sets;
public class CartesianProduct {
public List<List<Object>> getCartesianProductIterative(List<List<Object>> sets) {
List<List<Object>> result = new ArrayList<>();
if(sets == null || sets.isEmpty()) {
return result;
}
int totalSets = sets.size();
int totalCombinations = 1 << totalSets;
for(int i = 0; i < totalCombinations; i++) {
List<Object> combination = new ArrayList<>();
for(int j = 0; j < totalSets; j++) {
if (((i >> j) & 1) == 1) {
combination.add(sets.get(j).get(0));
} else {
combination.add(sets.get(j).get(1));
}
}
result.add(combination);
}
return result;
}
public List<List<Object>> getCartesianProductRecursive(List<List<Object>> sets) {
List<List<Object>> result = new ArrayList<>();
getCartesianProductRecursiveHelper(sets, 0, new ArrayList<>(), result);
return result;
}
private void getCartesianProductRecursiveHelper(List<List<Object>> sets, int index, List<Object> current, List<List<Object>> result) {
if(index == sets.size()) {
result.add(new ArrayList<>(current));
return;
}
List<Object> currentSet = sets.get(index);
for(Object element: currentSet) {
current.add(element);
getCartesianProductRecursiveHelper(sets, index+1, current, result);
current.remove(current.size() - 1);
}
}
public List<List<Object>> getCartesianProductUsingStreams(List<List<Object>> sets) {
return cartesianProduct(sets,0).collect(Collectors.toList());
}
public Stream<List<Object>> cartesianProduct(List<List<Object>> sets, int index) {
if(index == sets.size()) {
List<Object> emptyList = new ArrayList<>();
return Stream.of(emptyList);
}
List<Object> currentSet = sets.get(index);
return currentSet.stream().flatMap(element -> cartesianProduct(sets, index+1)
.map(list -> {
List<Object> newList = new ArrayList<>(list);
newList.add(0, element); return newList;
}));
}
public List<List<Object>> getCartesianProductUsingGuava(List<Set<Object>> sets) {
Set<List<Object>> cartesianProduct = Sets.cartesianProduct(sets);
List<List<Object>> cartesianList = new ArrayList<>(cartesianProduct);
return cartesianList;
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.indexawareset;
import java.util.Iterator;
import java.util.Set;
public class IndexOfElementsInSet<E> {
public int getIndexUsingIterator(Set<E> set, E element) {
Iterator<E> iterator = set.iterator();
int index = 0;
while (iterator.hasNext()) {
if (element.equals(iterator.next())) {
return index;
}
index++;
}
return -1;
}
public int getIndexUsingForEach(Set<E> set, E element) {
int index = 0;
for (E current : set) {
if (element.equals(current)) {
return index;
}
index++;
}
return -1;
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.indexawareset;
import java.util.LinkedHashSet;
public class InsertionIndexAwareSet<E> extends LinkedHashSet<E> {
public InsertionIndexAwareSet() {
super();
}
public int getIndexOf(E element) {
int index = 0;
for (E current : this) {
if (current.equals(element)) {
return index;
}
index++;
}
return -1;
}
}

View File

@ -0,0 +1,93 @@
package com.baeldung.cartesianproduct;
import static org.testng.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.testng.annotations.Test;
public class CartesianProductUnitTest {
private CartesianProduct cp = new CartesianProduct();
List<List<Object>> sets = Arrays.asList(
Arrays.asList(10, 20),
Arrays.asList("John", "Jack"),
Arrays.asList('I', 'J')
);
@Test
public void whenUsingStreams_thenCalculateCartesianProduct() {
List<List<Object>> expected = Arrays.asList(
Arrays.asList(10, "John", 'I'),
Arrays.asList(10, "John", 'J'),
Arrays.asList(10, "Jack", 'I'),
Arrays.asList(10, "Jack", 'J'),
Arrays.asList(20, "John", 'I'),
Arrays.asList(20, "John", 'J'),
Arrays.asList(20, "Jack", 'I'),
Arrays.asList(20, "Jack", 'J')
);
List<List<Object>> cartesianProduct = cp.getCartesianProductUsingStreams(sets);
assertEquals(expected, cartesianProduct);
}
@Test
public void whenUsingRecursion_thenCalculateCartesianProduct() {
List<List<Object>> expected = Arrays.asList(
Arrays.asList(10, "John", 'I'),
Arrays.asList(10, "John", 'J'),
Arrays.asList(10, "Jack", 'I'),
Arrays.asList(10, "Jack", 'J'),
Arrays.asList(20, "John", 'I'),
Arrays.asList(20, "John", 'J'),
Arrays.asList(20, "Jack", 'I'),
Arrays.asList(20, "Jack", 'J')
);
List<List<Object>> cartesianProduct = cp.getCartesianProductRecursive(sets);
assertEquals(expected, cartesianProduct);
}
@Test
public void whenUsingIterativeApproach_thenCalculateCartesianProduct() {
List<List<Object>> expected = Arrays.asList(
Arrays.asList(20, "Jack", 'J'),
Arrays.asList(10, "Jack", 'J'),
Arrays.asList(20, "John", 'J'),
Arrays.asList(10, "John", 'J'),
Arrays.asList(20, "Jack", 'I'),
Arrays.asList(10, "Jack", 'I'),
Arrays.asList(20, "John", 'I'),
Arrays.asList(10, "John", 'I')
);
List<List<Object>> cartesianProduct = cp.getCartesianProductIterative(sets);
assertEquals(expected, cartesianProduct);
}
@Test
public void whenUsingGuava_thenCalculateCartesianProduct() {
List<Set<Object>> sets = new ArrayList<>();
sets.add(new HashSet<>(Arrays.asList(10, 20)));
sets.add(new HashSet<>(Arrays.asList("John", "Jack")));
sets.add(new HashSet<>(Arrays.asList('I', 'J')));
List<List<Object>> expected = Arrays.asList(
Arrays.asList(20, "John", 'I'),
Arrays.asList(20, "John", 'J'),
Arrays.asList(20, "Jack", 'I'),
Arrays.asList(20, "Jack", 'J'),
Arrays.asList(10, "John", 'I'),
Arrays.asList(10, "John", 'J'),
Arrays.asList(10, "Jack", 'I'),
Arrays.asList(10, "Jack", 'J')
);
List<List<Object>> cartesianProduct = cp.getCartesianProductUsingGuava(sets);
assertEquals(expected, cartesianProduct);
}
}

View File

@ -0,0 +1,108 @@
package com.baeldung.indexawareset;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.collections4.set.ListOrderedSet;
import org.junit.Assert;
import org.junit.Test;
public class IndexOfSetElementsUsingListUnitTest {
@Test
public void givenHashSet_whenIndexOfElement_thenGivesIndex() {
Set<Integer> set = new HashSet<>();
set.add(100);
set.add(20);
set.add(300);
set.add(0);
set.add(-1);
set.add(300);
IndexOfElementsInSet<Integer> integerIndexOfElementsInSet = new IndexOfElementsInSet<>();
int index100 = integerIndexOfElementsInSet.getIndexUsingIterator(set, 100);
Assert.assertEquals(index100, integerIndexOfElementsInSet.getIndexUsingIterator(set, 100));
Assert.assertEquals(-1, integerIndexOfElementsInSet.getIndexUsingIterator(set, 12));
}
@Test
public void givenLinkedHashSet_whenIndexOfElement_thenGivesIndex() {
Set<Integer> set = new LinkedHashSet<>();
set.add(100);
set.add(20);
set.add(300);
set.add(0);
set.add(-1);
set.add(300);
IndexOfElementsInSet<Integer> integerIndexOfElementsInSet = new IndexOfElementsInSet<>();
Assert.assertEquals(0, integerIndexOfElementsInSet.getIndexUsingIterator(set, 100));
}
@Test
public void givenTreeSet_whenIndexOfElement_thenGivesIndex() {
Set<Integer> set = new TreeSet<>();
set.add(100);
set.add(20);
set.add(300);
set.add(0);
set.add(-1);
set.add(300);
IndexOfElementsInSet<Integer> integerIndexOfElementsInSet = new IndexOfElementsInSet<>();
Assert.assertEquals(0, integerIndexOfElementsInSet.getIndexUsingIterator(set, -1));
Assert.assertEquals(3, integerIndexOfElementsInSet.getIndexUsingIterator(set, 100));
}
@Test
public void givenIndexAwareSet_whenIndexOfElement_thenGivesIndex() {
InsertionIndexAwareSet<Integer> set = new InsertionIndexAwareSet<>();
set.add(100);
set.add(20);
set.add(300);
Assert.assertEquals(0, set.getIndexOf(100));
Assert.assertEquals(2, set.getIndexOf(300));
Assert.assertEquals(-1, set.getIndexOf(0));
}
@Test
public void givenIndexAwareSetWithStrings_whenIndexOfElement_thenGivesIndex() {
InsertionIndexAwareSet<String> set = new InsertionIndexAwareSet<>();
set.add("Go");
set.add("Java");
set.add("Scala");
set.add("Python");
Assert.assertEquals(0, set.getIndexOf("Go"));
Assert.assertEquals(2, set.getIndexOf("Scala"));
Assert.assertEquals(-1, set.getIndexOf("C++"));
}
@Test
public void givenListOrderedSet_whenIndexOfElement_thenGivesIndex() {
ListOrderedSet<Integer> set = new ListOrderedSet<>();
set.add(12);
set.add(0);
set.add(-1);
set.add(50);
Assert.assertEquals(0, set.indexOf(12));
Assert.assertEquals(2, set.indexOf(-1));
Assert.assertEquals(-1, set.indexOf(100));
}
@Test
public void givenLinkedHashSet_whenIndexUsingUtilityMethod_thenReturnsIndex() {
Set<Integer> set = new LinkedHashSet<>();
set.add(100);
set.add(20);
set.add(300);
set.add(0);
set.add(-1);
set.add(300);
IndexOfElementsInSet<Integer> integerIndexOfElementsInSet = new IndexOfElementsInSet<>();
Assert.assertEquals(-1, integerIndexOfElementsInSet.getIndexUsingForEach(set, 150));
}
}

View File

@ -4,6 +4,7 @@ import java.util.logging.Logger;
public class Consumer implements Runnable { public class Consumer implements Runnable {
private static final Logger log = Logger.getLogger(Consumer.class.getCanonicalName()); private static final Logger log = Logger.getLogger(Consumer.class.getCanonicalName());
private boolean running = false;
private final DataQueue dataQueue; private final DataQueue dataQueue;
public Consumer(DataQueue dataQueue) { public Consumer(DataQueue dataQueue) {
@ -12,26 +13,36 @@ public class Consumer implements Runnable {
@Override @Override
public void run() { public void run() {
running = true;
consume(); consume();
} }
public void stop() {
running = false;
}
public void consume() { public void consume() {
while (dataQueue.runFlag) { while (running) {
while (dataQueue.isEmpty() && dataQueue.runFlag) {
if (dataQueue.isEmpty()) {
try { try {
dataQueue.waitOnEmpty(); dataQueue.waitIsNotEmpty();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); log.severe("Error while waiting to Consume messages.");
break; break;
} }
} }
if (!dataQueue.runFlag) {
// avoid spurious wake-up
if (!running) {
break; break;
} }
Message message = dataQueue.remove();
dataQueue.notifyAllForFull(); Message message = dataQueue.poll();
useMessage(message); useMessage(message);
//Sleeping on random time to make it realistic
ThreadUtil.sleep((long) (Math.random() * 100));
} }
log.info("Consumer Stopped"); log.info("Consumer Stopped");
} }
@ -40,14 +51,7 @@ public class Consumer implements Runnable {
if (message != null) { if (message != null) {
log.info(String.format("[%s] Consuming Message. Id: %d, Data: %f%n", log.info(String.format("[%s] Consuming Message. Id: %d, Data: %f%n",
Thread.currentThread().getName(), message.getId(), message.getData())); Thread.currentThread().getName(), message.getId(), message.getData()));
//Sleeping on random time to make it realistic
ThreadUtil.sleep((long) (message.getData() * 100));
} }
} }
public void stop() {
dataQueue.runFlag = false;
dataQueue.notifyAllForEmpty();
}
} }

View File

@ -6,10 +6,8 @@ import java.util.Queue;
public class DataQueue { public class DataQueue {
private final Queue<Message> queue = new LinkedList<>(); private final Queue<Message> queue = new LinkedList<>();
private final int maxSize; private final int maxSize;
private final Object FULL_QUEUE = new Object(); private final Object IS_NOT_FULL = new Object();
private final Object EMPTY_QUEUE = new Object(); private final Object IS_NOT_EMPTY = new Object();
public boolean runFlag = true;
DataQueue(int maxSize) { DataQueue(int maxSize) {
this.maxSize = maxSize; this.maxSize = maxSize;
@ -23,39 +21,42 @@ public class DataQueue {
return queue.isEmpty(); return queue.isEmpty();
} }
public void waitOnFull() throws InterruptedException { public void waitIsNotFull() throws InterruptedException {
synchronized (FULL_QUEUE) { synchronized (IS_NOT_FULL) {
FULL_QUEUE.wait(); IS_NOT_FULL.wait();
} }
} }
public void waitOnEmpty() throws InterruptedException { public void waitIsNotEmpty() throws InterruptedException {
synchronized (EMPTY_QUEUE) { synchronized (IS_NOT_EMPTY) {
EMPTY_QUEUE.wait(); IS_NOT_EMPTY.wait();
}
}
public void notifyAllForFull() {
synchronized (FULL_QUEUE) {
FULL_QUEUE.notifyAll();
}
}
public void notifyAllForEmpty() {
synchronized (EMPTY_QUEUE) {
EMPTY_QUEUE.notifyAll();
} }
} }
public void add(Message message) { public void add(Message message) {
synchronized (queue) { queue.add(message);
queue.add(message); notifyIsNotEmpty();
}
public Message poll() {
Message mess = queue.poll();
notifyIsNotFull();
return mess;
}
public Integer getSize() {
return queue.size();
}
private void notifyIsNotFull() {
synchronized (IS_NOT_FULL) {
IS_NOT_FULL.notify();
} }
} }
public Message remove() { private void notifyIsNotEmpty() {
synchronized (queue) { synchronized (IS_NOT_EMPTY) {
return queue.poll(); IS_NOT_EMPTY.notify();
} }
} }
} }

View File

@ -1,60 +1,63 @@
package com.baeldung.producerconsumer; package com.baeldung.producerconsumer;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger; import java.util.logging.Logger;
public class Producer implements Runnable { public class Producer implements Runnable {
private static final Logger log = Logger.getLogger(Producer.class.getCanonicalName()); private static final Logger log = Logger.getLogger(Producer.class.getCanonicalName());
private static final AtomicInteger idSequence = new AtomicInteger(0);
private boolean running = false;
private final DataQueue dataQueue; private final DataQueue dataQueue;
private static int idSequence = 0;
public Producer(DataQueue dataQueue) { public Producer(DataQueue dataQueue) {
this.dataQueue = dataQueue; this.dataQueue = dataQueue;
} }
@Override @Override
public void run() { public void run() {
running = true;
produce(); produce();
} }
public void stop() {
running = false;
}
public void produce() { public void produce() {
while (dataQueue.runFlag) {
while (dataQueue.isFull() && dataQueue.runFlag) { while (running) {
if (dataQueue.isFull()) {
try { try {
dataQueue.waitOnFull(); dataQueue.waitIsNotFull();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); log.severe("Error while waiting to Produce messages.");
break; break;
} }
} }
if (!dataQueue.runFlag) {
// avoid spurious wake-up
if (!running) {
break; break;
} }
Message message = generateMessage();
dataQueue.add(message);
dataQueue.notifyAllForEmpty();
dataQueue.add(generateMessage());
log.info("Size of the queue is: " + dataQueue.getSize());
//Sleeping on random time to make it realistic
ThreadUtil.sleep((long) (Math.random() * 100));
} }
log.info("Producer Stopped"); log.info("Producer Stopped");
} }
private Message generateMessage() { private Message generateMessage() {
Message message = new Message(incrementAndGetId(), Math.random()); Message message = new Message(idSequence.incrementAndGet(), Math.random());
log.info(String.format("[%s] Generated Message. Id: %d, Data: %f%n", log.info(String.format("[%s] Generated Message. Id: %d, Data: %f%n",
Thread.currentThread().getName(), message.getId(), message.getData())); Thread.currentThread().getName(), message.getId(), message.getData()));
//Sleeping on random time to make it realistic
ThreadUtil.sleep((long) (message.getData() * 100));
return message; return message;
} }
private static int incrementAndGetId() {
return ++idSequence;
}
public void stop() {
dataQueue.runFlag = false;
dataQueue.notifyAllForFull();
}
} }

View File

@ -27,7 +27,7 @@ public class ProducerConsumerDemonstrator {
// let threads run for two seconds // let threads run for two seconds
sleep(2000); sleep(2000);
// Stop threads // stop threads
producer.stop(); producer.stop();
consumer.stop(); consumer.stop();
@ -36,28 +36,34 @@ public class ProducerConsumerDemonstrator {
public static void demoMultipleProducersAndMultipleConsumers() { public static void demoMultipleProducersAndMultipleConsumers() {
DataQueue dataQueue = new DataQueue(MAX_QUEUE_CAPACITY); DataQueue dataQueue = new DataQueue(MAX_QUEUE_CAPACITY);
int producerCount = 3; int producerCount = 5;
int consumerCount = 3; int consumerCount = 5;
List<Thread> threads = new ArrayList<>(); List<Thread> threads = new ArrayList<>();
Producer producer = new Producer(dataQueue); List<Producer> producers = new ArrayList<>();
List<Consumer> consumers = new ArrayList<>();
for(int i = 0; i < producerCount; i++) { for(int i = 0; i < producerCount; i++) {
Producer producer = new Producer(dataQueue);
Thread producerThread = new Thread(producer); Thread producerThread = new Thread(producer);
producerThread.start(); producerThread.start();
threads.add(producerThread); threads.add(producerThread);
producers.add(producer);
} }
Consumer consumer = new Consumer(dataQueue);
for(int i = 0; i < consumerCount; i++) { for(int i = 0; i < consumerCount; i++) {
Consumer consumer = new Consumer(dataQueue);
Thread consumerThread = new Thread(consumer); Thread consumerThread = new Thread(consumer);
consumerThread.start(); consumerThread.start();
threads.add(consumerThread); threads.add(consumerThread);
consumers.add(consumer);
} }
// let threads run for two seconds // let threads run for ten seconds
sleep(2000); sleep(10000);
// Stop threads // stop threads
producer.stop(); consumers.forEach(Consumer::stop);
consumer.stop(); producers.forEach(Producer::stop);
waitForAllThreadsToComplete(threads); waitForAllThreadsToComplete(threads);
} }

View File

@ -7,31 +7,37 @@ import java.util.concurrent.Phaser;
class LongRunningAction implements Runnable { class LongRunningAction implements Runnable {
private static Logger log = LoggerFactory.getLogger(LongRunningAction.class); private static final Logger log = LoggerFactory.getLogger(LongRunningAction.class);
private String threadName; private final String threadName;
private Phaser ph; private final Phaser ph;
LongRunningAction(String threadName, Phaser ph) { LongRunningAction(String threadName, Phaser ph) {
this.threadName = threadName; this.threadName = threadName;
this.ph = ph; this.ph = ph;
this.randomWait();
ph.register(); ph.register();
log.info("Thread {} registered during phase {}", threadName, ph.getPhase());
} }
@Override @Override
public void run() { public void run() {
log.info("This is phase {}", ph.getPhase()); log.info("Thread {} BEFORE long running action in phase {}", threadName, ph.getPhase());
log.info("Thread {} before long running action", threadName); ph.arriveAndAwaitAdvance();
randomWait();
log.info("Thread {} AFTER long running action in phase {}", threadName, ph.getPhase());
ph.arriveAndDeregister();
}
// Simulating real work
private void randomWait() {
try { try {
Thread.sleep(2000); Thread.sleep((long) (Math.random() * 100));
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
log.debug("Thread {} action completed and waiting for others", threadName);
ph.arriveAndAwaitAdvance();
log.debug("Thread {} proceeding in phase {}", threadName, ph.getPhase());
ph.arriveAndDeregister();
} }
} }

View File

@ -7,8 +7,6 @@ import org.junit.runners.MethodSorters;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertEquals;
@ -16,38 +14,32 @@ import static junit.framework.TestCase.assertEquals;
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class PhaserUnitTest { public class PhaserUnitTest {
private static Logger log = LoggerFactory.getLogger(PhaserUnitTest.class); private static final Logger log = LoggerFactory.getLogger(PhaserUnitTest.class);
@Test @Test
public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() { public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() throws InterruptedException {
//given
ExecutorService executorService = Executors.newCachedThreadPool();
Phaser ph = new Phaser(1); Phaser ph = new Phaser(1);
assertEquals(0, ph.getPhase()); assertEquals(0, ph.getPhase());
//when new Thread(new LongRunningAction("thread-1", ph)).start();
executorService.submit(new LongRunningAction("thread-1", ph)); new Thread(new LongRunningAction("thread-2", ph)).start();
executorService.submit(new LongRunningAction("thread-2", ph)); new Thread(new LongRunningAction("thread-3", ph)).start();
executorService.submit(new LongRunningAction("thread-3", ph));
//then log.info("Thread {} waiting for others", Thread.currentThread().getName());
log.debug("Thread {} waiting for others", Thread.currentThread().getName());
ph.arriveAndAwaitAdvance(); ph.arriveAndAwaitAdvance();
log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase()); log.info("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
assertEquals(1, ph.getPhase()); assertEquals(1, ph.getPhase());
//and new Thread(new LongRunningAction("thread-4", ph)).start();
executorService.submit(new LongRunningAction("thread-4", ph)); new Thread(new LongRunningAction("thread-5", ph)).start();
executorService.submit(new LongRunningAction("thread-5", ph));
log.debug("Thread {} waiting for others", Thread.currentThread().getName()); log.info("Thread {} waiting for new phase", Thread.currentThread().getName());
ph.arriveAndAwaitAdvance(); ph.arriveAndAwaitAdvance();
log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase()); log.info("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
assertEquals(2, ph.getPhase()); assertEquals(2, ph.getPhase());
ph.arriveAndDeregister(); ph.arriveAndDeregister();
Thread.sleep(1000);
assertEquals(true, ph.isTerminated());
} }
} }

View File

@ -11,4 +11,5 @@ This module contains articles about basic Java concurrency
- [Runnable vs. Callable in Java](https://www.baeldung.com/java-runnable-callable) - [Runnable vs. Callable in Java](https://www.baeldung.com/java-runnable-callable)
- [What Is Thread-Safety and How to Achieve It?](https://www.baeldung.com/java-thread-safety) - [What Is Thread-Safety and How to Achieve It?](https://www.baeldung.com/java-thread-safety)
- [How to Get Notified When a Task Completes in Java Executors](https://www.baeldung.com/java-executors-task-completed-notification) - [How to Get Notified When a Task Completes in Java Executors](https://www.baeldung.com/java-executors-task-completed-notification)
- [Difference Between Future, CompletableFuture, and Rxjavas Observable](https://www.baeldung.com/java-future-completablefuture-rxjavas-observable)
- [[Next -->]](/core-java-modules/core-java-concurrency-basic-2) - [[Next -->]](/core-java-modules/core-java-concurrency-basic-2)

View File

@ -0,0 +1,73 @@
package com.baeldung.hashtableandconcurrenthashmap;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 1)
@Warmup(iterations = 3)
@Measurement(iterations = 5)
@Threads(10) // 10 threads for the test
public class BenchMarkRunner {
private Hashtable<String, Integer> hashTable;
private ConcurrentHashMap<String, Integer> concurrentHashMap;
@Setup(Level.Trial)
public void setup() {
hashTable = new Hashtable<>();
concurrentHashMap = new ConcurrentHashMap<>();
}
@Benchmark
@Group("hashtable")
public void benchmarkHashtablePut() {
for (int i = 0; i < 10000; i++) {
hashTable.put(String.valueOf(i), i);
}
}
@Benchmark
@Group("hashtable")
public void benchmarkHashtableGet(Blackhole blackhole) {
for (int i = 0; i < 10000; i++) {
Integer value = hashTable.get(String.valueOf(i));
blackhole.consume(value);
}
}
@Benchmark
@Group("concurrentHashMap")
public void benchmarkConcurrentHashMapPut() {
for (int i = 0; i < 10000; i++) {
concurrentHashMap.put(String.valueOf(i), i);
}
}
@Benchmark
@Group("concurrentHashMap")
public void benchmarkConcurrentHashMapGet(Blackhole blackhole) {
for (int i = 0; i < 10000; i++) {
Integer value = concurrentHashMap.get(String.valueOf(i));
blackhole.consume(value);
}
}
public static void main(String[] args) throws Exception {
Options options = new OptionsBuilder()
.include(BenchMarkRunner.class.getSimpleName())
.shouldFailOnError(true)
.shouldDoGC(true)
.jvmArgs("-server")
.build();
new Runner(options).run();
}
}

View File

@ -0,0 +1,62 @@
package com.baeldung.hashtableandconcurrenthashmap;
import org.junit.Test;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
public class ConcurrentHashMapUnitTest {
@Test
public void givenEmptyConcurrentHashMap_whenValuesAreAdded_thenValuesCanBeRetrieved() {
ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("Key1", "1");
concurrentHashMap.put("Key2", "2");
concurrentHashMap.putIfAbsent("Key3", "3");
String value = concurrentHashMap.get("Key2");
assertEquals("1", concurrentHashMap.get("Key1"));
assertEquals("2", value);
assertEquals("3", concurrentHashMap.get("Key3"));
}
@Test
public void givenPopulatedConcurrentHashMap_whenModifiedDuringIteration_thenShouldNotThrowConcurrentModificationException() throws InterruptedException {
ConcurrentHashMap<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("Key1", 1);
concurrentHashMap.put("Key2", 2);
concurrentHashMap.put("Key3", 3);
AtomicBoolean exceptionCaught = new AtomicBoolean(false);
Thread iteratorThread = new Thread(() -> {
Iterator<String> it = concurrentHashMap.keySet().iterator();
try {
while (it.hasNext()) {
it.next();
Thread.sleep(100);
}
} catch (ConcurrentModificationException e) {
exceptionCaught.set(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread modifierThread = new Thread(() -> {
try {
Thread.sleep(50);
concurrentHashMap.put("Key4", 4);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
iteratorThread.start();
modifierThread.start();
iteratorThread.join();
modifierThread.join();
assertFalse(exceptionCaught.get());
}
}

View File

@ -0,0 +1,63 @@
package com.baeldung.hashtableandconcurrenthashmap;
import org.junit.Test;
import java.util.ConcurrentModificationException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class HashtableUnitTest {
@Test
public void givenEmptyHashtable_whenValuesAreAdded_thenValuesCanBeRetrieved() {
Hashtable<String, String> hashtable = new Hashtable<>();
hashtable.put("Key1", "1");
hashtable.put("Key2", "2");
hashtable.putIfAbsent("Key3", "3");
String value = hashtable.get("Key2");
assertEquals("1", hashtable.get("Key1"));
assertEquals("2", value);
assertEquals("3", hashtable.get("Key3"));
}
@Test
public void givenPopulatedHashtable_whenModifiedDuringIteration_thenShouldThrowConcurrentModificationException() throws InterruptedException {
Hashtable<String, Integer> hashtable = new Hashtable<>();
hashtable.put("Key1", 1);
hashtable.put("Key2", 2);
hashtable.put("Key3", 3);
AtomicBoolean exceptionCaught = new AtomicBoolean(false);
Thread iteratorThread = new Thread(() -> {
Iterator<String> it = hashtable.keySet().iterator();
try {
while (it.hasNext()) {
it.next();
Thread.sleep(100);
}
} catch (ConcurrentModificationException e) {
exceptionCaught.set(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread modifierThread = new Thread(() -> {
try {
Thread.sleep(50);
hashtable.put("Key4", 4);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
iteratorThread.start();
modifierThread.start();
iteratorThread.join();
modifierThread.join();
assertTrue(exceptionCaught.get());
}
}

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