Merge branch 'eugenp:master' into PR-7091

This commit is contained in:
parthiv39731 2023-11-16 20:28:19 +05:30 committed by GitHub
commit c265dc7041
569 changed files with 8602 additions and 3240 deletions

View File

@ -0,0 +1,129 @@
package com.baeldung.algorithms.connect4;
import java.util.ArrayList;
import java.util.List;
public class GameBoard {
private final List<List<Piece>> columns;
private final int rows;
public GameBoard(int columns, int rows) {
this.rows = rows;
this.columns = new ArrayList<>();
for (int i = 0; i < columns; ++i) {
this.columns.add(new ArrayList<>());
}
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns.size();
}
public Piece getCell(int x, int y) {
assert(x >= 0 && x < getColumns());
assert(y >= 0 && y < getRows());
List<Piece> column = columns.get(x);
if (column.size() > y) {
return column.get(y);
} else {
return null;
}
}
public boolean move(int x, Piece player) {
assert(x >= 0 && x < getColumns());
List<Piece> column = columns.get(x);
if (column.size() >= this.rows) {
throw new IllegalArgumentException("That column is full");
}
column.add(player);
return checkWin(x, column.size() - 1, player);
}
private boolean checkWin(int x, int y, Piece player) {
// Vertical line
if (checkLine(x, y, 0, -1, player)) {
return true;
}
for (int offset = 0; offset < 4; ++offset) {
// Horizontal line
if (checkLine(x - 3 + offset, y, 1, 0, player)) {
return true;
}
// Leading diagonal
if (checkLine(x - 3 + offset, y + 3 - offset, 1, -1, player)) {
return true;
}
// Trailing diagonal
if (checkLine(x - 3 + offset, y - 3 + offset, 1, 1, player)) {
return true;
}
}
return false;
}
private boolean checkLine(int x1, int y1, int xDiff, int yDiff, Piece player) {
for (int i = 0; i < 4; ++i) {
int x = x1 + (xDiff * i);
int y = y1 + (yDiff * i);
if (x < 0 || x > columns.size() - 1) {
return false;
}
if (y < 0 || y > rows - 1) {
return false;
}
if (player != getCell(x, y)) {
return false;
}
}
return true;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (int y = getRows() - 1; y >= 0; --y) {
for (int x = 0; x < getColumns(); ++x) {
Piece piece = getCell(x, y);
result.append("|");
if (piece == null) {
result.append(" ");
} else if (piece == Piece.PLAYER_1) {
result.append("X");
} else if (piece == Piece.PLAYER_2) {
result.append("O");
}
}
result.append("|\n");
for (int i = 0; i < getColumns(); ++i) {
result.append("+-");
}
result.append("+\n");
}
return result.toString();
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.algorithms.connect4;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class GameUnitTest {
@Test
public void blankGame() {
GameBoard gameBoard = new GameBoard(8, 6);
System.out.println(gameBoard);
}
@Test
public void playedGame() {
GameBoard gameBoard = new GameBoard(8, 6);
assertFalse(gameBoard.move(3, Piece.PLAYER_1));
assertFalse(gameBoard.move(2, Piece.PLAYER_2));
assertFalse(gameBoard.move(4, Piece.PLAYER_1));
assertFalse(gameBoard.move(3, Piece.PLAYER_2));
assertFalse(gameBoard.move(5, Piece.PLAYER_1));
assertFalse(gameBoard.move(6, Piece.PLAYER_2));
assertFalse(gameBoard.move(5, Piece.PLAYER_1));
assertFalse(gameBoard.move(4, Piece.PLAYER_2));
assertFalse(gameBoard.move(5, Piece.PLAYER_1));
assertFalse(gameBoard.move(5, Piece.PLAYER_2));
assertFalse(gameBoard.move(6, Piece.PLAYER_1));
assertTrue(gameBoard.move(4, Piece.PLAYER_2));
System.out.println(gameBoard);
}
}

View File

@ -0,0 +1,6 @@
package com.baeldung.algorithms.connect4;
public enum Piece {
PLAYER_1,
PLAYER_2
}

View File

@ -0,0 +1,2 @@
## Relevant Articles
- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game)

View File

@ -1 +0,0 @@
log4j.rootLogger=INFO, stdout

View File

@ -23,11 +23,6 @@
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version> <version>${org.slf4j.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
@ -57,6 +52,11 @@
<version>${lombok.version}</version> <version>${lombok.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind.version} </version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
@ -64,6 +64,7 @@
<kafka.version>2.8.0</kafka.version> <kafka.version>2.8.0</kafka.version>
<testcontainers-kafka.version>1.15.3</testcontainers-kafka.version> <testcontainers-kafka.version>1.15.3</testcontainers-kafka.version>
<testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version> <testcontainers-jupiter.version>1.15.3</testcontainers-jupiter.version>
<jackson.databind.version>2.15.2</jackson.databind.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,11 @@
package com.baeldung.kafka.message.ordering;
public class Config {
public static final String CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS = "value.deserializer.serializedClass";
public static final String MULTI_PARTITION_TOPIC = "multi_partition_topic";
public static final String SINGLE_PARTITION_TOPIC = "single_partition_topic";
public static final int MULTIPLE_PARTITIONS = 5;
public static final int SINGLE_PARTITION = 1;
public static final short REPLICATION_FACTOR = 1;
}

View File

@ -0,0 +1,61 @@
package com.baeldung.kafka.message.ordering.payload;
import java.util.Objects;
public class UserEvent implements Comparable<UserEvent> {
private String userEventId;
private long eventNanoTime;
private long globalSequenceNumber;
@SuppressWarnings("unused")
public UserEvent() {
// Required for Jackson Serialization and Deserialization
}
public UserEvent(String userEventId) {
this.userEventId = userEventId;
}
public String getUserEventId() {
return userEventId;
}
public long getEventNanoTime() {
return eventNanoTime;
}
public void setEventNanoTime(long eventNanoTime) {
this.eventNanoTime = eventNanoTime;
}
public long getGlobalSequenceNumber() {
return globalSequenceNumber;
}
public void setGlobalSequenceNumber(long globalSequenceNumber) {
this.globalSequenceNumber = globalSequenceNumber;
}
@Override
public int compareTo(UserEvent other) {
return Long.compare(this.globalSequenceNumber, other.globalSequenceNumber);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof UserEvent)) {
return false;
}
UserEvent userEvent = (UserEvent) obj;
return this.globalSequenceNumber == userEvent.globalSequenceNumber;
}
@Override
public int hashCode() {
return Objects.hash(globalSequenceNumber);
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.kafka.message.ordering.serialization;
import com.baeldung.kafka.message.ordering.Config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.common.serialization.Deserializer;
import java.util.Map;
/**
* Configured via {@link org.apache.kafka.clients.consumer.ConsumerConfig#VALUE_DESERIALIZER_CLASS_CONFIG}
*/
public class JacksonDeserializer<T> implements Deserializer<T> {
private final ObjectMapper objectMapper = new ObjectMapper();
private Class<T> type;
@Override
public void configure(Map<String, ?> configs, boolean isKey) {
this.type = (Class<T>) configs.get(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS);
}
@Override
public T deserialize(String topic, byte[] bytes) {
if (bytes == null) {
return null;
}
try {
return objectMapper.readValue(bytes, type);
} catch (Exception e) {
throw new RuntimeException("Error deserializing value", e);
}
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.kafka.message.ordering.serialization;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.common.serialization.Serializer;
/**
* Configured via {@link org.apache.kafka.clients.producer.ProducerConfig#VALUE_SERIALIZER_CLASS_CONFIG}
*/
public class JacksonSerializer<T> implements Serializer<T> {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public byte[] serialize(String topic, T data) {
if (data == null) {
return null;
}
try {
return objectMapper.writeValueAsBytes(data);
} catch (Exception e) {
throw new RuntimeException("Error serializing value", e);
}
}
}

View File

@ -0,0 +1,126 @@
package com.baeldung.kafka.message.ordering;
import com.baeldung.kafka.message.ordering.payload.UserEvent;
import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer;
import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer;
import org.apache.kafka.clients.admin.*;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.serialization.LongDeserializer;
import org.apache.kafka.common.serialization.LongSerializer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import com.google.common.collect.ImmutableList;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
@Testcontainers
public class ExternalSequenceWithTimeWindowLiveTest {
private static Admin admin;
private static KafkaProducer<Long, UserEvent> producer;
private static KafkaConsumer<Long, UserEvent> consumer;
private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5);
private static final long BUFFER_PERIOD_NS = Duration.ofSeconds(5)
.toNanos();
private static Logger logger = LoggerFactory.getLogger(ExternalSequenceWithTimeWindowLiveTest.class);
@Container
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
@BeforeAll
static void setup() throws ExecutionException, InterruptedException {
KAFKA_CONTAINER.addExposedPort(9092);
Properties adminProperties = new Properties();
adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class);
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group");
admin = Admin.create(adminProperties);
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR)))
.all()
.get();
}
@AfterAll
static void destroy() {
KAFKA_CONTAINER.stop();
}
@Test
void givenMultiplePartitions_whenPublishedToKafkaAndConsumedWithExtSeqNumberAndTimeWindow_thenCheckForMessageOrder() throws ExecutionException, InterruptedException {
List<UserEvent> sentUserEventList = new ArrayList<>();
List<UserEvent> receivedUserEventList = new ArrayList<>();
for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) {
UserEvent userEvent = new UserEvent(UUID.randomUUID()
.toString());
userEvent.setEventNanoTime(System.nanoTime());
userEvent.setGlobalSequenceNumber(sequenceNumber);
Future<RecordMetadata> future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent));
sentUserEventList.add(userEvent);
RecordMetadata metadata = future.get();
logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition());
}
consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC));
List<UserEvent> buffer = new ArrayList<>();
long lastProcessedTime = System.nanoTime();
ConsumerRecords<Long, UserEvent> records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES);
records.forEach(record -> {
buffer.add(record.value());
});
while (!buffer.isEmpty()) {
if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_NS) {
processBuffer(buffer, receivedUserEventList);
lastProcessedTime = System.nanoTime();
}
records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES);
records.forEach(record -> {
buffer.add(record.value());
});
}
assertThat(receivedUserEventList).isEqualTo(sentUserEventList)
.containsExactlyElementsOf(sentUserEventList);
}
private static void processBuffer(List<UserEvent> buffer, List<UserEvent> receivedUserEventList) {
Collections.sort(buffer);
buffer.forEach(userEvent -> {
receivedUserEventList.add(userEvent);
logger.info("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", User Event Id: " + userEvent.getUserEventId());
});
buffer.clear();
}
}

View File

@ -0,0 +1,105 @@
package com.baeldung.kafka.message.ordering;
import com.baeldung.kafka.message.ordering.payload.UserEvent;
import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer;
import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer;
import org.apache.kafka.clients.admin.*;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.serialization.LongDeserializer;
import org.apache.kafka.common.serialization.LongSerializer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import com.google.common.collect.ImmutableList;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
@Testcontainers
public class MultiplePartitionLiveTest {
private static Admin admin;
private static KafkaProducer<Long, UserEvent> producer;
private static KafkaConsumer<Long, UserEvent> consumer;
private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5);
private static Logger logger = LoggerFactory.getLogger(MultiplePartitionLiveTest.class);
@Container
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
@BeforeAll
static void setup() throws ExecutionException, InterruptedException {
KAFKA_CONTAINER.addExposedPort(9092);
Properties adminProperties = new Properties();
adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class);
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group");
admin = Admin.create(adminProperties);
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR)))
.all()
.get();
}
@AfterAll
static void destroy() {
KAFKA_CONTAINER.stop();
}
@Test
void givenMultiplePartitions_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException {
List<UserEvent> sentUserEventList = new ArrayList<>();
List<UserEvent> receivedUserEventList = new ArrayList<>();
for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) {
UserEvent userEvent = new UserEvent(UUID.randomUUID()
.toString());
userEvent.setGlobalSequenceNumber(sequenceNumber);
userEvent.setEventNanoTime(System.nanoTime());
Future<RecordMetadata> future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent));
sentUserEventList.add(userEvent);
RecordMetadata metadata = future.get();
logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition());
}
consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC));
ConsumerRecords<Long, UserEvent> records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES);
records.forEach(record -> {
UserEvent userEvent = record.value();
receivedUserEventList.add(userEvent);
logger.info("User Event ID: " + userEvent.getUserEventId());
});
assertThat(receivedUserEventList).isNotEqualTo(sentUserEventList)
.containsExactlyInAnyOrderElementsOf(sentUserEventList);
}
}

View File

@ -0,0 +1,109 @@
package com.baeldung.kafka.message.ordering;
import com.baeldung.kafka.message.ordering.payload.UserEvent;
import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer;
import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer;
import org.apache.kafka.clients.admin.Admin;
import org.apache.kafka.clients.admin.AdminClientConfig;
import org.apache.kafka.clients.admin.NewTopic;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.serialization.LongDeserializer;
import org.apache.kafka.common.serialization.LongSerializer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import com.google.common.collect.ImmutableList;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
@Testcontainers
public class SinglePartitionLiveTest {
private static Admin admin;
private static KafkaProducer<Long, UserEvent> producer;
private static KafkaConsumer<Long, UserEvent> consumer;
private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5);
private static Logger logger = LoggerFactory.getLogger(SinglePartitionLiveTest.class);
@Container
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
@BeforeAll
static void setup() throws ExecutionException, InterruptedException {
KAFKA_CONTAINER.addExposedPort(9092);
Properties adminProperties = new Properties();
adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName());
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName());
Properties consumerProperties = new Properties();
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName());
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class);
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group");
admin = Admin.create(adminProperties);
producer = new KafkaProducer<>(producerProperties);
consumer = new KafkaConsumer<>(consumerProperties);
admin.createTopics(ImmutableList.of(new NewTopic(Config.SINGLE_PARTITION_TOPIC, Config.SINGLE_PARTITION, Config.REPLICATION_FACTOR)))
.all()
.get();
}
@AfterAll
static void destroy() {
KAFKA_CONTAINER.stop();
}
@Test
void givenASinglePartition_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException {
List<UserEvent> sentUserEventList = new ArrayList<>();
List<UserEvent> receivedUserEventList = new ArrayList<>();
for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) {
UserEvent userEvent = new UserEvent(UUID.randomUUID()
.toString());
userEvent.setGlobalSequenceNumber(sequenceNumber);
userEvent.setEventNanoTime(System.nanoTime());
ProducerRecord<Long, UserEvent> producerRecord = new ProducerRecord<>(Config.SINGLE_PARTITION_TOPIC, userEvent);
Future<RecordMetadata> future = producer.send(producerRecord);
sentUserEventList.add(userEvent);
RecordMetadata metadata = future.get();
logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition());
}
consumer.subscribe(Collections.singletonList(Config.SINGLE_PARTITION_TOPIC));
ConsumerRecords<Long, UserEvent> records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES);
records.forEach(record -> {
UserEvent userEvent = record.value();
receivedUserEventList.add(userEvent);
logger.info("User Event ID: " + userEvent.getUserEventId());
});
assertThat(receivedUserEventList).isEqualTo(sentUserEventList)
.containsExactlyElementsOf(sentUserEventList);
}
}

View File

@ -0,0 +1,11 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -82,26 +82,11 @@
<artifactId>geronimo-jta_1.0.1B_spec</artifactId> <artifactId>geronimo-jta_1.0.1B_spec</artifactId>
<version>${geronimo.version}</version> <version>${geronimo.version}</version>
</dependency> </dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${validation-api.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.hibernate.validator</groupId> <groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId> <artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version> <version>${hibernate-validator.version}</version>
</dependency> </dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>${javax.el-api.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>${javax.el.version}</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
@ -113,10 +98,7 @@
<derby.version>10.8.1.2</derby.version> <derby.version>10.8.1.2</derby.version>
<jta.version>1.1</jta.version> <jta.version>1.1</jta.version>
<geronimo.version>1.0</geronimo.version> <geronimo.version>1.0</geronimo.version>
<validation-api.version>2.0.1.Final</validation-api.version> <hibernate-validator.version>8.0.1.Final</hibernate-validator.version>
<hibernate-validator.version>6.1.2.Final</hibernate-validator.version>
<javax.el-api.version>3.0.0</javax.el-api.version>
<javax.el.version>2.2.4</javax.el.version>
</properties> </properties>
</project> </project>

View File

@ -3,10 +3,10 @@ package com.baeldung.atomikos.spring.jpa;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import javax.validation.ConstraintViolation; import jakarta.validation.ConstraintViolation;
import javax.validation.Validation; import jakarta.validation.Validation;
import javax.validation.Validator; import jakarta.validation.Validator;
import javax.validation.ValidatorFactory; import jakarta.validation.ValidatorFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;

View File

@ -3,7 +3,7 @@ package com.baeldung.atomikos.spring.jpa.order;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import javax.validation.constraints.Max; import jakarta.validation.constraints.Max;
@Entity @Entity
@Table(name = "ORDERS") @Table(name = "ORDERS")

View File

@ -79,7 +79,7 @@
</build> </build>
<properties> <properties>
<gson.version>2.8.0</gson.version> <gson.version>2.10.1</gson.version>
<dynamodblocal.version>1.21.1</dynamodblocal.version> <dynamodblocal.version>1.21.1</dynamodblocal.version>
<maven-plugins-version>3.1.1</maven-plugins-version> <maven-plugins-version>3.1.1</maven-plugins-version>
</properties> </properties>

View File

@ -73,7 +73,7 @@
</build> </build>
<properties> <properties>
<gson.version>2.8.0</gson.version> <gson.version>2.10.1</gson.version>
<dynamodblocal.version>1.21.1</dynamodblocal.version> <dynamodblocal.version>1.21.1</dynamodblocal.version>
<commons-codec-version>1.10.L001</commons-codec-version> <commons-codec-version>1.10.L001</commons-codec-version>
<jets3t-version>0.9.4.0006L</jets3t-version> <jets3t-version>0.9.4.0006L</jets3t-version>

View File

@ -6,4 +6,5 @@
- [How Many Days Are There in a Particular Month of a Given Year?](https://www.baeldung.com/days-particular-month-given-year) - [How Many Days Are There in a Particular Month of a Given Year?](https://www.baeldung.com/days-particular-month-given-year)
- [Difference Between Instant and LocalDateTime](https://www.baeldung.com/java-instant-vs-localdatetime) - [Difference Between Instant and LocalDateTime](https://www.baeldung.com/java-instant-vs-localdatetime)
- [Add Minutes to a Time String in Java](https://www.baeldung.com/java-string-time-add-mins) - [Add Minutes to a Time String in Java](https://www.baeldung.com/java-string-time-add-mins)
- [Round the Date in Java](https://www.baeldung.com/java-round-the-date)
- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1)

View File

@ -55,7 +55,7 @@
<properties> <properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<joda-time.version>2.10</joda-time.version> <joda-time.version>2.12.5</joda-time.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,18 @@
package com.baeldung.maxdate;
import java.util.Date;
public class DateComparison {
public int compareTodayWithMaxDate() {
Date today = new Date();
Date maxDate = new Date(Long.MAX_VALUE);
int comparisonResult = today.compareTo(maxDate);
return comparisonResult;
}
public static void main(String[] args) {
DateComparison comparator = new DateComparison();
System.out.println(comparator.compareTodayWithMaxDate());
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.maxdate;
import java.util.Date;
import java.text.SimpleDateFormat;
public class MaxDateDisplay {
public String getMaxDateValue() {
Date maxDate = new Date(Long.MAX_VALUE);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
return "The maximum date value in Java is: " + sdf.format(maxDate);
}
public static void main(String[] args) {
MaxDateDisplay display = new MaxDateDisplay();
System.out.println(display.getMaxDateValue());
}
}

View File

@ -7,7 +7,7 @@ import java.util.List;
public class SimpleParseDate { public class SimpleParseDate {
public Date parseDate(String dateString, List<String> formatStrings) { public static Date parseDate(String dateString, List<String> formatStrings) {
for (String formatString : formatStrings) { for (String formatString : formatStrings) {
try { try {
return new SimpleDateFormat(formatString).parse(dateString); return new SimpleDateFormat(formatString).parse(dateString);

View File

@ -0,0 +1,113 @@
package com.baeldung.rounddate;
import java.time.DayOfWeek;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
public class RoundDate {
public static Date getDate(int year, int month, int day, int hour, int minute) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
public static Date roundToDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
public static Date roundToNearestUnit(Date date, int unit) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
switch (unit) {
case Calendar.HOUR:
int minute = calendar.get(Calendar.MINUTE);
if (minute >= 0 && minute < 15) {
calendar.set(Calendar.MINUTE, 0);
} else if (minute >= 15 && minute < 45) {
calendar.set(Calendar.MINUTE, 30);
} else {
calendar.set(Calendar.MINUTE, 0);
calendar.add(Calendar.HOUR_OF_DAY, 1);
}
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
break;
case Calendar.DAY_OF_MONTH:
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour >= 12) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
break;
case Calendar.MONTH:
int day = calendar.get(Calendar.DAY_OF_MONTH);
if (day >= 15) {
calendar.add(Calendar.MONTH, 1);
}
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
break;
}
return calendar.getTime();
}
public static LocalDateTime roundToStartOfMonthUsingLocalDateTime(LocalDateTime dateTime) {
return dateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
}
public static LocalDateTime roundToEndOfWeekUsingLocalDateTime(LocalDateTime dateTime) {
return dateTime.with(TemporalAdjusters.next(DayOfWeek.SATURDAY))
.withHour(23)
.withMinute(59)
.withSecond(59)
.withNano(999);
}
public static ZonedDateTime roundToStartOfMonthUsingZonedDateTime(ZonedDateTime dateTime) {
return dateTime.withDayOfMonth(1)
.withHour(0)
.withMinute(0)
.withSecond(0)
.with(ChronoField.MILLI_OF_SECOND, 0)
.with(ChronoField.MICRO_OF_SECOND, 0)
.with(ChronoField.NANO_OF_SECOND, 0);
}
public static ZonedDateTime roundToEndOfWeekUsingZonedDateTime(ZonedDateTime dateTime) {
return dateTime.with(TemporalAdjusters.next(DayOfWeek.SATURDAY))
.withHour(23)
.withMinute(59)
.withSecond(59)
.with(ChronoField.MILLI_OF_SECOND, 999)
.with(ChronoField.MICRO_OF_SECOND, 999)
.with(ChronoField.NANO_OF_SECOND, 999);
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.maxdate;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
class DateComparisonUnitTest {
@Test
void whenCompareTodayWithMaxDate_thenCorrectResult() {
DateComparison comparator = new DateComparison();
int result = comparator.compareTodayWithMaxDate();
assertTrue(result < 0);
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.maxdate;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class MaxDateDisplayUnitTest {
@Test
void whenGetMaxDate_thenCorrectResult() {
MaxDateDisplay display = new MaxDateDisplay();
String result = display.getMaxDateValue();
assertEquals(
"The maximum date value in Java is: 292278994-08-17 07:12:55.807",
result
);
}
}

View File

@ -1,43 +1,41 @@
package com.baeldung.parsingDates; package com.baeldung.parsingDates;
import com.baeldung.parsingDates.SimpleDateTimeFormat; import static org.junit.jupiter.api.Assertions.assertEquals;
import com.baeldung.parsingDates.SimpleDateTimeFormater; import static org.junit.jupiter.api.Assertions.assertNull;
import com.baeldung.parsingDates.SimpleDateUtils; import static org.junit.jupiter.api.Assertions.assertThrows;
import com.baeldung.parsingDates.SimpleParseDate;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.Arrays; import java.util.Arrays;
import org.junit.*;
import static org.junit.Assert.*;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.junit.jupiter.api.Test;
public class SimpleParseDateUnitTest { class SimpleParseDateUnitTest {
@Test @Test
public void whenInvalidInput_thenGettingUnexpectedResult() { void whenInvalidInput_thenGettingUnexpectedResult() {
SimpleParseDate simpleParseDate = new SimpleParseDate();
String date = "2022-40-40"; String date = "2022-40-40";
assertEquals("Sat May 10 00:00:00 UTC 2025", simpleParseDate.parseDate(date, Arrays.asList("MM/dd/yyyy", "dd.MM.yyyy", "yyyy-MM-dd")).toString()); assertEquals("Sat May 10 00:00:00 UTC 2025", SimpleParseDate.parseDate(date, Arrays.asList("MM/dd/yyyy", "dd.MM.yyyy", "yyyy-MM-dd"))
.toString());
} }
@Test @Test
public void whenInvalidDate_thenAssertThrows() { void whenInvalidDate_thenAssertThrows() {
SimpleDateTimeFormater simpleDateTimeFormater = new SimpleDateTimeFormater(); assertEquals(java.time.LocalDate.parse("2022-12-04"), SimpleDateTimeFormater.parseDate("2022-12-04"));
assertEquals(java.time.LocalDate.parse("2022-12-04"), simpleDateTimeFormater.parseDate("2022-12-04")); assertThrows(DateTimeParseException.class, () -> SimpleDateTimeFormater.parseDate("2022-13-04"));
assertThrows(DateTimeParseException.class, () -> simpleDateTimeFormater.parseDate("2022-13-04"));
} }
@Test @Test
public void whenDateIsCorrect_thenParseCorrect() { void whenDateIsCorrect_thenParseCorrect() {
SimpleDateUtils simpleDateUtils = new SimpleDateUtils(); assertNull(SimpleDateUtils.parseDate("53/10/2014"));
assertNull(simpleDateUtils.parseDate("53/10/2014")); assertEquals("Wed Sep 10 00:00:00 UTC 2014", SimpleDateUtils.parseDate("10/09/2014")
assertEquals("Wed Sep 10 00:00:00 UTC 2014", simpleDateUtils.parseDate("10/09/2014").toString()); .toString());
} }
@Test @Test
public void whenDateIsCorrect_thenResultCorrect() { void whenDateIsCorrect_thenResultCorrect() {
SimpleDateTimeFormat simpleDateTimeFormat = new SimpleDateTimeFormat(); assertNull(SimpleDateTimeFormat.parseDate("53/10/2014"));
assertNull(simpleDateTimeFormat.parseDate("53/10/2014")); assertEquals(LocalDate.parse("2014-10-10"), SimpleDateTimeFormat.parseDate("2014-10-10"));
assertEquals(LocalDate.parse("2014-10-10"), simpleDateTimeFormat.parseDate("2014-10-10"));
} }
} }

View File

@ -0,0 +1,63 @@
package com.baeldung.rounddate;
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import static org.junit.Assert.assertEquals;
public class DateRoundingUnitTest {
@Test
public void givenDate_whenRoundToDay_thenBeginningOfDay() {
Date date = RoundDate.getDate(2023, Calendar.JANUARY, 27, 14, 30);
Date result = RoundDate.roundToDay(date);
assertEquals(RoundDate.getDate(2023, Calendar.JANUARY, 27, 0, 0), result);
}
@Test
public void givenDate_whenRoundToNearestUnit_thenNearestUnit() {
Date date = RoundDate.getDate(2023, Calendar.JANUARY, 27, 14, 12);
Date result = RoundDate.roundToNearestUnit(date, Calendar.DAY_OF_MONTH);
Date expected = RoundDate.getDate(2023, Calendar.JANUARY, 28, 0, 0);
assertEquals(expected, result);
}
@Test
public void givenLocalDateTime_whenRoundToStartOfMonth_thenStartOfMonth() {
LocalDateTime dateTime = LocalDateTime.of(2023, 1, 27, 14, 12);
LocalDateTime result = RoundDate.roundToStartOfMonthUsingLocalDateTime(dateTime);
LocalDateTime expected = LocalDateTime.of(2023, 1, 1, 0, 0, 0);
assertEquals(expected, result);
}
@Test
public void givenZonedDateTime_whenRoundToStartOfMonth_thenStartOfMonth() {
ZonedDateTime dateTime = ZonedDateTime.of(2023, 1, 27, 14, 12, 0, 0, ZoneId.systemDefault());
ZonedDateTime result = RoundDate.roundToStartOfMonthUsingZonedDateTime(dateTime);
ZonedDateTime expected = ZonedDateTime.of(2023, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault());
assertEquals(expected, result);
}
@Test
public void givenLocalDateTime_whenRoundToEndOfWeek_thenEndOfWeek() {
LocalDateTime dateTime = LocalDateTime.of(2023, 1, 27, 14, 12);
LocalDateTime result = RoundDate.roundToEndOfWeekUsingLocalDateTime(dateTime);
LocalDateTime expected = LocalDateTime.of(2023, 1, 28, 23, 59, 59, 999);
assertEquals(expected, result);
}
@Test
public void givenZonedDateTime_whenRoundToEndOfWeek_thenEndOfWeek() {
ZonedDateTime dateTime = ZonedDateTime.of(2023, 1, 27, 14, 12, 0, 0, ZoneId.systemDefault());
ZonedDateTime result = RoundDate.roundToEndOfWeekUsingZonedDateTime(dateTime);
ZonedDateTime expected = ZonedDateTime.of(2023, 1, 28, 23, 59, 59, 999, ZoneId.systemDefault());
assertEquals(expected, result);
}
}

View File

@ -56,7 +56,7 @@
<properties> <properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<joda-time.version>2.10</joda-time.version> <joda-time.version>2.12.5</joda-time.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,48 @@
package com.baeldung.spliterator;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;
public class CustomSpliterator implements Spliterator<Integer> {
private final List<Integer> elements;
private int currentIndex;
public CustomSpliterator(List<Integer> elements) {
this.elements = elements;
this.currentIndex = 0;
}
@Override
public boolean tryAdvance(Consumer<? super Integer> action) {
if (currentIndex < elements.size()) {
action.accept(elements.get(currentIndex));
currentIndex++;
return true;
}
return false;
}
@Override
public Spliterator<Integer> trySplit() {
int currentSize = elements.size() - currentIndex;
if (currentSize < 2) {
return null;
}
int splitIndex = currentIndex + currentSize / 2;
CustomSpliterator newSpliterator = new CustomSpliterator(elements.subList(currentIndex, splitIndex));
currentIndex = splitIndex;
return newSpliterator;
}
@Override
public long estimateSize() {
return elements.size() - currentIndex;
}
@Override
public int characteristics() {
return ORDERED | SIZED | SUBSIZED | NONNULL;
}
}

View File

@ -1,12 +0,0 @@
package com.baeldung.spliterator;
import java.util.stream.Stream;
public class Executor {
public static int countAutors(Stream<Author> stream) {
RelatedAuthorCounter wordCounter = stream.reduce(new RelatedAuthorCounter(0, true),
RelatedAuthorCounter::accumulate, RelatedAuthorCounter::combine);
return wordCounter.getCounter();
}
}

View File

@ -1,27 +0,0 @@
package com.baeldung.spliterator;
public class RelatedAuthorCounter {
private final int counter;
private final boolean isRelated;
public RelatedAuthorCounter(int counter, boolean isRelated) {
this.counter = counter;
this.isRelated = isRelated;
}
public RelatedAuthorCounter accumulate(Author author) {
if (author.getRelatedArticleId() == 0) {
return isRelated ? this : new RelatedAuthorCounter(counter, true);
} else {
return isRelated ? new RelatedAuthorCounter(counter + 1, false) : this;
}
}
public RelatedAuthorCounter combine(RelatedAuthorCounter RelatedAuthorCounter) {
return new RelatedAuthorCounter(counter + RelatedAuthorCounter.counter, RelatedAuthorCounter.isRelated);
}
public int getCounter() {
return counter;
}
}

View File

@ -1,49 +0,0 @@
package com.baeldung.spliterator;
import java.util.List;
import java.util.Spliterator;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
public class RelatedAuthorSpliterator implements Spliterator<Author> {
private final List<Author> list;
AtomicInteger current = new AtomicInteger();
public RelatedAuthorSpliterator(List<Author> list) {
this.list = list;
}
@Override
public boolean tryAdvance(Consumer<? super Author> action) {
action.accept(list.get(current.getAndIncrement()));
return current.get() < list.size();
}
@Override
public Spliterator<Author> trySplit() {
int currentSize = list.size() - current.get();
if (currentSize < 10) {
return null;
}
for (int splitPos = currentSize / 2 + current.intValue(); splitPos < list.size(); splitPos++) {
if (list.get(splitPos).getRelatedArticleId() == 0) {
Spliterator<Author> spliterator = new RelatedAuthorSpliterator(list.subList(current.get(), splitPos));
current.set(splitPos);
return spliterator;
}
}
return null;
}
@Override
public long estimateSize() {
return list.size() - current.get();
}
@Override
public int characteristics() {
return CONCURRENT;
}
}

View File

@ -1,62 +0,0 @@
package com.baeldung.streamreduce.application;
import com.baeldung.streamreduce.entities.User;
import com.baeldung.streamreduce.utilities.NumberUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Application {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
int result1 = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(result1);
int result2 = numbers.stream().reduce(0, Integer::sum);
System.out.println(result2);
List<String> letters = Arrays.asList("a", "b", "c", "d", "e");
String result3 = letters.stream().reduce("", (a, b) -> a + b);
System.out.println(result3);
String result4 = letters.stream().reduce("", String::concat);
System.out.println(result4);
String result5 = letters.stream().reduce("", (a, b) -> a.toUpperCase() + b.toUpperCase());
System.out.println(result5);
List<User> users = Arrays.asList(new User("John", 30), new User("Julie", 35));
int result6 = users.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum);
System.out.println(result6);
String result7 = letters.parallelStream().reduce("", String::concat);
System.out.println(result7);
int result8 = users.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum);
System.out.println(result8);
List<User> userList = new ArrayList<>();
for (int i = 0; i <= 1000000; i++) {
userList.add(new User("John" + i, i));
}
long t1 = System.currentTimeMillis();
int result9 = userList.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum);
long t2 = System.currentTimeMillis();
System.out.println(result9);
System.out.println("Sequential stream time: " + (t2 - t1) + "ms");
long t3 = System.currentTimeMillis();
int result10 = userList.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum);
long t4 = System.currentTimeMillis();
System.out.println(result10);
System.out.println("Parallel stream time: " + (t4 - t3) + "ms");
int result11 = NumberUtils.divideListElements(numbers, 1);
System.out.println(result11);
int result12 = NumberUtils.divideListElementsWithExtractedTryCatchBlock(numbers, 0);
System.out.println(result12);
}
}

View File

@ -1,39 +0,0 @@
package com.baeldung.streamreduce.entities;
import java.util.ArrayList;
import java.util.List;
public class Rating {
double points;
List<Review> reviews = new ArrayList<>();
public Rating() {}
public void add(Review review) {
reviews.add(review);
computeRating();
}
private double computeRating() {
double totalPoints = reviews.stream().map(Review::getPoints).reduce(0, Integer::sum);
this.points = totalPoints / reviews.size();
return this.points;
}
public static Rating average(Rating r1, Rating r2) {
Rating combined = new Rating();
combined.reviews = new ArrayList<>(r1.reviews);
combined.reviews.addAll(r2.reviews);
combined.computeRating();
return combined;
}
public double getPoints() {
return points;
}
public List<Review> getReviews() {
return reviews;
}
}

View File

@ -1,28 +0,0 @@
package com.baeldung.streamreduce.entities;
public class Review {
int points;
String review;
public Review(int points, String review) {
this.points = points;
this.review = review;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
public String getReview() {
return review;
}
public void setReview(String review) {
this.review = review;
}
}

View File

@ -1,30 +0,0 @@
package com.baeldung.streamreduce.entities;
public class User {
private final String name;
private final int age;
private final Rating rating = new Rating();
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Rating getRating() {
return rating;
}
@Override
public String toString() {
return "User{" + "name=" + name + ", age=" + age + '}';
}
}

View File

@ -1,52 +0,0 @@
package com.baeldung.streamreduce.utilities;
import java.util.List;
import java.util.function.BiFunction;
import java.util.logging.Level;
import java.util.logging.Logger;
public abstract class NumberUtils {
private static final Logger LOGGER = Logger.getLogger(NumberUtils.class.getName());
public static int divideListElements(List<Integer> values, Integer divider) {
return values.stream()
.reduce(0, (a, b) -> {
try {
return a / divider + b / divider;
} catch (ArithmeticException e) {
LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero");
}
return 0;
});
}
public static int divideListElementsWithExtractedTryCatchBlock(List<Integer> values, int divider) {
return values.stream().reduce(0, (a, b) -> divide(a, divider) + divide(b, divider));
}
public static int divideListElementsWithApplyFunctionMethod(List<Integer> values, int divider) {
BiFunction<Integer, Integer, Integer> division = (a, b) -> a / b;
return values.stream().reduce(0, (a, b) -> applyFunction(division, a, divider) + applyFunction(division, b, divider));
}
private static int divide(int value, int factor) {
int result = 0;
try {
result = value / factor;
} catch (ArithmeticException e) {
LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero");
}
return result;
}
private static int applyFunction(BiFunction<Integer, Integer, Integer> function, int a, int b) {
try {
return function.apply(a, b);
}
catch(Exception e) {
LOGGER.log(Level.INFO, "Exception occurred!");
}
return 0;
}
}

View File

@ -6,10 +6,10 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Spliterator; import java.util.Spliterator;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -18,22 +18,50 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class ExecutorUnitTest { public class ExecutorUnitTest {
Article article; Article article;
Stream<Author> stream;
Spliterator<Author> spliterator;
@Before @Before
public void init() { public void init() {
article = new Article(Arrays.asList(new Author("Ahmad", 0), new Author("Eugen", 0), new Author("Alice", 1), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), article = new Article(Arrays.asList(new Author("Ahmad", 0), new Author("Eugen", 0), new Author("Alice", 1), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0),
new Author("Alice", 1), new Author("Mike", 0), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Alice", 1), new Author("Mike", 0), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1),
new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0); new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0);
spliterator = new RelatedAuthorSpliterator(article.getListOfAuthors());
} }
@Test @Test
public void givenAstreamOfAuthors_whenProcessedInParallelWithCustomSpliterator_coubtProducessRightOutput() { public void givenAStreamOfIntegers_whenProcessedSequentialCustomSpliterator_countProducesRightOutput() {
Stream<Author> stream2 = StreamSupport.stream(spliterator, true); List<Integer> numbers = new ArrayList<>();
assertThat(Executor.countAutors(stream2.parallel())).isEqualTo(9); numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
CustomSpliterator customSpliterator = new CustomSpliterator(numbers);
AtomicInteger sum = new AtomicInteger();
customSpliterator.forEachRemaining(sum::addAndGet);
assertThat(sum.get()).isEqualTo(15);
}
@Test
public void givenAStreamOfIntegers_whenProcessedInParallelWithCustomSpliterator_countProducesRightOutput() {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
CustomSpliterator customSpliterator = new CustomSpliterator(numbers);
// Create a ForkJoinPool for parallel processing
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
AtomicInteger sum = new AtomicInteger(0);
// Process elements in parallel using parallelStream
forkJoinPool.submit(() -> customSpliterator.forEachRemaining(sum::addAndGet)).join();
assertThat(sum.get()).isEqualTo(15);
} }
@Test @Test
@ -43,9 +71,7 @@ public class ExecutorUnitTest {
.collect(Collectors.toList()); .collect(Collectors.toList());
Spliterator<Article> spliterator = articles.spliterator(); Spliterator<Article> spliterator = articles.spliterator();
while (spliterator.tryAdvance(article -> article.setName(article.getName() while(spliterator.tryAdvance(article -> article.setName(article.getName().concat("- published by Baeldung"))));
.concat("- published by Baeldung"))))
;
articles.forEach(article -> assertThat(article.getName()).isEqualTo("Java- published by Baeldung")); articles.forEach(article -> assertThat(article.getName()).isEqualTo("Java- published by Baeldung"));
} }

View File

@ -57,5 +57,9 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<properties>
<maven.compiler.release>11</maven.compiler.release>
</properties>
</project> </project>

View File

@ -0,0 +1,29 @@
package com.baeldung.arraycompare;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
class ArraysCompareUnitTest {
@Test
void givenSameContents_whenCompare_thenCorrect() {
String[] array1 = new String[] { "A", "B", "C" };
String[] array2 = new String[] { "A", "B", "C" };
assertThat(Arrays.compare(array1, array2)).isEqualTo(0);
}
@Test
void givenDifferentContents_whenCompare_thenDifferent() {
String[] array1 = new String[] { "A", "B", "C" };
String[] array2 = new String[] { "A", "C", "B", "D" };
assertThat(Arrays.compare(array1, array2)).isLessThan(0);
assertThat(Arrays.compare(array2, array1)).isGreaterThan(0);
assertThat(Arrays.compare(array1, null)).isGreaterThan(0);
}
}

View File

@ -8,4 +8,5 @@
- [Difference Between Arrays.sort() and Collections.sort()](https://www.baeldung.com/java-arrays-collections-sort-methods) - [Difference Between Arrays.sort() and Collections.sort()](https://www.baeldung.com/java-arrays-collections-sort-methods)
- [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration)
- [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue) - [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue)
- [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4)

View File

@ -0,0 +1,87 @@
package com.baeldung.vectors;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Vector;
import org.junit.Test;
public class VectorOperationsUnitTest {
private static Vector<String> getVector() {
Vector<String> vector = new Vector<String>();
vector.add("Today");
vector.add("is");
vector.add("a");
vector.add("great");
vector.add("day!");
return vector;
}
@Test
public void givenAVector_whenAddElementsUsingAddMethod_thenElementsGetAddedAtEnd() {
Vector<String> vector = getVector();
vector.add("Hello");
assertEquals(6, vector.size());
}
@Test
public void givenAVector_whenUpdateElementAtIndex_thenElementAtIndexGetsUpdated() {
Vector<String> vector = getVector();
assertEquals(5, vector.size());
assertEquals("great", vector.get(3));
vector.set(3, "good");
assertEquals("good", vector.get(3));
}
@Test
public void givenAVector_whenRemoveAnElement_thenElementGetsRemovedFromTheVector() {
Vector<String> vector = getVector();
assertEquals(5, vector.size());
// remove a specific element
vector.remove("a");
assertEquals(4, vector.size());
// remove at specific index
vector.remove(2);
assertEquals("day!", vector.get(2));
assertEquals(3, vector.size());
assertEquals(false, vector.remove("SomethingThatDoesn'tExist"));
}
@Test(expected = ArrayIndexOutOfBoundsException.class)
public void givenAVector_whenIndexIsBeyondRange_thenRemoveMethodThrowsArrayIndexOutOfBoundsException() {
Vector<String> vector = getVector();
assertEquals(5, vector.size());
vector.remove(10);
}
@Test
public void givenAVector_whenGetElementWithinARange_thenGetMethodGetsAnElementFromTheVector() {
Vector<String> vector = getVector();
String fourthElement = vector.get(3);
assertEquals("great", fourthElement);
}
@Test(expected = ArrayIndexOutOfBoundsException.class)
public void givenAVector_whenGetElementBeyondARange_thenGetMethodThrowsArrayIndexOutOfBoundsException() {
Vector<String> vector = getVector();
assertEquals(5, vector.size());
vector.get(10);
}
@Test
public void givenAVector_whenAddElementFromACollection_thenAllElementsGetAdeddToTheVector() {
Vector<String> vector = getVector();
assertEquals(5, vector.size());
ArrayList<String> words = new ArrayList<>(Arrays.asList("Baeldung", "is", "cool!"));
vector.addAll(words);
assertEquals(8, vector.size());
assertEquals("cool!", vector.get(7));
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.toarraymethod;
import org.junit.Test;
import java.util.HashSet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ConvertingHashSetToArrayUnitTest {
@Test
public void givenStringHashSet_whenConvertedToArray_thenArrayContainsStringElements() {
HashSet<String> stringSet = new HashSet<>();
stringSet.add("Apple");
stringSet.add("Banana");
stringSet.add("Cherry");
// Convert the HashSet of Strings to an array of Strings
String[] stringArray = stringSet.toArray(new String[0]);
// Test that the array is of the correct length
assertEquals(3, stringArray.length);
for (String str : stringArray) {
assertTrue(stringSet.contains(str));
}
}
@Test
public void givenIntegerHashSet_whenConvertedToArray_thenArrayContainsIntegerElements() {
HashSet<Integer> integerSet = new HashSet<>();
integerSet.add(5);
integerSet.add(10);
integerSet.add(15);
// Convert the HashSet of Integers to an array of Integers
Integer[] integerArray = integerSet.toArray(new Integer[0]);
// Test that the array is of the correct length
assertEquals(3, integerArray.length);
for (Integer num : integerArray) {
assertTrue(integerSet.contains(num));
}
assertTrue(integerSet.contains(5));
assertTrue(integerSet.contains(10));
assertTrue(integerSet.contains(15));
}
}

View File

@ -44,6 +44,6 @@
<properties> <properties>
<vavr.version>0.10.3</vavr.version> <vavr.version>0.10.3</vavr.version>
<java.version>11</java.version> <java.version>11</java.version>
<modelmapper.version>3.1.1</modelmapper.version> <modelmapper.version>3.2.0</modelmapper.version>
</properties> </properties>
</project> </project>

View File

@ -1,8 +1,9 @@
package com.baeldung.modelmapper; package com.baeldung.modelmapper;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.modelmapper.ModelMapper; import org.modelmapper.ModelMapper;
import org.modelmapper.TypeMap; import org.modelmapper.TypeMap;
import org.modelmapper.TypeToken; import org.modelmapper.TypeToken;
@ -10,11 +11,10 @@ import org.modelmapper.TypeToken;
import java.util.ArrayList; import java.util.ArrayList;
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.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.hasProperty;
import static org.junit.Assert.assertThat;
/** /**
* This class has test methods of mapping Integer to Character list, * This class has test methods of mapping Integer to Character list,
@ -22,12 +22,12 @@ import static org.junit.Assert.assertThat;
* *
* @author Sasa Milenkovic * @author Sasa Milenkovic
*/ */
public class UsersListMappingUnitTest { class UsersListMappingUnitTest {
private ModelMapper modelMapper; private ModelMapper modelMapper;
private List<User> users; private List<User> users;
@Before @BeforeEach
public void init() { public void init() {
modelMapper = new ModelMapper(); modelMapper = new ModelMapper();
@ -35,18 +35,16 @@ public class UsersListMappingUnitTest {
TypeMap<UserList, UserListDTO> typeMap = modelMapper.createTypeMap(UserList.class, UserListDTO.class); TypeMap<UserList, UserListDTO> typeMap = modelMapper.createTypeMap(UserList.class, UserListDTO.class);
typeMap.addMappings(mapper -> mapper.using(new UsersListConverter()) typeMap.addMappings(mapper -> mapper.using(new UsersListConverter())
.map(UserList::getUsers, UserListDTO::setUsernames)); .map(UserList::getUsers, UserListDTO::setUsernames));
users = new ArrayList(); users = new ArrayList<>();
users.add(new User("b100", "user1", "user1@baeldung.com", "111-222", "USER")); users.add(new User("b100", "user1", "user1@baeldung.com", "111-222", "USER"));
users.add(new User("b101", "user2", "user2@baeldung.com", "111-333", "USER")); users.add(new User("b101", "user2", "user2@baeldung.com", "111-333", "USER"));
users.add(new User("b102", "user3", "user3@baeldung.com", "111-444", "ADMIN")); users.add(new User("b102", "user3", "user3@baeldung.com", "111-444", "ADMIN"));
} }
@Test @Test
public void whenInteger_thenMapToCharacter() { void whenInteger_thenMapToCharacter() {
List<Integer> integers = new ArrayList<Integer>(); List<Integer> integers = new ArrayList<Integer>();
integers.add(1); integers.add(1);
@ -57,36 +55,27 @@ public class UsersListMappingUnitTest {
}.getType()); }.getType());
assertThat(characters, hasItems('1', '2', '3')); assertThat(characters, hasItems('1', '2', '3'));
} }
@Test @Test
public void givenUsersList_whenUseGenericType_thenMapToUserDTO() { void givenUsersList_whenUseGenericType_thenMapToUserDTO() {
// Mapping lists using custom (generic) type mapping // Mapping lists using custom (generic) type mapping
List<UserDTO> userDtoList = MapperUtil.mapList(users, UserDTO.class); List<UserDTO> userDtoList = MapperUtil.mapList(users, UserDTO.class);
assertThat(userDtoList, Matchers.<UserDTO>hasItem( assertThat(userDtoList, Matchers.<UserDTO> hasItem(Matchers.both(hasProperty("userId", equalTo("b100")))
Matchers.both(hasProperty("userId", equalTo("b100"))) .and(hasProperty("email", equalTo("user1@baeldung.com")))
.and(hasProperty("email", equalTo("user1@baeldung.com"))) .and(hasProperty("username", equalTo("user1")))));
.and(hasProperty("username", equalTo("user1")))));
} }
@Test @Test
public void givenUsersList_whenUseConverter_thenMapToUsernames() { void givenUsersList_whenUseConverter_thenMapToUsernames() {
// Mapping lists using property mapping and converter // Mapping lists using property mapping and converter
UserList userList = new UserList(); UserList userList = new UserList();
userList.setUsers(users); userList.setUsers(users);
UserListDTO dtos = new UserListDTO(); UserListDTO dtos = new UserListDTO();
modelMapper.map(userList, dtos); modelMapper.map(userList, dtos);
assertThat(dtos.getUsernames(), hasItems("user1", "user2", "user3")); assertThat(dtos.getUsernames(), hasItems("user1", "user2", "user3"));
} }
} }

View File

@ -1,3 +1,7 @@
## Relevant Articles ## Relevant Articles:
- [Difference Between putIfAbsent() and computeIfAbsent() in Javas Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent) - [Difference Between putIfAbsent() and computeIfAbsent() in Javas Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent)
- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/how-to-write-and-read-a-file-with-a-java-hashmap/)
- [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv) - [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv)
- [How to Get First or Last Entry From a LinkedHashMap in Java](https://www.baeldung.com/java-linkedhashmap-first-last-key-value-pair)
- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/java-hashmap-write-read-file)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-6)

View File

@ -1,11 +1,15 @@
<?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-maps-7</artifactId> <artifactId>core-java-collections-maps-7</artifactId>
<name>core-java-collections-maps-7</name> <name>core-java-collections-maps-7</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties>
<gson.version>2.10.1</gson.version>
<csv.version>1.5</csv.version>
</properties>
<parent> <parent>
<artifactId>core-java-modules</artifactId> <artifactId>core-java-modules</artifactId>
@ -13,71 +17,35 @@
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
</parent> </parent>
<properties>
<spring.version>5.2.5.RELEASE</spring.version>
</properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.12.4</version> <version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.36</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
<version>2.8.9</version> <version>${gson.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20230227</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId> <artifactId>commons-csv</artifactId>
<version>1.5</version> <version>${csv.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens java.base/java.util=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -0,0 +1,51 @@
package com.baeldung.map.readandwritefile;
import java.io.Serializable;
import java.util.Objects;
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String firstName;
private String lastName;
/** Default constructor for JSON serialization */
public Student() {
}
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Student student = (Student) o;
return Objects.equals(firstName, student.firstName) && Objects.equals(lastName, student.lastName);
}
@Override
public int hashCode() {
return super.hashCode();
}
}

View File

@ -0,0 +1,85 @@
package com.baeldung.map.linkedhashmapfirstandlastentry;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class GetFirstAndLastEntryFromLinkedHashMapUnitTest {
private static final LinkedHashMap<String, String> THE_MAP = new LinkedHashMap<>();
static {
THE_MAP.put("key one", "a1 b1 c1");
THE_MAP.put("key two", "a2 b2 c2");
THE_MAP.put("key three", "a3 b3 c3");
THE_MAP.put("key four", "a4 b4 c4");
}
@Test
void whenIteratingEntrySet_thenGetExpectedResult() {
Entry<String, String> firstEntry = THE_MAP.entrySet().iterator().next();
assertEquals("key one", firstEntry.getKey());
assertEquals("a1 b1 c1", firstEntry.getValue());
Entry<String, String> lastEntry = null;
Iterator<Entry<String, String>> it = THE_MAP.entrySet().iterator();
while (it.hasNext()) {
lastEntry = it.next();
}
assertNotNull(lastEntry);
assertEquals("key four", lastEntry.getKey());
assertEquals("a4 b4 c4", lastEntry.getValue());
}
@Test
void whenConvertingEntriesToArray_thenGetExpectedResult() {
Entry<String, String>[] theArray = new Entry[THE_MAP.size()];
THE_MAP.entrySet().toArray(theArray);
Entry<String, String> firstEntry = theArray[0];
assertEquals("key one", firstEntry.getKey());
assertEquals("a1 b1 c1", firstEntry.getValue());
Entry<String, String> lastEntry = theArray[THE_MAP.size() - 1];
assertEquals("key four", lastEntry.getKey());
assertEquals("a4 b4 c4", lastEntry.getValue());
}
@Test
void whenUsingStreamAPI_thenGetExpectedResult() {
Entry<String, String> firstEntry = THE_MAP.entrySet().stream().findFirst().get();
assertEquals("key one", firstEntry.getKey());
assertEquals("a1 b1 c1", firstEntry.getValue());
Entry<String, String> lastEntry = THE_MAP.entrySet().stream().skip(THE_MAP.size() - 1).findFirst().get();
assertNotNull(lastEntry);
assertEquals("key four", lastEntry.getKey());
assertEquals("a4 b4 c4", lastEntry.getValue());
}
@Test
void whenUsingReflection_thenGetExpectedResult() throws NoSuchFieldException, IllegalAccessException {
Field head = THE_MAP.getClass().getDeclaredField("head");
head.setAccessible(true);
Entry<String, String> firstEntry = (Entry<String, String>) head.get(THE_MAP);
assertEquals("key one", firstEntry.getKey());
assertEquals("a1 b1 c1", firstEntry.getValue());
Field tail = THE_MAP.getClass().getDeclaredField("tail");
tail.setAccessible(true);
Entry<String, String> lastEntry = (Entry<String, String>) tail.get(THE_MAP);
assertEquals("key four", lastEntry.getKey());
assertEquals("a4 b4 c4", lastEntry.getValue());
}
}

View File

@ -0,0 +1,135 @@
package com.baeldung.map.readandwritefile;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.junit.After;
import org.junit.Test;
import org.junit.Before;
public class ReadAndWriteFileWithHashMapUnitTest {
private static final Map<Integer, Student> STUDENT_DATA = new HashMap<>();
static {
STUDENT_DATA.put(1234, new Student("Henry", "Winter"));
STUDENT_DATA.put(5678, new Student("Richard", "Papen"));
}
private File file;
@Before
public void createFile() throws IOException {
file = File.createTempFile("student", ".data");
}
@After
public void deleteFile() {
file.delete();
}
@Test
public void givenHashMap_whenWrittenAsPropertiesFile_thenReloadedMapIsIdentical() throws IOException {
// Given a map containing student data
Map<String, String> studentData = new HashMap<>();
studentData.put("student.firstName", "Henry");
studentData.put("student.lastName", "Winter");
// When converting to a Properties object and writing to a file
Properties props = new Properties();
props.putAll(studentData);
try (OutputStream output = Files.newOutputStream(file.toPath())) {
props.store(output, null);
}
// Then the map resulting from loading the Properties file is identical
Properties propsFromFile = new Properties();
try (InputStream input = Files.newInputStream(file.toPath())) {
propsFromFile.load(input);
}
Map<String, String> studentDataFromProps = propsFromFile.stringPropertyNames()
.stream()
.collect(Collectors.toMap(key -> key, props::getProperty));
assertThat(studentDataFromProps).isEqualTo(studentData);
}
@Test
public void givenHashMap_whenSerializedToFile_thenDeserializedMapIsIdentical() throws IOException, ClassNotFoundException {
// Given a map containing student data (STUDENT_DATA)
// When serializing the map to a file
try (FileOutputStream fileOutput = new FileOutputStream(file); ObjectOutputStream objectStream = new ObjectOutputStream(fileOutput)) {
objectStream.writeObject(STUDENT_DATA);
}
// Then read the file back into a map and check the contents
Map<Integer, Student> studentsFromFile;
try (FileInputStream fileReader = new FileInputStream(file); ObjectInputStream objectStream = new ObjectInputStream(fileReader)) {
studentsFromFile = (HashMap<Integer, Student>) objectStream.readObject();
}
assertThat(studentsFromFile).isEqualTo(STUDENT_DATA);
}
@Test
public void givenHashMap_whenSerializedToFileWithJackson_thenDeserializedMapIsIdentical() throws IOException {
// Given a map containing student data (STUDENT_DATA)
// When converting to JSON with Jackson and writing to a file
ObjectMapper mapper = new ObjectMapper();
try (FileOutputStream fileOutput = new FileOutputStream(file)) {
mapper.writeValue(fileOutput, STUDENT_DATA);
}
// Then deserialize the file back into a map and check that it's identical
Map<Integer, Student> mapFromFile;
try (FileInputStream fileInput = new FileInputStream(file)) {
// Create a TypeReference so we can deserialize the parameterized type
TypeReference<HashMap<Integer, Student>> mapType = new TypeReference<HashMap<Integer, Student>>() {
};
mapFromFile = mapper.readValue(fileInput, mapType);
}
assertThat(mapFromFile).isEqualTo(STUDENT_DATA);
}
@Test
public void givenHashMap_whenSerializedToFileWithGson_thenDeserializedMapIsIdentical() throws IOException {
// Given a map containing student data (STUDENT_DATA)
// When converting to JSON using Gson and writing to a file
Gson gson = new Gson();
try (FileWriter writer = new FileWriter(file)) {
gson.toJson(STUDENT_DATA, writer);
}
// Then deserialize the file back into a map and check that it's identical
Map<Integer, Student> studentsFromFile;
try (FileReader reader = new FileReader(file)) {
Type mapType = new TypeToken<HashMap<Integer, Student>>() {
}.getType();
studentsFromFile = gson.fromJson(reader, mapType);
}
assertThat(studentsFromFile).isEqualTo(STUDENT_DATA);
}
}

View File

@ -0,0 +1,126 @@
package com.baeldung.exceptions_completablefuture;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.stream.Stream;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class CompletableFutureExceptionsHandlingUnitTest {
@ParameterizedTest
@MethodSource("parametersSource_handle")
void whenCompletableFutureIsScheduled_thenHandleStageIsAlwaysInvoked(int radius, long expected)
throws ExecutionException, InterruptedException {
long actual = CompletableFuture
.supplyAsync(() -> {
if (radius <= 0) {
throw new IllegalArgumentException("Supplied with non-positive radius '%d'");
}
return Math.round(Math.pow(radius, 2) * Math.PI);
})
.handle((result, ex) -> {
if (ex == null) {
return result;
} else {
return -1L;
}
})
.get();
Assertions.assertThat(actual).isEqualTo(expected);
}
@ParameterizedTest
@MethodSource("parametersSource_exceptionally")
void whenCompletableFutureIsScheduled_thenExceptionallyExecutedOnlyOnFailure(int a, int b, int c, long expected)
throws ExecutionException, InterruptedException {
long actual = CompletableFuture
.supplyAsync(() -> {
if (a <= 0 || b <= 0 || c <= 0) {
throw new IllegalArgumentException(String.format("Supplied with incorrect edge length [%s]", List.of(a, b, c)));
}
return a * b * c;
})
.exceptionally((ex) -> -1)
.get();
Assertions.assertThat(actual).isEqualTo(expected);
}
@ParameterizedTest
@MethodSource("parametersSource_exceptionally")
void givenCompletableFutureIsScheduled_whenHandleIsAlreadyPresent_thenExceptionallyIsNotExecuted(int a, int b, int c, long expected)
throws ExecutionException, InterruptedException {
long actual = CompletableFuture
.supplyAsync(() -> {
if (a <= 0 || b <= 0 || c <= 0) {
throw new IllegalArgumentException(String.format("Supplied with incorrect edge length [%s]", List.of(a, b, c)));
}
return a * b * c;
})
.handle((result, throwable) -> {
if (throwable != null) {
return -1;
}
return result;
})
.exceptionally((ex) -> {
System.exit(1);
return 0;
})
.get();
Assertions.assertThat(actual).isEqualTo(expected);
}
@ParameterizedTest
@MethodSource("parametersSource_whenComplete")
void whenCompletableFutureIsScheduled_thenWhenCompletedExecutedAlways(Double a, long expected, Class<Exception> ifAny) {
try {
CountDownLatch countDownLatch = new CountDownLatch(1);
long actual = CompletableFuture
.supplyAsync(() -> {
if (a.isNaN()) {
throw new IllegalArgumentException("Supplied value is NaN");
}
return Math.round(Math.pow(a, 2));
})
.whenComplete((result, exception) -> countDownLatch.countDown())
.get();
Assertions.assertThat(countDownLatch.await(20L, java.util.concurrent.TimeUnit.SECONDS));
Assertions.assertThat(actual).isEqualTo(expected);
} catch (Exception e) {
Assertions.assertThat(e.getClass()).isSameAs(ExecutionException.class);
Assertions.assertThat(e.getCause().getClass()).isSameAs(ifAny);
}
}
static Stream<Arguments> parametersSource_handle() {
return Stream.of(
Arguments.of(1, 3),
Arguments.of(-1, -1)
);
}
static Stream<Arguments> parametersSource_exceptionally() {
return Stream.of(
Arguments.of(1, 5, 5, 25),
Arguments.of(-1, 10, 15, -1)
);
}
static Stream<Arguments> parametersSource_whenComplete() {
return Stream.of(
Arguments.of(2d, 4, null),
Arguments.of(Double.NaN, 1, IllegalArgumentException.class)
);
}
}

View File

@ -11,4 +11,5 @@ This module contains articles about basic Java concurrency.
- [CompletableFuture and ThreadPool in Java](https://www.baeldung.com/java-completablefuture-threadpool) - [CompletableFuture and ThreadPool in Java](https://www.baeldung.com/java-completablefuture-threadpool)
- [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join) - [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join)
- [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic) - [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic)
- [Convert From List of CompletableFuture to CompletableFuture List](https://www.baeldung.com/java-completablefuture-list-convert)
- [[<-- Prev]](../core-java-concurrency-basic-2) - [[<-- Prev]](../core-java-concurrency-basic-2)

View File

@ -0,0 +1,30 @@
package com.baeldung.concurrent.synchronizestatic.atomicinteger;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Synchronizing static variable with AtomicInteger.
*/
public class Employee {
private static final AtomicInteger count = new AtomicInteger(0);
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
count.incrementAndGet();
}
public static int getCount() {
return count.get();
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.concurrent.synchronizestatic.none;
/**
* No synchronization.
*/
public class Employee {
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
System.out.println("Count = " + ++count);
}
public static Integer getCount() {
return count;
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.concurrent.synchronizestatic.reentrantlock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Synchronizing static variable with a Reenatrant Lock.
*/
public class Employee {
private static final ReentrantLock lock = new ReentrantLock();
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
lock.lock();
try {
System.out.println("Count = " + ++count);
}
finally {
lock.unlock();
}
}
public static int getCount() {
lock.lock();
try {
return count;
}
finally {
lock.unlock();
}
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.concurrent.synchronizestatic.synchronizedblock;
/**
* Synchronizing static variable with a synchronized block.
*/
public class Employee {
private static final Object lock = new Object();
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
synchronized(lock) {
System.out.println("Count = " + ++count);
}
}
public static int getCount() {
synchronized(lock) {
return count;
}
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.concurrent.synchronizestatic.synchronizedclass;
/**
* Synchronizing static variable with a synchronized block.
*/
public class Employee
{
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title) {
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static void incrementCount() {
synchronized(Employee.class) {
System.out.println("Count = " + ++count);
}
}
public static int getCount() {
synchronized(Employee.class) {
return count;
}
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.concurrent.synchronizestatic.synchronizedmethod;
/**
* Synchronizing static variable with a synchronized method.
*/
public class Employee {
static int count;
int id;
String name;
String title;
public Employee(int id, String name, String title)
{
incrementCount();
this.id = id;
this.name = name;
this.title = title;
}
private static synchronized void incrementCount() {
System.out.println("Count = " + ++count);
}
public static synchronized int getCount() {
return count;
}
}

View File

@ -0,0 +1,90 @@
package com.baeldung.concurrent.synchronizestatic;
import org.junit.Test;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* The tests in this class show the output of creating multiple
* types of Employee classes in the <code>synchronizedstatic</code>
* package. When not synchronized the out will not be sequential;
* when it is synchronized the output will be in sequential.
*/
public class SychronizeStaticDataUnitTest {
private final Executor pool = Executors.newFixedThreadPool(4);
private final int numberToTest = 100;
@Test
public void whenNotSynchronized_thenDataOutOfOrder() {
System.out.println("No synchronization");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.none.Employee(finalI, "John", "Smith");
});
}
}
@Test
public void whenSynchronizedMethod_thenDataInOrder() {
System.out.println("Synchronization with synchronized method");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.synchronizedmethod.Employee(finalI, "John", "Smith");
});
}
}
@Test
public void whenSynchronizedClass_thenDataInOrder() {
System.out.println("Synchronization with synchronized block on class");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.synchronizedclass.Employee(finalI, "John", "Smith");
});
}
}
@Test
public void whenSynchronizedBlock_thenDataInOrder() {
System.out.println("Synchronization with synchronized block on a private object");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.synchronizedblock.Employee(finalI, "John", "Smith");
});
}
}
@Test
public void whenAtomicInteger_thenDataInOrder() {
// Not straight forward to test this because we cannot log/print
// and increment values in a synchronized fashion like other
// tests
}
@Test
public void whenReentrantLock_thenDataInOrder() {
System.out.println("Synchronization with ReentrantLock");
for(int i = 0; i < numberToTest; i++) {
int finalI = i;
pool.execute(() -> {
new com.baeldung.concurrent.synchronizestatic.reentrantlock.Employee(finalI, "John", "Smith");
});
}
}
}

View File

@ -12,6 +12,15 @@
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
</parent> </parent>
<dependencies>
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build> <build>
<finalName>core-java-concurrency-simple</finalName> <finalName>core-java-concurrency-simple</finalName>
<resources> <resources>

View File

@ -0,0 +1,182 @@
package com.baeldung.concurrent.completablefuture;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.*;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CompletableFutureTimeoutUnitTest {
private WireMockServer wireMockServer;
private ScheduledExecutorService executorService;
private static final int DEFAULT_TIMEOUT = 1000; //1 seconds
private static final String DEFAULT_PRODUCT = """
{
"products": [
{
"id": 2,
"title": "iPhone X",
"description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...",
"price": 899,
"discountPercentage": 0.0,
"rating": 4.44,
"stock": 34,
"brand": "Apple",
"category": "smartphones"
},
{
"id": 3,
"title": "Samsung Universe 9",
"description": "Samsung's new variant which goes beyond Galaxy to the Universe",
"price": 1249,
"discountPercentage": 0.0,
"rating": 4.09,
"stock": 36,
"brand": "Samsung",
"category": "smartphones"
}
],
"total": 2
}""";
private static final String PRODUCT_OFFERS = """
{
"products": [
{
"id": 1,
"title": "iPhone 9",
"description": "An apple mobile which is nothing like apple",
"price": 549,
"discountPercentage": 12.96,
"rating": 4.69,
"stock": 94,
"brand": "Apple",
"category": "smartphones"
},
{
"id": 2,
"title": "iPhone X",
"description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...",
"price": 899,
"discountPercentage": 17.94,
"rating": 4.44,
"stock": 34,
"brand": "Apple",
"category": "smartphones"
},
{
"id": 3,
"title": "Samsung Universe 9",
"description": "Samsung's new variant which goes beyond Galaxy to the Universe",
"price": 1249,
"discountPercentage": 15.46,
"rating": 4.09,
"stock": 36,
"brand": "Samsung",
"category": "smartphones"
},
{
"id": 4,
"title": "OPPOF19",
"description": "OPPO F19 is officially announced on April 2021.",
"price": 280,
"discountPercentage": 17.91,
"rating": 4.3,
"stock": 123,
"brand": "OPPO",
"category": "smartphones"
},
{
"id": 5,
"title": "Huawei P30",
"description": "Huaweis re-badged P30 Pro New Edition was officially unveiled yesterday in Germany and now the device has made its way to the UK.",
"price": 499,
"discountPercentage": 10.58,
"rating": 4.09,
"stock": 32,
"brand": "Huawei",
"category": "smartphones"
}
],
"total": 5
}""";
@BeforeAll
void setUp() {
wireMockServer = new WireMockServer(8080);
wireMockServer.start();
WireMock.configureFor("localhost", 8080);
stubFor(get(urlEqualTo("/api/dummy"))
.willReturn(aResponse()
.withFixedDelay(5000) // must be > DEFAULT_TIMEOUT for a timeout to occur.
.withBody(PRODUCT_OFFERS)));
executorService = Executors.newScheduledThreadPool(1);
}
@AfterAll
void tearDown() {
executorService.shutdown();
wireMockServer.stop();
}
private CompletableFuture<String> fetchProductData() {
return CompletableFuture.supplyAsync(() -> {
try {
URL url = new URL("http://localhost:8080/api/dummy");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
return response.toString();
} finally {
connection.disconnect();
}
} catch (IOException e) {
return "";
}
});
}
@Test
void whenorTimeout_thenGetThrow() {
CompletableFuture<String> productDataFuture = fetchProductData();
productDataFuture.orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
assertThrows(ExecutionException.class, productDataFuture::get);
}
@Test
void whencompleteOnTimeout_thenReturnValue() throws ExecutionException, InterruptedException {
CompletableFuture<String> productDataFuture = fetchProductData();
productDataFuture.completeOnTimeout(DEFAULT_PRODUCT, DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
assertEquals(DEFAULT_PRODUCT, productDataFuture.get());
}
@Test
void whencompleteExceptionally_thenGetThrow() {
CompletableFuture<String> productDataFuture = fetchProductData();
executorService.schedule(() -> productDataFuture
.completeExceptionally(new TimeoutException("Timeout occurred")), DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
assertThrows(ExecutionException.class, productDataFuture::get);
}
}

View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>core-java-conditionals</artifactId> <artifactId>core-java-conditionals</artifactId>
<version>0.1.0-SNAPSHOT</version> <version>0.1.0-SNAPSHOT</version>
<name>core-java-compiler</name> <name>core-java-conditionals</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<parent> <parent>

View File

@ -29,6 +29,11 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>de.vandermeer</groupId>
<artifactId>asciitable</artifactId>
<version>${ascii.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -157,6 +162,7 @@
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version> <maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<source.version>1.8</source.version> <source.version>1.8</source.version>
<target.version>1.8</target.version> <target.version>1.8</target.version>
<ascii.version>0.3.2</ascii.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,44 @@
package com.baeldung.consoletableoutput;
public class BodyMassIndex {
private String name;
private double height;
private double weight;
public BodyMassIndex(String name, double height, double weight) {
this.name = name;
this.height = height;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public double calculate() {
double bmi = weight / (height * height);
String formattedBmi = String.format("%.2f", bmi);
return Double.parseDouble(formattedBmi);
}
}

View File

@ -0,0 +1,62 @@
package com.baeldung.consoletableoutput;
import java.util.ArrayList;
import java.util.List;
import de.vandermeer.asciitable.AsciiTable;
import de.vandermeer.skb.interfaces.transformers.textformat.TextAlignment;
public class BodyMassIndexApplication {
public static void main(String[] args) {
stringFormat();
asciiTable();
}
public static void stringFormat() {
List<BodyMassIndex> bodyMassIndices = new ArrayList<>();
bodyMassIndices.add(new BodyMassIndex("Tom", 1.8, 80));
bodyMassIndices.add(new BodyMassIndex("Elton", 1.9, 90));
bodyMassIndices.add(new BodyMassIndex("Harry", 1.9, 90));
bodyMassIndices.add(new BodyMassIndex("Hannah", 1.9, 90));
String leftAlignment = "| %-7s | %-7.2f | %-7.2f | %-5.2f |%n";
System.out.format("+---------+---------+---------+-------+%n");
System.out.format("| Name | Height | Weight | BMI |%n");
System.out.format("+---------+---------+---------+-------+%n");
for (BodyMassIndex bodyMassIndex : bodyMassIndices) {
System.out.format(leftAlignment, bodyMassIndex.getName(), bodyMassIndex.getHeight(), bodyMassIndex.getWeight(), bodyMassIndex.calculate());
System.out.format("+---------+---------+---------+-------+%n");
}
}
public static void asciiTable() {
List<BodyMassIndex> bodyMassIndices = new ArrayList<>();
bodyMassIndices.add(new BodyMassIndex("Tom", 1.8, 80));
bodyMassIndices.add(new BodyMassIndex("Elton", 1.9, 90));
bodyMassIndices.add(new BodyMassIndex("Harry", 1.9, 90));
bodyMassIndices.add(new BodyMassIndex("Hannah", 1.9, 90));
AsciiTable asciiTable = new AsciiTable();
asciiTable.addRule();
asciiTable.addRow("Name", "Height", "Weight", "BMI");
asciiTable.addRule();
for (BodyMassIndex bodyMassIndex : bodyMassIndices) {
asciiTable.addRow(bodyMassIndex.getName(), bodyMassIndex.getHeight(), bodyMassIndex.getWeight(), bodyMassIndex.calculate());
asciiTable.addRule();
}
asciiTable.setTextAlignment(TextAlignment.CENTER);
String render = asciiTable.render();
System.out.println(render);
}
}

View File

@ -54,7 +54,7 @@
</build> </build>
<properties> <properties>
<joda-time.version>2.10</joda-time.version> <joda-time.version>2.12.5</joda-time.version>
<hirondelle-date4j.version>RELEASE</hirondelle-date4j.version> <hirondelle-date4j.version>RELEASE</hirondelle-date4j.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>

View File

@ -47,7 +47,7 @@
</dependencies> </dependencies>
<properties> <properties>
<joda-time.version>2.10</joda-time.version> <joda-time.version>2.12.5</joda-time.version>
<hirondelle-date4j.version>1.5.1</hirondelle-date4j.version> <hirondelle-date4j.version>1.5.1</hirondelle-date4j.version>
<prettytime.version>3.2.7.Final</prettytime.version> <prettytime.version>3.2.7.Final</prettytime.version>
<time4j-base.version>5.9</time4j-base.version> <time4j-base.version>5.9</time4j-base.version>

View File

@ -11,4 +11,6 @@ This module contains articles about date operations in Java.
- [Getting Yesterdays Date in Java](https://www.baeldung.com/java-find-yesterdays-date) - [Getting Yesterdays Date in Java](https://www.baeldung.com/java-find-yesterdays-date)
- [How to Get the Start and End Dates of a Year Using Java](https://www.baeldung.com/java-date-year-start-end) - [How to Get the Start and End Dates of a Year Using Java](https://www.baeldung.com/java-date-year-start-end)
- [Convert Between Java LocalDate and Epoch](https://www.baeldung.com/java-localdate-epoch) - [Convert Between Java LocalDate and Epoch](https://www.baeldung.com/java-localdate-epoch)
- [Get First Date of Current Month in Java](https://www.baeldung.com/java-current-month-start-date)
- [Time Conversions Using TimeUnit](https://www.baeldung.com/java-timeunit-conversion)
- [[<-- Prev]](/core-java-modules/core-java-date-operations-2) - [[<-- Prev]](/core-java-modules/core-java-date-operations-2)

View File

@ -0,0 +1,61 @@
package com.baeldung.firstdaymonth;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.junit.jupiter.api.Test;
public class FirstDayOfMonthUnitTest {
@Test
void givenMonth_whenUsingCalendar_thenReturnFirstDay() {
Date currentDate = new GregorianCalendar(2023, Calendar.NOVEMBER, 23).getTime();
Date expectedDate = new GregorianCalendar(2023, Calendar.NOVEMBER, 1).getTime();
Calendar cal = Calendar.getInstance();
cal.setTime(currentDate);
cal.set(Calendar.DAY_OF_MONTH, 1);
assertEquals(expectedDate, cal.getTime());
}
@Test
void givenMonth_whenUsingLocalDate_thenReturnFirstDay() {
LocalDate currentDate = LocalDate.of(2023, 9, 6);
LocalDate expectedDate = LocalDate.of(2023, 9, 1);
assertEquals(expectedDate, currentDate.withDayOfMonth(1));
}
@Test
void givenMonth_whenUsingTemporalAdjusters_thenReturnFirstDay() {
LocalDate currentDate = LocalDate.of(2023, 7, 19);
LocalDate expectedDate = LocalDate.of(2023, 7, 1);
assertEquals(expectedDate, currentDate.with(TemporalAdjusters.firstDayOfMonth()));
}
@Test
void givenMonth_whenUsingYearMonth_thenReturnFirstDay() {
YearMonth currentDate = YearMonth.of(2023, 4);
LocalDate expectedDate = LocalDate.of(2023, 4, 1);
assertEquals(expectedDate, currentDate.atDay(1));
}
@Test
void givenMonth_whenUsingJodaTime_thenReturnFirstDay() {
org.joda.time.LocalDate currentDate = org.joda.time.LocalDate.parse("2023-5-10");
org.joda.time.LocalDate expectedDate = org.joda.time.LocalDate.parse("2023-5-1");
assertEquals(expectedDate, currentDate.dayOfMonth()
.withMinimumValue());
}
}

View File

@ -0,0 +1,105 @@
package com.baeldung.timeunitconversions;
import org.junit.jupiter.api.Test;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
class TimeUnitConversionsUnitTest {
@Test
void givenSeconds_whenConvertToMinutes_thenCorrect() {
int input = 60;
long minutes = TimeUnit.MINUTES.convert(input, TimeUnit.SECONDS);
assertThat(minutes).isEqualTo(1);
}
@Test
void givenMinutes_whenConvertToSeconds_thenCorrect() {
int input = 1;
long seconds = TimeUnit.SECONDS.convert(input, TimeUnit.MINUTES);
assertThat(seconds).isEqualTo(60);
}
@Test
void givenSeconds_whenToMinutes_thenCorrect() {
int input = 60;
long minutes = TimeUnit.SECONDS.toMinutes(input);
assertThat(minutes).isEqualTo(1);
}
@Test
void givenMinutes_whenToSeconds_thenCorrect() {
int input = 1;
long seconds = TimeUnit.MINUTES.toSeconds(input);
assertThat(seconds).isEqualTo(60);
}
@Test
void givenNegativeInput_whenToMinutes_thenCorrect() {
int input = -60;
long minutes = TimeUnit.SECONDS.toMinutes(input);
assertThat(minutes).isEqualTo(-1);
}
@Test
void givenNonTotalInput_whenToMinutes_thenCorrectTotalResultWithDecimalTruncate() {
long positiveUnder = TimeUnit.SECONDS.toMinutes(59);
long positiveAbove = TimeUnit.SECONDS.toMinutes(61);
assertThat(positiveUnder).isEqualTo(0);
assertThat(positiveAbove).isEqualTo(1);
}
@Test
void givenNonTotalNegativeInput_whenToMinutes_thenCorrectTotalResultWithDecimalTruncate() {
long negativeUnder = TimeUnit.SECONDS.toMinutes(-59);
long negativeAbove = TimeUnit.SECONDS.toMinutes(-61);
assertThat(negativeUnder).isEqualTo(0);
assertThat(negativeAbove).isEqualTo(-1);
}
@Test
void givenOverflowInput_whenToMillis_thenTruncatedToLimit() {
long maxMillis = TimeUnit.DAYS.toMillis(Long.MAX_VALUE);
long minMillis = TimeUnit.DAYS.toMillis(Long.MIN_VALUE);
assertThat(maxMillis).isEqualTo(Long.MAX_VALUE);
assertThat(minMillis).isEqualTo(Long.MIN_VALUE);
}
@Test
void givenInput_whenExtractFineTimeUnits_thenCorrect() {
long inputSeconds = 3672;
long hours = TimeUnit.SECONDS.toHours(inputSeconds);
long secondsRemainingAfterHours = inputSeconds - TimeUnit.HOURS.toSeconds(hours);
long minutes = TimeUnit.SECONDS.toMinutes(secondsRemainingAfterHours);
long seconds = secondsRemainingAfterHours - TimeUnit.MINUTES.toSeconds(minutes);
assertThat(hours).isEqualTo(1);
assertThat(minutes).isEqualTo(1);
assertThat(seconds).isEqualTo(12);
assertThat(inputSeconds).isEqualTo(
(hours * 60 * 60) +
(minutes * 60) +
(seconds)
);
}
}

View File

@ -54,7 +54,7 @@
</build> </build>
<properties> <properties>
<joda-time.version>2.10</joda-time.version> <joda-time.version>2.12.5</joda-time.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>
</properties> </properties>

View File

@ -0,0 +1,32 @@
package com.baeldung.timestamptolong;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
public class TimestampToLong {
public void usingSimpleDateFormat() throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
long actualTimestamp = sdf.parse(currentDateString).getTime();
}
public void usingInstantClass() {
Instant instant = Instant.now();
long actualTimestamp = instant.toEpochMilli();
}
public void usingTimestamp() {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
long actualTimestamp = timestamp.getTime();
}
public void usingJava8DateTime() {
LocalDateTime localDateTime = LocalDateTime.now();
long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
}

View File

@ -0,0 +1,52 @@
package com.baeldung.timestamptolong;
import org.junit.Test;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import static org.junit.Assert.assertTrue;
public class TimestampToLongUnitTest {
private static final long TOLERANCE = 1000;
@Test
public void givenSimpleDateFormat_whenFormattingDate_thenTConvertToLong() throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentDateString = sdf.format(new Date());
long actualTimestamp = sdf.parse(currentDateString).getTime();
assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE);
}
@Test
public void givenInstantClass_whenGettingTimestamp_thenTConvertToLong() {
Instant instant = Instant.now();
long actualTimestamp = instant.toEpochMilli();
assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE);
}
@Test
public void givenTimestamp_whenCreatingTimestamp_thenTConvertToLong() {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
long actualTimestamp = timestamp.getTime();
assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE);
}
@Test
public void givenJava8DateTime_whenGettingTimestamp_thenTConvertToLong() {
LocalDateTime localDateTime = LocalDateTime.now();
long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE);
}
}

View File

@ -64,7 +64,7 @@
</build> </build>
<properties> <properties>
<commons-validator.version>1.6</commons-validator.version> <commons-validator.version>1.7</commons-validator.version>
<joda-time.version>2.12.5</joda-time.version> <joda-time.version>2.12.5</joda-time.version>
<hirondelle-date4j.version>RELEASE</hirondelle-date4j.version> <hirondelle-date4j.version>RELEASE</hirondelle-date4j.version>
<maven.compiler.source>1.9</maven.compiler.source> <maven.compiler.source>1.9</maven.compiler.source>

View File

@ -6,6 +6,7 @@ import java.time.Instant;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.UnsupportedTemporalTypeException;
import java.util.TimeZone;
import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormat;
import org.junit.Test; import org.junit.Test;
@ -17,7 +18,7 @@ public class FormatInstantUnitTest {
@Test @Test
public void givenInstant_whenUsingDateTimeFormatter_thenFormat() { public void givenInstant_whenUsingDateTimeFormatter_thenFormat() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT) DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT)
.withZone(ZoneId.systemDefault()); .withZone(TimeZone.getTimeZone("UTC").toZoneId());
Instant instant = Instant.parse("2022-02-15T18:35:24.00Z"); Instant instant = Instant.parse("2022-02-15T18:35:24.00Z");
String formattedInstant = formatter.format(instant); String formattedInstant = formatter.format(instant);

View File

@ -4,3 +4,4 @@
- [Introduction to Javadoc](http://www.baeldung.com/javadoc) - [Introduction to Javadoc](http://www.baeldung.com/javadoc)
- [Code Snippets in Java API Documentation](https://www.baeldung.com/java-doc-code-snippets) - [Code Snippets in Java API Documentation](https://www.baeldung.com/java-doc-code-snippets)
- [How to Document Generic Type Parameters in Javadoc](https://www.baeldung.com/java-javadoc-generic-type-parameters)

View File

@ -0,0 +1,23 @@
package com.baeldung.generictype;
/**
* @param <T> The type of the first value in the {@code Pair<T,S>}.
* @param <S> The type of the second value in the {@code Pair<T,S>}.
*/
public class Pair<T, S> {
public T first;
public S second;
/**
* Constructs a new Pair object with the specified values.
*
* @param a The first value.
* @param b The second value.
*/
public Pair(T a, S b) {
first = a;
second = b;
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.hextoint;
import org.junit.Test;
import java.math.BigInteger;
import static org.junit.Assert.assertEquals;
public class HexToIntConversionUnitTest {
@Test
public void givenValidHexString_whenUsingParseInt_thenExpectCorrectDecimalValue() {
String hexString = "0x00FF00";
int expectedDecimalValue = 65280;
int decimalValue = Integer.parseInt(hexString.substring(2), 16);
assertEquals(expectedDecimalValue, decimalValue);
}
@Test
public void givenValidHexString_whenUsingIntegerDecode_thenExpectCorrectDecimalValue() {
String hexString = "0x00FF00";
int expectedDecimalValue = 65280;
int decimalValue = Integer.decode(hexString);
assertEquals(expectedDecimalValue, decimalValue);
}
@Test
public void givenValidHexString_whenUsingBigInteger_thenExpectCorrectDecimalValue() {
String hexString = "0x00FF00";
int expectedDecimalValue = 65280;
BigInteger bigIntegerValue = new BigInteger(hexString.substring(2), 16);
int decimalValue = bigIntegerValue.intValue();
assertEquals(expectedDecimalValue, decimalValue);
}
}

View File

@ -5,5 +5,6 @@ This module contains articles about core Java input and output (IO)
### Relevant Articles: ### Relevant Articles:
- [Get File Extension From MIME Type in Java](https://www.baeldung.com/java-mime-type-file-extension) - [Get File Extension From MIME Type in Java](https://www.baeldung.com/java-mime-type-file-extension)
- [How to Remove Line Breaks From a File in Java](https://www.baeldung.com/java-file-remove-line-breaks) - [How to Remove Line Breaks From a File in Java](https://www.baeldung.com/java-file-remove-line-breaks)
- [Difference Between ZipFile and ZipInputStream in Java](https://www.baeldung.com/java-zipfile-vs-zipinputstream)
- [[<-- Prev]](/core-java-modules/core-java-io-4) - [[<-- Prev]](/core-java-modules/core-java-io-4)

View File

@ -8,3 +8,4 @@ This module contains articles about core Java input/output(IO) APIs.
- [Check if a File Is Empty in Java](https://www.baeldung.com/java-check-file-empty) - [Check if a File Is Empty in Java](https://www.baeldung.com/java-check-file-empty)
- [Converting Relative to Absolute Paths in Java](https://www.baeldung.com/java-from-relative-to-absolute-paths) - [Converting Relative to Absolute Paths in Java](https://www.baeldung.com/java-from-relative-to-absolute-paths)
- [Detect EOF in Java](https://www.baeldung.com/java-file-detect-end-of-file) - [Detect EOF in Java](https://www.baeldung.com/java-file-detect-end-of-file)
- [PrintWriter vs. FileWriter in Java](https://www.baeldung.com/java-printwriter-filewriter-difference)

View File

@ -56,7 +56,7 @@
<source.version>11</source.version> <source.version>11</source.version>
<target.version>11</target.version> <target.version>11</target.version>
<json.version>20200518</json.version> <json.version>20200518</json.version>
<opencsv.version>4.1</opencsv.version> <opencsv.version>5.8</opencsv.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,63 @@
package com.baeldung.filetofrombytearray;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
class FileToByteArrayUnitTest {
private static final String FILE_NAME = "src" + File.separator + "test" + File.separator + "resources" + File.separator + "sample.txt";
private final byte[] expectedByteArray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 };
@Test
void givenFile_whenUsingFileInputStreamClass_thenConvert() throws IOException {
File myFile = new File(FILE_NAME);
byte[] byteArray = new byte[(int) myFile.length()];
try (FileInputStream inputStream = new FileInputStream(myFile)) {
inputStream.read(byteArray);
}
assertArrayEquals(expectedByteArray, byteArray);
}
@Test
void givenFile_whenUsingNioApiFilesClass_thenConvert() throws IOException {
byte[] byteArray = Files.readAllBytes(Paths.get(FILE_NAME));
assertArrayEquals(expectedByteArray, byteArray);
}
@Test
void givenFile_whenUsingApacheCommonsIOUtilsClass_thenConvert() throws IOException {
File myFile = new File(FILE_NAME);
byte[] byteArray = new byte[(int) myFile.length()];
try (FileInputStream inputStream = new FileInputStream(myFile)) {
byteArray = IOUtils.toByteArray(inputStream);
}
assertArrayEquals(expectedByteArray, byteArray);
}
@Test
void givenFile_whenUsingApacheCommonsFileUtilsClass_thenConvert() throws IOException {
byte[] byteArray = FileUtils.readFileToByteArray(new File(FILE_NAME));
assertArrayEquals(expectedByteArray, byteArray);
}
@Test
void givenFile_whenUsingGuavaFilesClass_thenConvert() throws IOException {
byte[] byteArray = com.google.common.io.Files.toByteArray(new File(FILE_NAME));
assertArrayEquals(expectedByteArray, byteArray);
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.size;
import java.io.File;
public class FileSizeUtils {
public static long getFileSizeInBytes(File file) {
if (file.exists()) {
return file.length();
} else {
throw new IllegalArgumentException("File not found.");
}
}
public static double getFileSizeInKilobytes(File file) {
long bytes = getFileSizeInBytes(file);
return (double) bytes / 1024;
}
public static double getFileSizeInMegabytes(File file) {
double kilobytes = getFileSizeInKilobytes(file);
return kilobytes / 1024;
}
public static double getFileSizeInGigabytes(File file) {
double megabytes = getFileSizeInMegabytes(file);
return megabytes / 1024;
}
}

View File

@ -1,6 +1,8 @@
package com.baeldung.size; package com.baeldung.size;
import static org.junit.Assert.assertEquals; import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -10,9 +12,9 @@ import java.net.URL;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import org.apache.commons.io.FileUtils;
import org.junit.Before; import static org.junit.Assert.assertEquals;
import org.junit.Test; import static org.junit.Assert.fail;
public class JavaFileSizeUnitTest { public class JavaFileSizeUnitTest {
private static final long EXPECTED_FILE_SIZE_IN_BYTES = 11; private static final long EXPECTED_FILE_SIZE_IN_BYTES = 11;
@ -85,4 +87,23 @@ public class JavaFileSizeUnitTest {
assertEquals(EXPECTED_FILE_SIZE_IN_BYTES, stream.available()); assertEquals(EXPECTED_FILE_SIZE_IN_BYTES, stream.available());
} }
} }
}
@Test
public void whenGetFileSizeInDifferentUnits_thenCorrect(){
filePath = String.join(File.separator, new String[] { "src", "test", "resources", "size", "sample_file_1.in" });
File file = new File(filePath);
if (file.exists()) {
long expectedBytes = file.length();
double expectedKilobytes = (double) expectedBytes / 1024;
double expectedMegabytes = expectedKilobytes / 1024;
double expectedGigabytes = expectedMegabytes / 1024;
assertEquals(expectedBytes, FileSizeUtils.getFileSizeInBytes(file));
assertEquals(expectedKilobytes, FileSizeUtils.getFileSizeInKilobytes(file), 0.01);
assertEquals(expectedMegabytes, FileSizeUtils.getFileSizeInMegabytes(file), 0.01);
assertEquals(expectedGigabytes, FileSizeUtils.getFileSizeInGigabytes(file), 0.01);
} else {
fail("File not found.");
}
}
}

View File

@ -4,3 +4,4 @@
- [Java Naming and Directory Interface Overview](https://www.baeldung.com/jndi) - [Java Naming and Directory Interface Overview](https://www.baeldung.com/jndi)
- [LDAP Authentication Using Pure Java](https://www.baeldung.com/java-ldap-auth) - [LDAP Authentication Using Pure Java](https://www.baeldung.com/java-ldap-auth)
- [Testing LDAP Connections With Java](https://www.baeldung.com/java-test-ldap-connections) - [Testing LDAP Connections With Java](https://www.baeldung.com/java-test-ldap-connections)
- [JNDI What Is java:comp/env?](https://www.baeldung.com/java-jndi-comp-env)

View File

@ -0,0 +1,72 @@
package com.baeldung.jndi;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jndi.JndiTemplate;
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
import javax.naming.*;
import javax.sql.DataSource;
import java.util.Enumeration;
import static org.junit.jupiter.api.Assertions.*;
class JndiNamingUnitTest {
private static InitialContext context;
private static DriverManagerDataSource dataSource;
@BeforeAll
static void setUp() throws Exception {
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
dataSource = new DriverManagerDataSource("jdbc:h2:mem:mydb");
builder.activate();
JndiTemplate jndiTemplate = new JndiTemplate();
context = (InitialContext) jndiTemplate.getContext();
dataSource.setDriverClassName("org.h2.Driver");
context.bind("java:comp/env/jdbc/datasource", dataSource);
}
@Test
void givenACompositeName_whenAddingAnElement_thenNameIsAdded() throws Exception {
Name objectName = new CompositeName("java:comp/env/jdbc");
Enumeration<String> items = objectName.getAll();
while(items.hasMoreElements()) {
System.out.println(items.nextElement());
}
objectName.add("New Name");
assertEquals("env", objectName.get(1));
assertEquals("New Name", objectName.get(objectName.size() - 1));
}
@Test
void givenContext_whenLookupByName_thenReturnsValidObject() throws Exception {
DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/datasource");
assertNotNull(ds);
assertNotNull(ds.getConnection());
}
@Test
void givenSubContext_whenLookupByName_thenReturnsValidObject() throws Exception {
Context subContext = (Context) context.lookup("java:comp/env");
DataSource ds = (DataSource) subContext.lookup("jdbc/datasource");
assertNotNull(ds);
assertNotNull(ds.getConnection());
}
@AfterAll
static void tearDown() throws Exception {
context.close();
}
}

View File

@ -29,7 +29,6 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration> <configuration>
<source>17</source> <source>17</source>
<target>17</target> <target>17</target>
@ -50,7 +49,7 @@
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mapstruct.version>1.5.5.Final</mapstruct.version> <mapstruct.version>1.6.0.Beta1</mapstruct.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,58 @@
package com.baeldung.compressbytes;
import java.io.ByteArrayOutputStream;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
public class CompressByteArrayUtil {
public static byte[] compress(byte[] input) {
Deflater deflater = new Deflater();
deflater.setInput(input);
deflater.finish();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while (!deflater.finished()) {
int compressedSize = deflater.deflate(buffer);
outputStream.write(buffer, 0, compressedSize);
}
return outputStream.toByteArray();
}
public static byte[] decompress(byte[] input) throws DataFormatException {
Inflater inflater = new Inflater();
inflater.setInput(input);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while (!inflater.finished()) {
int decompressedSize = inflater.inflate(buffer);
outputStream.write(buffer, 0, decompressedSize);
}
return outputStream.toByteArray();
}
public static void main(String[] args) throws Exception {
String inputString = "Baeldung helps developers explore the Java ecosystem and simply be better engineers. " +
"We publish to-the-point guides and courses, with a strong focus on building web applications, Spring, " +
"Spring Security, and RESTful APIs";
byte[] input = inputString.getBytes();
// Compression
byte[] compressedData = compress(input);
// Decompression
byte[] decompressedData = decompress(compressedData);
System.out.println("Original: " + input.length + " bytes");
System.out.println("Compressed: " + compressedData.length + " bytes");
System.out.println("Decompressed: " + decompressedData.length + " bytes");
}
}

View File

@ -4,9 +4,7 @@ public class InterruptThread extends Thread {
@Override @Override
public void run() { public void run() {
while (!isInterrupted()) { while (!isInterrupted()) {
if (isInterrupted()) { break;
break;
}
// business logic // business logic
} }
} }

View File

@ -0,0 +1,90 @@
package com.baeldung.genericnumberscomparator;
import static org.assertj.core.api.Assertions.entry;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Comparator;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
class GenericNumbersComparatorUnitTest {
public int compareDouble(Number num1, Number num2) {
return Double.compare(num1.doubleValue(), num2.doubleValue());
}
@Test
void givenNumbers_whenUseCompareDouble_thenWillExecuteComparison() {
assertEquals(0, compareDouble(5, 5.0));
}
// we create a method that compares Integer, but this could also be done for other types e.g. Double, BigInteger
public int compareTo(Integer int1, Integer int2) {
return int1.compareTo(int2);
}
@Test
void givenNumbers_whenUseCompareTo_thenWillExecuteComparison() {
assertEquals(-1, compareTo(5, 7));
}
// for this example, we create a function that compares Integer, but this could also be done for other types e.g. Double, BigInteger
Map<Class<? extends Number>, BiFunction<Number, Number, Integer>> comparisonMap = Map.ofEntries(entry(Integer.class, (num1, num2) -> ((Integer) num1).compareTo((Integer) num2)));
public int compareUsingMap(Number num1, Number num2) {
return comparisonMap.get(num1.getClass())
.apply(num1, num2);
}
@Test
void givenNumbers_whenUseCompareUsingMap_thenWillExecuteComparison() {
assertEquals(-1, compareUsingMap(5, 7));
}
public interface NumberComparator {
int compare(Number num1, Number num2);
}
@Test
void givenNumbers_whenUseProxy_thenWillExecuteComparison() {
NumberComparator proxy = (NumberComparator) Proxy.newProxyInstance(NumberComparator.class.getClassLoader(), new Class[] { NumberComparator.class },
(p, method, args) -> Double.compare(((Number) args[0]).doubleValue(), ((Number) args[1]).doubleValue()));
assertEquals(0, proxy.compare(5, 5.0));
}
public int compareUsingReflection(Number num1, Number num2) throws Exception {
Method method = num1.getClass()
.getMethod("compareTo", num1.getClass());
return (int) method.invoke(num1, num2);
}
@Test
void givenNumbers_whenUseCompareUsingReflection_thenWillExecuteComparison() throws Exception {
assertEquals(-1, compareUsingReflection(5, 7));
}
Function<Number, Double> toDouble = Number::doubleValue;
BiPredicate<Number, Number> isEqual = (num1, num2) -> toDouble.apply(num1)
.equals(toDouble.apply(num2));
@Test
void givenNumbers_whenUseIsEqual_thenWillExecuteComparison() {
assertEquals(true, isEqual.test(5, 5.0));
}
private boolean someCondition;
Function<Number, ?> dynamicFunction = someCondition ? Number::doubleValue : Number::intValue;
Comparator<Number> dynamicComparator = (num1, num2) -> ((Comparable) dynamicFunction.apply(num1)).compareTo(dynamicFunction.apply(num2));
@Test
void givenNumbers_whenUseDynamicComparator_thenWillExecuteComparison() {
assertEquals(0, dynamicComparator.compare(5, 5.0));
}
}

View File

@ -3,7 +3,7 @@ package com.baeldung.floatdoubleconversions;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class FloatDoubleConversionsTest { public class FloatDoubleConversionsUnitTest {
@Test @Test
public void whenDoubleType_thenFloatTypeSuccess(){ public void whenDoubleType_thenFloatTypeSuccess(){

View File

@ -47,14 +47,14 @@
<dependency> <dependency>
<groupId>io.rest-assured</groupId> <groupId>io.rest-assured</groupId>
<artifactId>json-path</artifactId> <artifactId>json-path</artifactId>
<version>${rest-assured.version}</version> <version>${json-path.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<properties> <properties>
<hibernate.core.version>5.4.0.Final</hibernate.core.version> <hibernate.core.version>5.4.0.Final</hibernate.core.version>
<rest-assured.version>3.1.1</rest-assured.version> <json-path.version>5.3.2</json-path.version>
</properties> </properties>
</project> </project>

View File

@ -8,88 +8,88 @@ import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
// Uncomment code when code base is compatible with Java 9
//public class Java9OptionalUnitTest { public class Java9OptionalUnitTest {
//
// @Test @Test
// public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() { public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() {
// //given //given
// Optional<String> value = Optional.of("a"); Optional<String> value = Optional.of("a");
//
// //when //when
// List<String> collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); List<String> collect = value.stream().map(String::toUpperCase).collect(Collectors.toList());
//
// //then //then
// assertThat(collect).hasSameElementsAs(List.of("A")); assertThat(collect).hasSameElementsAs(List.of("A"));
// } }
//
// @Test @Test
// public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() { public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() {
// //given //given
// Optional<String> value = Optional.empty(); Optional<String> value = Optional.empty();
//
// //when //when
// List<String> collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); List<String> collect = value.stream().map(String::toUpperCase).collect(Collectors.toList());
//
// //then //then
// assertThat(collect).isEmpty(); assertThat(collect).isEmpty();
// } }
//
// @Test @Test
// public void givenOptional_whenPresent_thenShouldExecuteProperCallback() { public void givenOptional_whenPresent_thenShouldExecuteProperCallback() {
// //given //given
// Optional<String> value = Optional.of("properValue"); Optional<String> value = Optional.of("properValue");
// AtomicInteger successCounter = new AtomicInteger(0); AtomicInteger successCounter = new AtomicInteger(0);
// AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0);
//
// //when //when
// value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet);
//
// //then //then
// assertThat(successCounter.get()).isEqualTo(1); assertThat(successCounter.get()).isEqualTo(1);
// assertThat(onEmptyOptionalCounter.get()).isEqualTo(0); assertThat(onEmptyOptionalCounter.get()).isEqualTo(0);
// } }
//
// @Test @Test
// public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() { public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() {
// //given //given
// Optional<String> value = Optional.empty(); Optional<String> value = Optional.empty();
// AtomicInteger successCounter = new AtomicInteger(0); AtomicInteger successCounter = new AtomicInteger(0);
// AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0);
//
// //when //when
// value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet);
//
// //then //then
// assertThat(successCounter.get()).isEqualTo(0); assertThat(successCounter.get()).isEqualTo(0);
// assertThat(onEmptyOptionalCounter.get()).isEqualTo(1); assertThat(onEmptyOptionalCounter.get()).isEqualTo(1);
// } }
//
// @Test @Test
// public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() { public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() {
// //given //given
// String expected = "properValue"; String expected = "properValue";
// Optional<String> value = Optional.of(expected); Optional<String> value = Optional.of(expected);
// Optional<String> defaultValue = Optional.of("default"); Optional<String> defaultValue = Optional.of("default");
//
// //when //when
// Optional<String> result = value.or(() -> defaultValue); Optional<String> result = value.or(() -> defaultValue);
//
// //then //then
// assertThat(result.get()).isEqualTo(expected); assertThat(result.get()).isEqualTo(expected);
// } }
//
// @Test @Test
// public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() { public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() {
// //given //given
// String defaultString = "default"; String defaultString = "default";
// Optional<String> value = Optional.empty(); Optional<String> value = Optional.empty();
// Optional<String> defaultValue = Optional.of(defaultString); Optional<String> defaultValue = Optional.of(defaultString);
//
// //when //when
// Optional<String> result = value.or(() -> defaultValue); Optional<String> result = value.or(() -> defaultValue);
//
// //then //then
// assertThat(result.get()).isEqualTo(defaultString); assertThat(result.get()).isEqualTo(defaultString);
// } }
//} }

View File

@ -3,8 +3,8 @@
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-os</artifactId> <artifactId>core-java-os-2</artifactId>
<name>core-java-os</name> <name>core-java-os-2</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<parent> <parent>

View File

@ -1,2 +1,3 @@
## Relevant Articles ## Relevant Articles
- [Overriding hashCode() And equals() For Records](https://www.baeldung.com/java-override-hashcode-equals-records) - [Overriding hashCode() And equals() For Records](https://www.baeldung.com/java-override-hashcode-equals-records)
- [Optional as a Record Parameter in Java](https://www.baeldung.com/java-record-optional-param)

View File

@ -0,0 +1,6 @@
package com.baeldung.optionalsasparameterrecords;
import java.util.Optional;
public record Product(String name, double price, Optional<String> description) {
}

View File

@ -0,0 +1,17 @@
package com.baeldung.optionalsasparameterrecords;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Optional;
public class OptionalAsRecordParameterUnitTest {
@Test
public void givenRecordCreationWithOptional_thenCreateItProperly() {
var emptyDescriptionProduct = new Product("television", 1699.99, Optional.empty());
Assertions.assertEquals("television", emptyDescriptionProduct.name());
Assertions.assertEquals(1699.99, emptyDescriptionProduct.price());
Assertions.assertNull(emptyDescriptionProduct.description().orElse(null));
}
}

View File

@ -85,7 +85,7 @@ public class AlphanumericPerformanceBenchmark {
public boolean isAlphanumeric(final int codePoint) { public boolean isAlphanumeric(final int codePoint) {
return (codePoint >= 65 && codePoint <= 90) || return (codePoint >= 65 && codePoint <= 90) ||
(codePoint >= 97 && codePoint <= 172) || (codePoint >= 97 && codePoint <= 122) ||
(codePoint >= 48 && codePoint <= 57); (codePoint >= 48 && codePoint <= 57);
} }
} }

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