Merge branch 'master' into JAVA-6511-p2
This commit is contained in:
commit
40b1bf01dd
|
@ -8,6 +8,9 @@ import java.util.PriorityQueue;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class RouteFinder<T extends GraphNode> {
|
public class RouteFinder<T extends GraphNode> {
|
||||||
private final Graph<T> graph;
|
private final Graph<T> graph;
|
||||||
private final Scorer<T> nextNodeScorer;
|
private final Scorer<T> nextNodeScorer;
|
||||||
|
@ -28,11 +31,11 @@ public class RouteFinder<T extends GraphNode> {
|
||||||
openSet.add(start);
|
openSet.add(start);
|
||||||
|
|
||||||
while (!openSet.isEmpty()) {
|
while (!openSet.isEmpty()) {
|
||||||
System.out.println("Open Set contains: " + openSet.stream().map(RouteNode::getCurrent).collect(Collectors.toSet()));
|
log.debug("Open Set contains: " + openSet.stream().map(RouteNode::getCurrent).collect(Collectors.toSet()));
|
||||||
RouteNode<T> next = openSet.poll();
|
RouteNode<T> next = openSet.poll();
|
||||||
System.out.println("Looking at node: " + next);
|
log.debug("Looking at node: " + next);
|
||||||
if (next.getCurrent().equals(to)) {
|
if (next.getCurrent().equals(to)) {
|
||||||
System.out.println("Found our destination!");
|
log.debug("Found our destination!");
|
||||||
|
|
||||||
List<T> route = new ArrayList<>();
|
List<T> route = new ArrayList<>();
|
||||||
RouteNode<T> current = next;
|
RouteNode<T> current = next;
|
||||||
|
@ -41,7 +44,7 @@ public class RouteFinder<T extends GraphNode> {
|
||||||
current = allNodes.get(current.getPrevious());
|
current = allNodes.get(current.getPrevious());
|
||||||
} while (current != null);
|
} while (current != null);
|
||||||
|
|
||||||
System.out.println("Route: " + route);
|
log.debug("Route: " + route);
|
||||||
return route;
|
return route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +58,7 @@ public class RouteFinder<T extends GraphNode> {
|
||||||
nextNode.setRouteScore(newScore);
|
nextNode.setRouteScore(newScore);
|
||||||
nextNode.setEstimatedScore(newScore + targetScorer.computeCost(connection, to));
|
nextNode.setEstimatedScore(newScore + targetScorer.computeCost(connection, to));
|
||||||
openSet.add(nextNode);
|
openSet.add(nextNode);
|
||||||
System.out.println("Found a better route to node: " + nextNode);
|
log.debug("Found a better route to node: " + nextNode);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.baeldung.algorithms.astar.underground;
|
package com.baeldung.algorithms.astar.underground;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -10,9 +12,13 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.baeldung.algorithms.astar.Graph;
|
import com.baeldung.algorithms.astar.Graph;
|
||||||
import com.baeldung.algorithms.astar.RouteFinder;
|
import com.baeldung.algorithms.astar.RouteFinder;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class RouteFinderIntegrationTest {
|
public class RouteFinderIntegrationTest {
|
||||||
|
|
||||||
private Graph<Station> underground;
|
private Graph<Station> underground;
|
||||||
|
@ -637,7 +643,8 @@ public class RouteFinderIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void findRoute() {
|
public void findRoute() {
|
||||||
List<Station> route = routeFinder.findRoute(underground.getNode("74"), underground.getNode("7"));
|
List<Station> route = routeFinder.findRoute(underground.getNode("74"), underground.getNode("7"));
|
||||||
|
assertThat(route).size().isPositive();
|
||||||
|
|
||||||
System.out.println(route.stream().map(Station::getName).collect(Collectors.toList()));
|
route.stream().map(Station::getName).collect(Collectors.toList()).forEach(station -> log.debug(station));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package com.baeldung.algorithms.prim;
|
package com.baeldung.algorithms.prim;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class PrimUnitTest {
|
public class PrimUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -29,6 +29,7 @@ public class Graph {
|
||||||
stack.push(start);
|
stack.push(start);
|
||||||
while (!stack.isEmpty()) {
|
while (!stack.isEmpty()) {
|
||||||
int current = stack.pop();
|
int current = stack.pop();
|
||||||
|
if(!isVisited[current]){
|
||||||
isVisited[current] = true;
|
isVisited[current] = true;
|
||||||
visit(current);
|
visit(current);
|
||||||
for (int dest : adjVertices.get(current)) {
|
for (int dest : adjVertices.get(current)) {
|
||||||
|
@ -37,6 +38,7 @@ public class Graph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void dfs(int start) {
|
public void dfs(int start) {
|
||||||
boolean[] isVisited = new boolean[adjVertices.size()];
|
boolean[] isVisited = new boolean[adjVertices.size()];
|
||||||
|
|
|
@ -8,7 +8,9 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SuffixTree {
|
public class SuffixTree {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(SuffixTree.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(SuffixTree.class);
|
||||||
|
|
||||||
private static final String WORD_TERMINATION = "$";
|
private static final String WORD_TERMINATION = "$";
|
||||||
private static final int POSITION_UNDEFINED = -1;
|
private static final int POSITION_UNDEFINED = -1;
|
||||||
private Node root;
|
private Node root;
|
||||||
|
@ -23,7 +25,7 @@ public class SuffixTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> searchText(String pattern) {
|
public List<String> searchText(String pattern) {
|
||||||
LOGGER.info("Searching for pattern \"{}\"", pattern);
|
LOGGER.debug("Searching for pattern \"{}\"", pattern);
|
||||||
List<String> result = new ArrayList<>();
|
List<String> result = new ArrayList<>();
|
||||||
List<Node> nodes = getAllNodesInTraversePath(pattern, root, false);
|
List<Node> nodes = getAllNodesInTraversePath(pattern, root, false);
|
||||||
|
|
||||||
|
@ -41,11 +43,11 @@ public class SuffixTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSuffix(String suffix, int position) {
|
private void addSuffix(String suffix, int position) {
|
||||||
LOGGER.info(">>>>>>>>>>>> Adding new suffix {}", suffix);
|
LOGGER.debug(">>>>>>>>>>>> Adding new suffix {}", suffix);
|
||||||
List<Node> nodes = getAllNodesInTraversePath(suffix, root, true);
|
List<Node> nodes = getAllNodesInTraversePath(suffix, root, true);
|
||||||
if (nodes.size() == 0) {
|
if (nodes.size() == 0) {
|
||||||
addChildNode(root, suffix, position);
|
addChildNode(root, suffix, position);
|
||||||
LOGGER.info("{}", printTree());
|
LOGGER.debug("{}", printTree());
|
||||||
} else {
|
} else {
|
||||||
Node lastNode = nodes.remove(nodes.size() - 1);
|
Node lastNode = nodes.remove(nodes.size() - 1);
|
||||||
String newText = suffix;
|
String newText = suffix;
|
||||||
|
@ -58,7 +60,7 @@ public class SuffixTree {
|
||||||
newText = newText.substring(existingSuffixUptoLastNode.length());
|
newText = newText.substring(existingSuffixUptoLastNode.length());
|
||||||
}
|
}
|
||||||
extendNode(lastNode, newText, position);
|
extendNode(lastNode, newText, position);
|
||||||
LOGGER.info("{}", printTree());
|
LOGGER.debug("{}", printTree());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.baeldung.algorithms.dfs;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.baeldung.algorithms.dfs.Graph;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class GraphUnitTest {
|
public class GraphUnitTest {
|
||||||
|
|
|
@ -27,16 +27,16 @@ public class QuadTreeSearchUnitTest {
|
||||||
Point point = new Point(points[i][0], points[i][1]);
|
Point point = new Point(points[i][0], points[i][1]);
|
||||||
quadTree.addPoint(point);
|
quadTree.addPoint(point);
|
||||||
}
|
}
|
||||||
LOGGER.info("\n" + quadTree.printTree(""));
|
LOGGER.debug("\n" + quadTree.printTree(""));
|
||||||
LOGGER.info("==============================================");
|
LOGGER.debug("==============================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenQuadTree_whenSearchingForRange_thenReturn1MatchingItem() {
|
public void givenQuadTree_whenSearchingForRange_thenReturn1MatchingItem() {
|
||||||
Region searchArea = new Region(200, 200, 250, 250);
|
Region searchArea = new Region(200, 200, 250, 250);
|
||||||
List<Point> result = quadTree.search(searchArea, null, "");
|
List<Point> result = quadTree.search(searchArea, null, "");
|
||||||
LOGGER.info(result.toString());
|
LOGGER.debug(result.toString());
|
||||||
LOGGER.info(quadTree.printSearchTraversePath());
|
LOGGER.debug(quadTree.printSearchTraversePath());
|
||||||
|
|
||||||
Assert.assertEquals(1, result.size());
|
Assert.assertEquals(1, result.size());
|
||||||
Assert.assertArrayEquals(new float[] { 245, 238 },
|
Assert.assertArrayEquals(new float[] { 245, 238 },
|
||||||
|
@ -47,8 +47,8 @@ public class QuadTreeSearchUnitTest {
|
||||||
public void givenQuadTree_whenSearchingForRange_thenReturn2MatchingItems() {
|
public void givenQuadTree_whenSearchingForRange_thenReturn2MatchingItems() {
|
||||||
Region searchArea = new Region(0, 0, 100, 100);
|
Region searchArea = new Region(0, 0, 100, 100);
|
||||||
List<Point> result = quadTree.search(searchArea, null, "");
|
List<Point> result = quadTree.search(searchArea, null, "");
|
||||||
LOGGER.info(result.toString());
|
LOGGER.debug(result.toString());
|
||||||
LOGGER.info(quadTree.printSearchTraversePath());
|
LOGGER.debug(quadTree.printSearchTraversePath());
|
||||||
|
|
||||||
Assert.assertEquals(2, result.size());
|
Assert.assertEquals(2, result.size());
|
||||||
Assert.assertArrayEquals(new float[] { 21, 25 },
|
Assert.assertArrayEquals(new float[] { 21, 25 },
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This module contains articles about Apache Kafka.
|
This module contains articles about Apache Kafka.
|
||||||
|
|
||||||
### Relevant articles
|
### Relevant articles
|
||||||
- [Kafka Streams vs Kafka Consumer](https://www.baeldung.com/java-kafka-streams-vs-kafka-consumer)
|
- [Kafka Streams vs. Kafka Consumer](https://www.baeldung.com/java-kafka-streams-vs-kafka-consumer)
|
||||||
- [Kafka Topic Creation Using Java](https://www.baeldung.com/kafka-topic-creation)
|
- [Kafka Topic Creation Using Java](https://www.baeldung.com/kafka-topic-creation)
|
||||||
- [Using Kafka MockConsumer](https://www.baeldung.com/kafka-mockconsumer)
|
- [Using Kafka MockConsumer](https://www.baeldung.com/kafka-mockconsumer)
|
||||||
- [Using Kafka MockProducer](https://www.baeldung.com/kafka-mockproducer)
|
- [Using Kafka MockProducer](https://www.baeldung.com/kafka-mockproducer)
|
||||||
|
@ -12,6 +12,7 @@ This module contains articles about Apache Kafka.
|
||||||
- [Kafka Connect Example with MQTT and MongoDB](https://www.baeldung.com/kafka-connect-mqtt-mongodb)
|
- [Kafka Connect Example with MQTT and MongoDB](https://www.baeldung.com/kafka-connect-mqtt-mongodb)
|
||||||
- [Building a Data Pipeline with Flink and Kafka](https://www.baeldung.com/kafka-flink-data-pipeline)
|
- [Building a Data Pipeline with Flink and Kafka](https://www.baeldung.com/kafka-flink-data-pipeline)
|
||||||
- [Exactly Once Processing in Kafka with Java](https://www.baeldung.com/kafka-exactly-once)
|
- [Exactly Once Processing in Kafka with Java](https://www.baeldung.com/kafka-exactly-once)
|
||||||
|
- [Custom Serializers in Apache Kafka](https://www.baeldung.com/kafka-custom-serializer)
|
||||||
|
|
||||||
|
|
||||||
##### Building the project
|
##### Building the project
|
||||||
|
|
|
@ -161,6 +161,12 @@
|
||||||
<artifactId>spark-cassandra-connector-java_2.11</artifactId>
|
<artifactId>spark-cassandra-connector-java_2.11</artifactId>
|
||||||
<version>${com.datastax.spark.spark-cassandra-connector-java.version}</version>
|
<version>${com.datastax.spark.spark-cassandra-connector-java.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -175,6 +181,7 @@
|
||||||
<graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version>
|
<graphframes.version>0.8.1-spark3.0-s_2.12</graphframes.version>
|
||||||
<com.datastax.spark.spark-cassandra-connector.version>2.5.2</com.datastax.spark.spark-cassandra-connector.version>
|
<com.datastax.spark.spark-cassandra-connector.version>2.5.2</com.datastax.spark.spark-cassandra-connector.version>
|
||||||
<com.datastax.spark.spark-cassandra-connector-java.version>1.6.0-M1</com.datastax.spark.spark-cassandra-connector-java.version>
|
<com.datastax.spark.spark-cassandra-connector-java.version>1.6.0-M1</com.datastax.spark.spark-cassandra-connector-java.version>
|
||||||
|
<lombok.version>1.18.20</lombok.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.kafka.dto;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class MessageDto {
|
||||||
|
private String message;
|
||||||
|
private String version;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.baeldung.kafka.serdes;
|
||||||
|
|
||||||
|
import com.baeldung.kafka.dto.MessageDto;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.apache.kafka.common.errors.SerializationException;
|
||||||
|
import org.apache.kafka.common.serialization.Deserializer;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CustomDeserializer implements Deserializer<MessageDto> {
|
||||||
|
|
||||||
|
private ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Map<String, ?> configs, boolean isKey) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageDto deserialize(String topic, byte[] data) {
|
||||||
|
try {
|
||||||
|
if (data == null){
|
||||||
|
System.out.println("Null received at deserializing");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
System.out.println("Deserializing...");
|
||||||
|
return objectMapper.readValue(new String(data, "UTF-8"), MessageDto.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SerializationException("Error when deserializing byte[] to MessageDto");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.kafka.serdes;
|
||||||
|
|
||||||
|
import com.baeldung.kafka.dto.MessageDto;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.apache.kafka.common.errors.SerializationException;
|
||||||
|
import org.apache.kafka.common.serialization.Serializer;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CustomSerializer implements Serializer<MessageDto> {
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Map<String, ?> configs, boolean isKey) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] serialize(String topic, MessageDto data) {
|
||||||
|
try {
|
||||||
|
if (data == null){
|
||||||
|
System.out.println("Null received at serializing");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
System.out.println("Serializing...");
|
||||||
|
return objectMapper.writeValueAsBytes(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SerializationException("Error when serializing MessageDto to byte[]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.baeldung.kafka.serdes;
|
||||||
|
|
||||||
|
import com.baeldung.kafka.dto.MessageDto;
|
||||||
|
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.junit.Before;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.testcontainers.containers.KafkaContainer;
|
||||||
|
import org.testcontainers.utility.DockerImageName;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class KafkaSerDesLiveTest {
|
||||||
|
private static final String CONSUMER_APP_ID = "consumer_id";
|
||||||
|
private static final String CONSUMER_GROUP_ID = "group_id";
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:5.4.3"));
|
||||||
|
private final String TOPIC = "mytopic";
|
||||||
|
|
||||||
|
private static KafkaConsumer<String, MessageDto> createKafkaConsumer() {
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers());
|
||||||
|
props.put(ConsumerConfig.CLIENT_ID_CONFIG, CONSUMER_APP_ID);
|
||||||
|
props.put(ConsumerConfig.GROUP_ID_CONFIG, CONSUMER_GROUP_ID);
|
||||||
|
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||||
|
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
|
||||||
|
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.serdes.CustomDeserializer");
|
||||||
|
|
||||||
|
return new KafkaConsumer<>(props);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static KafkaProducer<String, MessageDto> createKafkaProducer() {
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers());
|
||||||
|
props.put(ProducerConfig.CLIENT_ID_CONFIG, CONSUMER_APP_ID);
|
||||||
|
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
|
||||||
|
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.serdes.CustomSerializer");
|
||||||
|
|
||||||
|
return new KafkaProducer(props);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenKafkaClientShouldSerializeAndDeserialize() throws InterruptedException {
|
||||||
|
|
||||||
|
MessageDto msgProd = MessageDto.builder().message("test").version("1.0").build();
|
||||||
|
|
||||||
|
KafkaProducer<String, MessageDto> producer = createKafkaProducer();
|
||||||
|
producer.send(new ProducerRecord<String, MessageDto>(TOPIC, "1", msgProd));
|
||||||
|
System.out.println("Message sent " + msgProd);
|
||||||
|
producer.close();
|
||||||
|
|
||||||
|
Thread.sleep(2000);
|
||||||
|
|
||||||
|
AtomicReference<MessageDto> msgCons = new AtomicReference<>();
|
||||||
|
|
||||||
|
KafkaConsumer<String, MessageDto> consumer = createKafkaConsumer();
|
||||||
|
consumer.subscribe(Arrays.asList(TOPIC));
|
||||||
|
|
||||||
|
ConsumerRecords<String, MessageDto> records = consumer.poll(Duration.ofSeconds(1));
|
||||||
|
records.forEach(record -> {
|
||||||
|
msgCons.set(record.value());
|
||||||
|
System.out.println("Message received " + record.value());
|
||||||
|
});
|
||||||
|
|
||||||
|
consumer.close();
|
||||||
|
|
||||||
|
assertEquals(msgProd, msgCons.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,11 @@
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>${jackson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-annotations</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jayway.awaitility</groupId>
|
<groupId>com.jayway.awaitility</groupId>
|
||||||
<artifactId>awaitility</artifactId>
|
<artifactId>awaitility</artifactId>
|
||||||
|
@ -196,7 +201,6 @@
|
||||||
<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>
|
||||||
<avro.version>1.8.2</avro.version>
|
<avro.version>1.8.2</avro.version>
|
||||||
<slf4j.version>1.7.25</slf4j.version>
|
|
||||||
<beam.version>2.19.0</beam.version>
|
<beam.version>2.19.0</beam.version>
|
||||||
<assertj.version>3.9.0</assertj.version>
|
<assertj.version>3.9.0</assertj.version>
|
||||||
<bval.version>1.1.2</bval.version>
|
<bval.version>1.1.2</bval.version>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<Configuration status="WARN">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||||
|
</Console>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Logger name="org.apache.meecrowave" level="warn">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
</Logger>
|
||||||
|
|
||||||
|
<Root level="info">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,6 @@ import com.baeldung.apache.beam.intro.WordCount;
|
||||||
public class WordCountUnitTest {
|
public class WordCountUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
// @Ignore
|
|
||||||
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
|
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
|
||||||
boolean jobDone = WordCount.wordCount("src/test/resources/wordcount.txt", "target/output");
|
boolean jobDone = WordCount.wordCount("src/test/resources/wordcount.txt", "target/output");
|
||||||
assertTrue(jobDone);
|
assertTrue(jobDone);
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
# contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# this work for additional information regarding copyright ownership.
|
||||||
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
# (the "License"); you may not use this file except in compliance with
|
||||||
|
# the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Set everything to be logged to the console
|
||||||
|
log4j.rootCategory=WARN, console
|
||||||
|
log4j.appender.console=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.console.target=System.err
|
||||||
|
log4j.appender.console.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n
|
||||||
|
|
||||||
|
# Set the default spark-shell log level to WARN. When running the spark-shell, the
|
||||||
|
# log level for this class is used to overwrite the root logger's log level, so that
|
||||||
|
# the user can have different defaults for the shell and regular Spark apps.
|
||||||
|
log4j.logger.org.apache.spark.repl.Main=WARN
|
||||||
|
|
||||||
|
# Settings to quiet third party logs that are too verbose
|
||||||
|
log4j.logger.org.spark_project.jetty=WARN
|
||||||
|
log4j.logger.org.spark_project.jetty.util.component.AbstractLifeCycle=ERROR
|
||||||
|
log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO
|
||||||
|
log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO
|
||||||
|
|
||||||
|
# SPARK-9183: Settings to avoid annoying messages when looking up nonexistent UDFs in SparkSQL with Hive support
|
||||||
|
log4j.logger.org.apache.hadoop.hive.metastore.RetryingHMSHandler=FATAL
|
||||||
|
log4j.logger.org.apache.hadoop.hive.ql.exec.FunctionRegistry=ERROR
|
||||||
|
|
||||||
|
# Parquet related logging
|
||||||
|
log4j.logger.org.apache.parquet.CorruptStatistics=ERROR
|
||||||
|
log4j.logger.parquet.CorruptStatistics=ERROR
|
|
@ -32,7 +32,6 @@
|
||||||
<!-- Uncomment this to add support for file uploads: -->
|
<!-- Uncomment this to add support for file uploads: -->
|
||||||
<!-- <dependency> <groupId>org.apache.tapestry</groupId> <artifactId>tapestry-upload</artifactId>
|
<!-- <dependency> <groupId>org.apache.tapestry</groupId> <artifactId>tapestry-upload</artifactId>
|
||||||
<version>${tapestry-release-version}</version> </dependency> -->
|
<version>${tapestry-release-version}</version> </dependency> -->
|
||||||
|
|
||||||
<!-- A dependency on either JUnit or TestNG is required, or the surefire plugin (which runs the
|
<!-- A dependency on either JUnit or TestNG is required, or the surefire plugin (which runs the
|
||||||
tests) will fail, preventing Maven from packaging the WAR. Tapestry includes a large number of testing
|
tests) will fail, preventing Maven from packaging the WAR. Tapestry includes a large number of testing
|
||||||
facilities designed for use with TestNG (http://testng.org/), so it's recommended. -->
|
facilities designed for use with TestNG (http://testng.org/), so it's recommended. -->
|
||||||
|
@ -110,8 +109,6 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<reporting />
|
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>jboss</id>
|
<id>jboss</id>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-simple</artifactId>
|
<artifactId>slf4j-simple</artifactId>
|
||||||
<version>${org.slf4j.slf4j-simple.version}</version>
|
<version>${org.slf4j.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -61,7 +61,6 @@
|
||||||
<properties>
|
<properties>
|
||||||
<thrift.version>0.10.0</thrift.version>
|
<thrift.version>0.10.0</thrift.version>
|
||||||
<maven-thrift.version>0.1.11</maven-thrift.version>
|
<maven-thrift.version>0.1.11</maven-thrift.version>
|
||||||
<org.slf4j.slf4j-simple.version>1.7.12</org.slf4j.slf4j-simple.version>
|
|
||||||
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
|
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ This module contains articles about Amazon Web Services (AWS)
|
||||||
|
|
||||||
- [AWS Lambda Using DynamoDB With Java](https://www.baeldung.com/aws-lambda-dynamodb-java)
|
- [AWS Lambda Using DynamoDB With Java](https://www.baeldung.com/aws-lambda-dynamodb-java)
|
||||||
- [AWS S3 with Java](https://www.baeldung.com/aws-s3-java)
|
- [AWS S3 with Java](https://www.baeldung.com/aws-s3-java)
|
||||||
- [AWS Lambda With Java](https://www.baeldung.com/java-aws-lambda)
|
- [A Basic AWS Lambda Example With Java](https://www.baeldung.com/java-aws-lambda)
|
||||||
- [Managing EC2 Instances in Java](https://www.baeldung.com/ec2-java)
|
- [Managing EC2 Instances in Java](https://www.baeldung.com/ec2-java)
|
||||||
- [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload)
|
- [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload)
|
||||||
- [Integration Testing with a Local DynamoDB Instance](https://www.baeldung.com/dynamodb-local-integration-tests)
|
- [Integration Testing with a Local DynamoDB Instance](https://www.baeldung.com/dynamodb-local-integration-tests)
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.axon;
|
||||||
|
|
||||||
|
import org.axonframework.eventsourcing.EventCountSnapshotTriggerDefinition;
|
||||||
|
import org.axonframework.eventsourcing.SnapshotTriggerDefinition;
|
||||||
|
import org.axonframework.eventsourcing.Snapshotter;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class OrderApplicationConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SnapshotTriggerDefinition orderAggregateSnapshotTriggerDefinition(Snapshotter snapshotter,
|
||||||
|
@Value("${axon.aggregate.order.snapshot-threshold:250}") int threshold) {
|
||||||
|
return new EventCountSnapshotTriggerDefinition(snapshotter, threshold);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
|
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
|
||||||
|
|
||||||
@Aggregate
|
@Aggregate(snapshotTriggerDefinition = "orderAggregateSnapshotTriggerDefinition")
|
||||||
public class OrderAggregate {
|
public class OrderAggregate {
|
||||||
|
|
||||||
@AggregateIdentifier
|
@AggregateIdentifier
|
||||||
|
|
|
@ -166,7 +166,6 @@
|
||||||
<hsqldb.version>2.4.0</hsqldb.version>
|
<hsqldb.version>2.4.0</hsqldb.version>
|
||||||
<spock-core.version>1.1-groovy-2.4</spock-core.version>
|
<spock-core.version>1.1-groovy-2.4</spock-core.version>
|
||||||
<groovy-wslite.version>1.1.3</groovy-wslite.version>
|
<groovy-wslite.version>1.1.3</groovy-wslite.version>
|
||||||
<logback.version>1.2.3</logback.version>
|
|
||||||
<groovy.version>2.5.7</groovy.version>
|
<groovy.version>2.5.7</groovy.version>
|
||||||
<assembly.plugin.version>3.1.0</assembly.plugin.version>
|
<assembly.plugin.version>3.1.0</assembly.plugin.version>
|
||||||
<compiler.plugin.version>3.8.0</compiler.plugin.version>
|
<compiler.plugin.version>3.8.0</compiler.plugin.version>
|
||||||
|
|
|
@ -8,3 +8,4 @@ This module contains articles about Java 11 core features
|
||||||
- [Guide to Java 8’s Collectors](https://www.baeldung.com/java-8-collectors)
|
- [Guide to Java 8’s Collectors](https://www.baeldung.com/java-8-collectors)
|
||||||
- [New Features in Java 11](https://www.baeldung.com/java-11-new-features)
|
- [New Features in Java 11](https://www.baeldung.com/java-11-new-features)
|
||||||
- [Getting the Java Version at Runtime](https://www.baeldung.com/get-java-version-runtime)
|
- [Getting the Java Version at Runtime](https://www.baeldung.com/get-java-version-runtime)
|
||||||
|
- [Invoking a SOAP Web Service in Java](https://www.baeldung.com/java-soap-web-service)
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)
|
- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)
|
||||||
- [New Features in Java 12](https://www.baeldung.com/java-12-new-features)
|
- [New Features in Java 12](https://www.baeldung.com/java-12-new-features)
|
||||||
|
- [Compare the Content of Two Files in Java](https://www.baeldung.com/java-compare-files)
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
|
|
||||||
- [Collect a Java Stream to an Immutable Collection](https://www.baeldung.com/java-stream-immutable-collection)
|
- [Collect a Java Stream to an Immutable Collection](https://www.baeldung.com/java-stream-immutable-collection)
|
||||||
|
- [Guide to mapMulti in Stream API](https://www.baeldung.com/java-mapmulti)
|
||||||
|
- [Collecting Stream Elements into a List in Java](https://www.baeldung.com/java-stream-to-list-collecting)
|
||||||
|
- [New Features in Java 16](https://www.baeldung.com/java-16-new-features)
|
||||||
|
- [Guide to Java 8 groupingBy Collector](https://www.baeldung.com/java-groupingby-collector)
|
||||||
|
|
|
@ -28,6 +28,18 @@
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.12.0</version>
|
<version>3.12.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit-jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>${junit-jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -37,17 +49,38 @@
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>${maven-compiler-plugin.version}</version>
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<release>${maven.compiler.release}</release>
|
||||||
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
<source>${maven.compiler.source.version}</source>
|
<source>${maven.compiler.source.version}</source>
|
||||||
<target>${maven.compiler.target.version}</target>
|
<target>${maven.compiler.target.version}</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${surefire.plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<argLine>--enable-preview</argLine>
|
||||||
|
<forkCount>1</forkCount>
|
||||||
|
</configuration>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven.surefire</groupId>
|
||||||
|
<artifactId>surefire-api</artifactId>
|
||||||
|
<version>${surefire.plugin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source.version>16</maven.compiler.source.version>
|
<maven.compiler.source.version>16</maven.compiler.source.version>
|
||||||
<maven.compiler.target.version>16</maven.compiler.target.version>
|
<maven.compiler.target.version>16</maven.compiler.target.version>
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<maven.compiler.release>16</maven.compiler.release>
|
||||||
|
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||||
|
<surefire.plugin.version>3.0.0-M5</surefire.plugin.version>
|
||||||
|
<assertj.version>3.17.2</assertj.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
interface HelloWorld {
|
||||||
|
default String hello() {
|
||||||
|
return "world";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
import com.baeldung.features.record.Book;
|
||||||
|
|
||||||
|
public class OuterClass {
|
||||||
|
class InnerClass {
|
||||||
|
Book book = new Book("Title", "author", "isbn");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
import jdk.incubator.vector.IntVector;
|
||||||
|
|
||||||
|
public class VectorExample {
|
||||||
|
public int[] scalarComputation(int[] a, int[] b) {
|
||||||
|
var c = new int[a.length];
|
||||||
|
for (int i = 0; i < a.length; i++) {
|
||||||
|
c[i] = a[i] * b[i];
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] vectorComputation(int[] a, int[] b) {
|
||||||
|
var c = new int[a.length];
|
||||||
|
|
||||||
|
var vectorA = IntVector.fromArray(IntVector.SPECIES_128, a, 0);
|
||||||
|
var vectorB = IntVector.fromArray(IntVector.SPECIES_128, b, 0);
|
||||||
|
var vectorC = vectorA.mul(vectorB);
|
||||||
|
vectorC.intoArray(c, 0);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.baeldung.features.model;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class Book {
|
||||||
|
private final String title;
|
||||||
|
private final String author;
|
||||||
|
private final String isbn;
|
||||||
|
|
||||||
|
public Book(String title, String author, String isbn) {
|
||||||
|
this.title = title;
|
||||||
|
this.author = author;
|
||||||
|
this.isbn = isbn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIsbn() {
|
||||||
|
return isbn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Book book = (Book) o;
|
||||||
|
return Objects.equals(title, book.title) && Objects.equals(author, book.author) && Objects.equals(isbn, book.isbn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(title, author, isbn);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.baeldung.features.record;
|
||||||
|
|
||||||
|
public record Book(String title, String author, String isbn) {
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.baeldung.features.sealed;
|
||||||
|
|
||||||
|
public sealed interface JungleAnimal permits Monkey, Snake {
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.baeldung.features.sealed;
|
||||||
|
|
||||||
|
public final class Monkey implements JungleAnimal {
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.features.sealed;
|
||||||
|
|
||||||
|
public class Sealed {
|
||||||
|
public static void main(String... args) {
|
||||||
|
JungleAnimal j = new Monkey();
|
||||||
|
|
||||||
|
if (j instanceof Monkey m) {
|
||||||
|
// do logic
|
||||||
|
} else if (j instanceof Snake s) {
|
||||||
|
// do logic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.baeldung.features.sealed;
|
||||||
|
|
||||||
|
public non-sealed class Snake implements JungleAnimal {
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
package com.baeldung.java_16_features.groupingby;
|
package com.baeldung.java_16_features.groupingby;
|
||||||
|
|
||||||
|
import java.util.IntSummaryStatistics;
|
||||||
|
|
||||||
|
|
||||||
public class BlogPost {
|
public class BlogPost {
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
@ -7,6 +10,8 @@ public class BlogPost {
|
||||||
private BlogPostType type;
|
private BlogPostType type;
|
||||||
private int likes;
|
private int likes;
|
||||||
record AuthPostTypesLikes(String author, BlogPostType type, int likes) {};
|
record AuthPostTypesLikes(String author, BlogPostType type, int likes) {};
|
||||||
|
record PostcountTitlesLikesStats(long postCount, String titles, IntSummaryStatistics likesStats){};
|
||||||
|
record TitlesBoundedSumOfLikes(String titles, int boundedSumOfLikes) {};
|
||||||
|
|
||||||
public BlogPost(String title, String author, BlogPostType type, int likes) {
|
public BlogPost(String title, String author, BlogPostType type, int likes) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.baeldung.java_16_features.mapmulti;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
public class Album {
|
||||||
|
|
||||||
|
private String albumName;
|
||||||
|
private int albumCost;
|
||||||
|
private List<Artist> artists;
|
||||||
|
|
||||||
|
Album(String name, int albumCost, List<Artist> artists) {
|
||||||
|
this.albumName = name;
|
||||||
|
this.artists = artists;
|
||||||
|
this.albumCost = albumCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void artistAlbumPairsToMajorLabels(Consumer<Pair<String, String>> consumer) {
|
||||||
|
|
||||||
|
for (Artist artist : artists) {
|
||||||
|
if (artist.isAssociatedMajorLabels()) {
|
||||||
|
String concatLabels = artist.getMajorLabels()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.joining(","));
|
||||||
|
consumer.accept(new ImmutablePair<>(artist.getName() + ":" + albumName, concatLabels));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlbumName() {
|
||||||
|
return albumName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAlbumCost() {
|
||||||
|
return albumCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Artist> getArtists() {
|
||||||
|
return artists;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return albumName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.java_16_features.mapmulti;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class Artist {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private boolean associatedMajorLabels;
|
||||||
|
private List<String> majorLabels;
|
||||||
|
|
||||||
|
Artist(String name, boolean associatedMajorLabels, List<String> majorLabels) {
|
||||||
|
this.name = name;
|
||||||
|
this.associatedMajorLabels = associatedMajorLabels;
|
||||||
|
this.majorLabels = majorLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAssociatedMajorLabels() {
|
||||||
|
return associatedMajorLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getMajorLabels() {
|
||||||
|
return majorLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Artist other = (Artist) obj;
|
||||||
|
return Objects.equals(name, other.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
module core.java {
|
||||||
|
requires jdk.incubator.vector;
|
||||||
|
requires org.apache.commons.lang3;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class DayPeriodSupportUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASpecificTime_whenFormattingUsingTheBSymbol_thenExpectVerbosePeriodOfDay() {
|
||||||
|
LocalTime date = LocalTime.parse("15:25:08.690791");
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h B");
|
||||||
|
assertThat(date.format(formatter)).isEqualTo("3 in the afternoon");
|
||||||
|
|
||||||
|
formatter = DateTimeFormatter.ofPattern("h BBBB");
|
||||||
|
assertThat(date.format(formatter)).isEqualTo("3 in the afternoon");
|
||||||
|
|
||||||
|
formatter = DateTimeFormatter.ofPattern("h BBBBB");
|
||||||
|
assertThat(date.format(formatter)).isEqualTo("3 in the afternoon");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
|
||||||
|
import static java.lang.ClassLoader.getSystemClassLoader;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class HelloWorldUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAnInterfaceWithDefaulMethod_whenCreatingProxyInstance_thenCanInvokeDefaultMethod() throws Exception {
|
||||||
|
Object proxy = Proxy.newProxyInstance(getSystemClassLoader(), new Class<?>[] { HelloWorld.class },
|
||||||
|
(prox, method, args) -> {
|
||||||
|
if (method.isDefault()) {
|
||||||
|
return InvocationHandler.invokeDefault(prox, method, args);
|
||||||
|
}
|
||||||
|
return method.invoke(prox, args);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Method method = proxy.getClass().getMethod("hello");
|
||||||
|
assertThat(method.invoke(proxy)).isEqualTo("world");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class InstanceOfPatternMatchingUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenTheNewPatternMatchingAbility_whenComparingAgainstTheTradiationalApproach_thenBothVariablesAreEqual() {
|
||||||
|
Object obj = "TEST";
|
||||||
|
|
||||||
|
if (obj instanceof String a) {
|
||||||
|
String b = (String) obj;
|
||||||
|
assertThat(a).isEqualTo(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class StreamToListUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenAStream_whenCreatingANewListFromStream_thenCollectorsOrInbuiltFunctionAreEquivalent() {
|
||||||
|
List<String> integersAsString = Arrays.asList("1", "2", "3");
|
||||||
|
List<Integer> ints = integersAsString.stream().map(Integer::parseInt).collect(Collectors.toList());
|
||||||
|
List<Integer> intsEquivalent = integersAsString.stream().map(Integer::parseInt).toList();
|
||||||
|
assertThat(ints).isEqualTo(intsEquivalent);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
|
|
||||||
|
class VectorExampleUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenAScalarComputation_whenCalculatingUsingVectorAPI_thenResultIsSameAsPreviousMethodOfComputation() {
|
||||||
|
VectorExample objectUnderTest = new VectorExample();
|
||||||
|
|
||||||
|
int[] a = {1, 2, 3, 4};
|
||||||
|
int[] b = {5, 6, 7, 8};
|
||||||
|
|
||||||
|
int[] result = objectUnderTest.scalarComputation(a, b);
|
||||||
|
int[] result2 = objectUnderTest.vectorComputation(a, b);
|
||||||
|
|
||||||
|
assertArrayEquals(result, result2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,8 @@ import static java.util.stream.Collectors.averagingInt;
|
||||||
import static java.util.stream.Collectors.counting;
|
import static java.util.stream.Collectors.counting;
|
||||||
import static java.util.stream.Collectors.groupingBy;
|
import static java.util.stream.Collectors.groupingBy;
|
||||||
import static java.util.stream.Collectors.groupingByConcurrent;
|
import static java.util.stream.Collectors.groupingByConcurrent;
|
||||||
|
import static java.util.stream.Collectors.collectingAndThen;
|
||||||
|
import static java.util.stream.Collectors.toMap;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
import static java.util.stream.Collectors.mapping;
|
import static java.util.stream.Collectors.mapping;
|
||||||
import static java.util.stream.Collectors.maxBy;
|
import static java.util.stream.Collectors.maxBy;
|
||||||
|
@ -13,6 +15,7 @@ import static java.util.stream.Collectors.summingInt;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static java.util.stream.Collectors.toSet;
|
import static java.util.stream.Collectors.toSet;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.offset;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
@ -251,4 +254,49 @@ public class JavaGroupingByCollectorUnitTest {
|
||||||
assertThat(blogPost.getLikes()).isEqualTo(20);
|
assertThat(blogPost.getLikes()).isEqualTo(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenListOfPosts_whenGroupedByAuthor_thenGetAMapUsingCollectingAndThen() {
|
||||||
|
|
||||||
|
Map<String, BlogPost.PostcountTitlesLikesStats> postsPerAuthor = posts.stream()
|
||||||
|
.collect(groupingBy(BlogPost::getAuthor, collectingAndThen(toList(), list -> {
|
||||||
|
long count = list.stream()
|
||||||
|
.map(BlogPost::getTitle)
|
||||||
|
.collect(counting());
|
||||||
|
String titles = list.stream()
|
||||||
|
.map(BlogPost::getTitle)
|
||||||
|
.collect(joining(" : "));
|
||||||
|
IntSummaryStatistics summary = list.stream()
|
||||||
|
.collect(summarizingInt(BlogPost::getLikes));
|
||||||
|
return new BlogPost.PostcountTitlesLikesStats(count, titles, summary);
|
||||||
|
})));
|
||||||
|
|
||||||
|
BlogPost.PostcountTitlesLikesStats result = postsPerAuthor.get("Author 1");
|
||||||
|
assertThat(result.postCount()).isEqualTo(3L);
|
||||||
|
assertThat(result.titles()).isEqualTo("News item 1 : Programming guide : Tech review 2");
|
||||||
|
assertThat(result.likesStats().getMax()).isEqualTo(20);
|
||||||
|
assertThat(result.likesStats().getMin()).isEqualTo(15);
|
||||||
|
assertThat(result.likesStats().getAverage()).isEqualTo(16.666d, offset(0.001d));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenListOfPosts_whenGroupedByAuthor_thenGetAMapUsingToMap() {
|
||||||
|
|
||||||
|
int maxValLikes = 17;
|
||||||
|
Map<String, BlogPost.TitlesBoundedSumOfLikes> postsPerAuthor = posts.stream()
|
||||||
|
.collect(toMap(BlogPost::getAuthor, post -> {
|
||||||
|
int likes = (post.getLikes() > maxValLikes) ? maxValLikes : post.getLikes();
|
||||||
|
return new BlogPost.TitlesBoundedSumOfLikes(post.getTitle(), likes);
|
||||||
|
}, (u1, u2) -> {
|
||||||
|
int likes = (u2.boundedSumOfLikes() > maxValLikes) ? maxValLikes : u2.boundedSumOfLikes();
|
||||||
|
return new BlogPost.TitlesBoundedSumOfLikes(u1.titles()
|
||||||
|
.toUpperCase() + " : "
|
||||||
|
+ u2.titles()
|
||||||
|
.toUpperCase(),
|
||||||
|
u1.boundedSumOfLikes() + likes);
|
||||||
|
}));
|
||||||
|
|
||||||
|
BlogPost.TitlesBoundedSumOfLikes result = postsPerAuthor.get("Author 1");
|
||||||
|
assertThat(result.titles()).isEqualTo("NEWS ITEM 1 : PROGRAMMING GUIDE : TECH REVIEW 2");
|
||||||
|
assertThat(result.boundedSumOfLikes()).isEqualTo(47);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
package com.baeldung.java_16_features.mapmulti;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.offset;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class JavaStreamMapMultiUnitTest {
|
||||||
|
|
||||||
|
private static final List<Album> albums = Arrays.asList(new Album("album1", 10, Arrays.asList(new Artist("bob", true, Arrays.asList("label1", "label3")), new Artist("tom", true, Arrays.asList("label2", "label3")))),
|
||||||
|
new Album("album2", 20, Arrays.asList(new Artist("bill", true, Arrays.asList("label2", "label3")), new Artist("tom", true, Arrays.asList("label2", "label4")))));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAListOfintegers_whenMapMulti_thenGetListOfOfEvenDoublesPlusPercentage() {
|
||||||
|
|
||||||
|
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
|
||||||
|
double percentage = .01;
|
||||||
|
List<Double> evenDoubles = integers.stream()
|
||||||
|
.<Double> mapMulti((integer, consumer) -> {
|
||||||
|
if (integer % 2 == 0) {
|
||||||
|
consumer.accept((double) integer * (1 + percentage));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertThat(evenDoubles).containsAll(Arrays.asList(2.02D, 4.04D));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAListOfintegers_whenFilterMap_thenGetListOfOfEvenDoublesPlusPercentage() {
|
||||||
|
|
||||||
|
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
|
||||||
|
double percentage = .01;
|
||||||
|
List<Double> evenDoubles = integers.stream()
|
||||||
|
.filter(integer -> integer % 2 == 0)
|
||||||
|
.<Double> map(integer -> ((double) integer * (1 + percentage)))
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertThat(evenDoubles).containsAll(Arrays.asList(2.02D, 4.04D));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAListOfintegers_whenMapMultiToDouble_thenGetSumOfEvenNumbersAfterApplyPercentage() {
|
||||||
|
|
||||||
|
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
|
||||||
|
double percentage = .01;
|
||||||
|
double sum = integers.stream()
|
||||||
|
.mapMultiToDouble((integer, consumer) -> {
|
||||||
|
if (integer % 2 == 0) {
|
||||||
|
consumer.accept(integer * (1 + percentage));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
assertThat(sum).isEqualTo(12.12, offset(0.001d));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAListOfAlbums_whenFlatMap_thenGetListOfArtistAlbumPairs() {
|
||||||
|
|
||||||
|
List<Pair<String, String>> artistAlbum = albums.stream()
|
||||||
|
.flatMap(album -> album.getArtists()
|
||||||
|
.stream()
|
||||||
|
.map(artist -> new ImmutablePair<String, String>(artist.getName(), album.getAlbumName())))
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertThat(artistAlbum).contains(new ImmutablePair<String, String>("bob", "album1"), new ImmutablePair<String,
|
||||||
|
String>("tom", "album1"), new ImmutablePair<String, String>("bill", "album2"), new ImmutablePair<String, String>("tom", "album2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAListOfAlbums_whenMapMulti_thenGetListOfPairsOfArtistAlbum() {
|
||||||
|
|
||||||
|
List<Pair<String, String>> artistAlbum = albums.stream()
|
||||||
|
.<Pair<String, String>> mapMulti((album, consumer) -> {
|
||||||
|
for (Artist artist : album.getArtists()) {
|
||||||
|
consumer.accept(new ImmutablePair<String, String>(artist.getName(), album.getAlbumName()));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertThat(artistAlbum).contains(new ImmutablePair<String, String>("bob", "album1"), new ImmutablePair<String, String>("tom", "album1"),
|
||||||
|
new ImmutablePair<String, String>("bill", "album2"), new ImmutablePair<String, String>("tom", "album2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAListOfAlbums_whenFlatMap_thenGetListOfArtistAlbumjPairsBelowGivenCost() {
|
||||||
|
|
||||||
|
int upperCost = 9;
|
||||||
|
List<Pair<String, String>> artistAlbum = albums.stream()
|
||||||
|
.flatMap(album -> album.getArtists()
|
||||||
|
.stream()
|
||||||
|
.filter(artist -> upperCost > album.getAlbumCost())
|
||||||
|
.map(artist -> new ImmutablePair<String, String>(artist.getName(), album.getAlbumName())))
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertTrue(artistAlbum.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAListOfAlbums_whenMapMulti_thenGetListOfArtistAlbumPairsBelowGivenCost() {
|
||||||
|
|
||||||
|
int upperCost = 9;
|
||||||
|
List<Pair<String, String>> artistAlbum = albums.stream()
|
||||||
|
.<Pair<String, String>> mapMulti((album, consumer) -> {
|
||||||
|
if (album.getAlbumCost() < upperCost) {
|
||||||
|
for (Artist artist : album.getArtists()) {
|
||||||
|
consumer.accept(new ImmutablePair<String, String>(artist.getName(), album.getAlbumName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertTrue(artistAlbum.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAListOfAlbums_whenMapMulti_thenGetPairsOfArtistMajorLabelsUsingMethodReference() {
|
||||||
|
|
||||||
|
List<Pair<String, String>> artistLabels = albums.stream()
|
||||||
|
.mapMulti(Album::artistAlbumPairsToMajorLabels)
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertThat(artistLabels).contains(new ImmutablePair<String, String>("bob:album1", "label1,label3"), new ImmutablePair<String, String>("tom:album1", "label2,label3"),
|
||||||
|
new ImmutablePair<String, String>("bill:album2", "label2,label3"), new ImmutablePair<String, String>("tom:album2", "label2,label4"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package com.baeldung.streams;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class StreamToListComparisonWithCollectorsToListUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingtoCollectToList_thenSuccess() {
|
||||||
|
|
||||||
|
List<String> result = Stream.of(Locale.getISOCountries())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Assertions.assertDoesNotThrow(() -> {
|
||||||
|
result.add("test");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSortingtoCollectToList_thenSuccess() {
|
||||||
|
|
||||||
|
List<String> result = Stream.of(Locale.getISOCountries())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Assertions.assertDoesNotThrow(() -> {
|
||||||
|
result.sort(String::compareToIgnoreCase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingCollectUnmodifiableToList_thenException() {
|
||||||
|
|
||||||
|
List<String> result = Stream.of(Locale.getISOCountries())
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
|
||||||
|
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
|
||||||
|
result.add("test");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSortingCollectUnmodifiableToList_thenSortException() {
|
||||||
|
|
||||||
|
List<String> result = Stream.of(Locale.getISOCountries())
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
|
||||||
|
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
|
||||||
|
result.sort(String::compareToIgnoreCase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingStreamToList_thenException() {
|
||||||
|
|
||||||
|
List<String> result = Stream.of(Locale.getISOCountries())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
|
||||||
|
result.add("test");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSortingStreamToList_thenException() {
|
||||||
|
|
||||||
|
List<String> result = Stream.of(Locale.getISOCountries())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
|
||||||
|
result.sort(String::compareToIgnoreCase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenComparingStreamToList_withCollectToList_thenEqual() {
|
||||||
|
|
||||||
|
List<String> streamToList = Stream.of(Locale.getISOCountries())
|
||||||
|
.toList();
|
||||||
|
List<String> collectToList = Stream.of(Locale.getISOCountries())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Assertions.assertEquals(streamToList, collectToList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenComparingStreamToList_withUnmodifiedCollectToList_thenEqual() {
|
||||||
|
|
||||||
|
List<String> streamToList = Stream.of(Locale.getISOCountries())
|
||||||
|
.toList();
|
||||||
|
List<String> collectToUnmodifiableList = Stream.of(Locale.getISOCountries())
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
|
||||||
|
Assertions.assertEquals(streamToList, collectToUnmodifiableList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNullCollectorsToList_thenSuccess() {
|
||||||
|
|
||||||
|
Assertions.assertDoesNotThrow(() -> {
|
||||||
|
Stream.of(null, null)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNullCollectorsUnmodifiableToList_thenException() {
|
||||||
|
|
||||||
|
Assertions.assertThrows(NullPointerException.class, () -> {
|
||||||
|
Stream.of(null, null)
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNullStreamToList_thenSuccess() {
|
||||||
|
|
||||||
|
Assertions.assertDoesNotThrow(() -> {
|
||||||
|
Stream.of(null, null)
|
||||||
|
.toList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ This module contains articles about Java 8 core features
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [New Features in Java 8](https://www.baeldung.com/java-8-new-features)
|
- [New Features in Java 8](https://www.baeldung.com/java-8-new-features)
|
||||||
- [Guide to Java 8 groupingBy Collector](https://www.baeldung.com/java-groupingby-collector)
|
|
||||||
- [Strategy Design Pattern in Java 8](https://www.baeldung.com/java-strategy-pattern)
|
- [Strategy Design Pattern in Java 8](https://www.baeldung.com/java-strategy-pattern)
|
||||||
- [Guide to Java 8 Comparator.comparing()](https://www.baeldung.com/java-8-comparator-comparing)
|
- [Guide to Java 8 Comparator.comparing()](https://www.baeldung.com/java-8-comparator-comparing)
|
||||||
- [Guide to the Java 8 forEach](https://www.baeldung.com/foreach-java)
|
- [Guide to the Java 8 forEach](https://www.baeldung.com/foreach-java)
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package com.baeldung.java_8_features.groupingby;
|
|
||||||
|
|
||||||
public class BlogPost {
|
|
||||||
private String title;
|
|
||||||
private String author;
|
|
||||||
private BlogPostType type;
|
|
||||||
private int likes;
|
|
||||||
|
|
||||||
public BlogPost(String title, String author, BlogPostType type, int likes) {
|
|
||||||
this.title = title;
|
|
||||||
this.author = author;
|
|
||||||
this.type = type;
|
|
||||||
this.likes = likes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthor() {
|
|
||||||
return author;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlogPostType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLikes() {
|
|
||||||
return likes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "BlogPost{" + "title='" + title + '\'' + ", type=" + type + ", likes=" + likes + '}';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package com.baeldung.java_8_features.groupingby;
|
|
||||||
|
|
||||||
public enum BlogPostType {
|
|
||||||
NEWS, REVIEW, GUIDE
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package com.baeldung.java_8_features.groupingby;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class Tuple {
|
|
||||||
private final BlogPostType type;
|
|
||||||
private final String author;
|
|
||||||
|
|
||||||
public Tuple(BlogPostType type, String author) {
|
|
||||||
this.type = type;
|
|
||||||
this.author = author;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlogPostType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthor() {
|
|
||||||
return author;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
Tuple tuple = (Tuple) o;
|
|
||||||
return type == tuple.type && author.equals(tuple.author);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(type, author);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Tuple{" + "type=" + type + ", author='" + author + '\'' + '}';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,215 +0,0 @@
|
||||||
package com.baeldung.java_8_features.groupingby;
|
|
||||||
|
|
||||||
import static java.util.Comparator.comparingInt;
|
|
||||||
import static java.util.stream.Collectors.averagingInt;
|
|
||||||
import static java.util.stream.Collectors.counting;
|
|
||||||
import static java.util.stream.Collectors.groupingBy;
|
|
||||||
import static java.util.stream.Collectors.groupingByConcurrent;
|
|
||||||
import static java.util.stream.Collectors.joining;
|
|
||||||
import static java.util.stream.Collectors.mapping;
|
|
||||||
import static java.util.stream.Collectors.maxBy;
|
|
||||||
import static java.util.stream.Collectors.summarizingInt;
|
|
||||||
import static java.util.stream.Collectors.summingInt;
|
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
import static java.util.stream.Collectors.toSet;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.EnumMap;
|
|
||||||
import java.util.IntSummaryStatistics;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class Java8GroupingByCollectorUnitTest {
|
|
||||||
|
|
||||||
private static final List<BlogPost> posts = Arrays.asList(new BlogPost("News item 1", "Author 1", BlogPostType.NEWS, 15), new BlogPost("Tech review 1", "Author 2", BlogPostType.REVIEW, 5),
|
|
||||||
new BlogPost("Programming guide", "Author 1", BlogPostType.GUIDE, 20), new BlogPost("News item 2", "Author 2", BlogPostType.NEWS, 35), new BlogPost("Tech review 2", "Author 1", BlogPostType.REVIEW, 15));
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByType_thenGetAMapBetweenTypeAndPosts() {
|
|
||||||
Map<BlogPostType, List<BlogPost>> postsPerType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType));
|
|
||||||
|
|
||||||
assertEquals(2, postsPerType.get(BlogPostType.NEWS)
|
|
||||||
.size());
|
|
||||||
assertEquals(1, postsPerType.get(BlogPostType.GUIDE)
|
|
||||||
.size());
|
|
||||||
assertEquals(2, postsPerType.get(BlogPostType.REVIEW)
|
|
||||||
.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeAndTheirTitlesAreJoinedInAString_thenGetAMapBetweenTypeAndCsvTitles() {
|
|
||||||
Map<BlogPostType, String> postsPerType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType, mapping(BlogPost::getTitle, joining(", ", "Post titles: [", "]"))));
|
|
||||||
|
|
||||||
assertEquals("Post titles: [News item 1, News item 2]", postsPerType.get(BlogPostType.NEWS));
|
|
||||||
assertEquals("Post titles: [Programming guide]", postsPerType.get(BlogPostType.GUIDE));
|
|
||||||
assertEquals("Post titles: [Tech review 1, Tech review 2]", postsPerType.get(BlogPostType.REVIEW));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeAndSumTheLikes_thenGetAMapBetweenTypeAndPostLikes() {
|
|
||||||
Map<BlogPostType, Integer> likesPerType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType, summingInt(BlogPost::getLikes)));
|
|
||||||
|
|
||||||
assertEquals(50, likesPerType.get(BlogPostType.NEWS)
|
|
||||||
.intValue());
|
|
||||||
assertEquals(20, likesPerType.get(BlogPostType.REVIEW)
|
|
||||||
.intValue());
|
|
||||||
assertEquals(20, likesPerType.get(BlogPostType.GUIDE)
|
|
||||||
.intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeInAnEnumMap_thenGetAnEnumMapBetweenTypeAndPosts() {
|
|
||||||
EnumMap<BlogPostType, List<BlogPost>> postsPerType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType, () -> new EnumMap<>(BlogPostType.class), toList()));
|
|
||||||
|
|
||||||
assertEquals(2, postsPerType.get(BlogPostType.NEWS)
|
|
||||||
.size());
|
|
||||||
assertEquals(1, postsPerType.get(BlogPostType.GUIDE)
|
|
||||||
.size());
|
|
||||||
assertEquals(2, postsPerType.get(BlogPostType.REVIEW)
|
|
||||||
.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeInSets_thenGetAMapBetweenTypesAndSetsOfPosts() {
|
|
||||||
Map<BlogPostType, Set<BlogPost>> postsPerType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType, toSet()));
|
|
||||||
|
|
||||||
assertEquals(2, postsPerType.get(BlogPostType.NEWS)
|
|
||||||
.size());
|
|
||||||
assertEquals(1, postsPerType.get(BlogPostType.GUIDE)
|
|
||||||
.size());
|
|
||||||
assertEquals(2, postsPerType.get(BlogPostType.REVIEW)
|
|
||||||
.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeConcurrently_thenGetAMapBetweenTypeAndPosts() {
|
|
||||||
ConcurrentMap<BlogPostType, List<BlogPost>> postsPerType = posts.parallelStream()
|
|
||||||
.collect(groupingByConcurrent(BlogPost::getType));
|
|
||||||
|
|
||||||
assertEquals(2, postsPerType.get(BlogPostType.NEWS)
|
|
||||||
.size());
|
|
||||||
assertEquals(1, postsPerType.get(BlogPostType.GUIDE)
|
|
||||||
.size());
|
|
||||||
assertEquals(2, postsPerType.get(BlogPostType.REVIEW)
|
|
||||||
.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeAndAveragingLikes_thenGetAMapBetweenTypeAndAverageNumberOfLikes() {
|
|
||||||
Map<BlogPostType, Double> averageLikesPerType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType, averagingInt(BlogPost::getLikes)));
|
|
||||||
|
|
||||||
assertEquals(25, averageLikesPerType.get(BlogPostType.NEWS)
|
|
||||||
.intValue());
|
|
||||||
assertEquals(20, averageLikesPerType.get(BlogPostType.GUIDE)
|
|
||||||
.intValue());
|
|
||||||
assertEquals(10, averageLikesPerType.get(BlogPostType.REVIEW)
|
|
||||||
.intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeAndCounted_thenGetAMapBetweenTypeAndNumberOfPosts() {
|
|
||||||
Map<BlogPostType, Long> numberOfPostsPerType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType, counting()));
|
|
||||||
|
|
||||||
assertEquals(2, numberOfPostsPerType.get(BlogPostType.NEWS)
|
|
||||||
.intValue());
|
|
||||||
assertEquals(1, numberOfPostsPerType.get(BlogPostType.GUIDE)
|
|
||||||
.intValue());
|
|
||||||
assertEquals(2, numberOfPostsPerType.get(BlogPostType.REVIEW)
|
|
||||||
.intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeAndMaxingLikes_thenGetAMapBetweenTypeAndMaximumNumberOfLikes() {
|
|
||||||
Map<BlogPostType, Optional<BlogPost>> maxLikesPerPostType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType, maxBy(comparingInt(BlogPost::getLikes))));
|
|
||||||
|
|
||||||
assertTrue(maxLikesPerPostType.get(BlogPostType.NEWS)
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(35, maxLikesPerPostType.get(BlogPostType.NEWS)
|
|
||||||
.get()
|
|
||||||
.getLikes());
|
|
||||||
|
|
||||||
assertTrue(maxLikesPerPostType.get(BlogPostType.GUIDE)
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(20, maxLikesPerPostType.get(BlogPostType.GUIDE)
|
|
||||||
.get()
|
|
||||||
.getLikes());
|
|
||||||
|
|
||||||
assertTrue(maxLikesPerPostType.get(BlogPostType.REVIEW)
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(15, maxLikesPerPostType.get(BlogPostType.REVIEW)
|
|
||||||
.get()
|
|
||||||
.getLikes());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByAuthorAndThenByType_thenGetAMapBetweenAuthorAndMapsBetweenTypeAndBlogPosts() {
|
|
||||||
Map<String, Map<BlogPostType, List<BlogPost>>> map = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getAuthor, groupingBy(BlogPost::getType)));
|
|
||||||
|
|
||||||
assertEquals(1, map.get("Author 1")
|
|
||||||
.get(BlogPostType.NEWS)
|
|
||||||
.size());
|
|
||||||
assertEquals(1, map.get("Author 1")
|
|
||||||
.get(BlogPostType.GUIDE)
|
|
||||||
.size());
|
|
||||||
assertEquals(1, map.get("Author 1")
|
|
||||||
.get(BlogPostType.REVIEW)
|
|
||||||
.size());
|
|
||||||
|
|
||||||
assertEquals(1, map.get("Author 2")
|
|
||||||
.get(BlogPostType.NEWS)
|
|
||||||
.size());
|
|
||||||
assertEquals(1, map.get("Author 2")
|
|
||||||
.get(BlogPostType.REVIEW)
|
|
||||||
.size());
|
|
||||||
assertNull(map.get("Author 2")
|
|
||||||
.get(BlogPostType.GUIDE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByTypeAndSummarizingLikes_thenGetAMapBetweenTypeAndSummary() {
|
|
||||||
Map<BlogPostType, IntSummaryStatistics> likeStatisticsPerType = posts.stream()
|
|
||||||
.collect(groupingBy(BlogPost::getType, summarizingInt(BlogPost::getLikes)));
|
|
||||||
|
|
||||||
IntSummaryStatistics newsLikeStatistics = likeStatisticsPerType.get(BlogPostType.NEWS);
|
|
||||||
|
|
||||||
assertEquals(2, newsLikeStatistics.getCount());
|
|
||||||
assertEquals(50, newsLikeStatistics.getSum());
|
|
||||||
assertEquals(25.0, newsLikeStatistics.getAverage(), 0.001);
|
|
||||||
assertEquals(35, newsLikeStatistics.getMax());
|
|
||||||
assertEquals(15, newsLikeStatistics.getMin());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAListOfPosts_whenGroupedByComplexMapKeyType_thenGetAMapBetweenTupleAndList() {
|
|
||||||
Map<Tuple, List<BlogPost>> postsPerTypeAndAuthor = posts.stream()
|
|
||||||
.collect(groupingBy(post -> new Tuple(post.getType(), post.getAuthor())));
|
|
||||||
|
|
||||||
List<BlogPost> result = postsPerTypeAndAuthor.get(new Tuple(BlogPostType.GUIDE, "Author 1"));
|
|
||||||
|
|
||||||
assertThat(result.size()).isEqualTo(1);
|
|
||||||
|
|
||||||
BlogPost blogPost = result.get(0);
|
|
||||||
|
|
||||||
assertThat(blogPost.getTitle()).isEqualTo("Programming guide");
|
|
||||||
assertThat(blogPost.getType()).isEqualTo(BlogPostType.GUIDE);
|
|
||||||
assertThat(blogPost.getAuthor()).isEqualTo("Author 1");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,3 +10,4 @@ This module contains articles about advanced operations on arrays in Java. They
|
||||||
- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection)
|
- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection)
|
||||||
- [Comparing Arrays in Java](https://www.baeldung.com/java-comparing-arrays)
|
- [Comparing Arrays in Java](https://www.baeldung.com/java-comparing-arrays)
|
||||||
- [Concatenate Two Arrays in Java](https://www.baeldung.com/java-concatenate-arrays)
|
- [Concatenate Two Arrays in Java](https://www.baeldung.com/java-concatenate-arrays)
|
||||||
|
- [Performance of System.arraycopy() vs. Arrays.copyOf()](https://www.baeldung.com/java-system-arraycopy-arrays-copyof-performance)
|
||||||
|
|
|
@ -26,10 +26,50 @@
|
||||||
<version>${assertj-core.version}</version>
|
<version>${assertj-core.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-core</artifactId>
|
||||||
|
<version>${jmh.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>${jmh.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
|
<jmh.version>1.33</jmh.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.baeldung.copyarraymethodsperformance.BenchmarkRunner</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.copyarraymethodsperformance;
|
||||||
|
|
||||||
|
public class BenchmarkRunner {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
org.openjdk.jmh.Main.main(args);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.copyarraymethodsperformance;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@Warmup(iterations = 10)
|
||||||
|
@Fork(1)
|
||||||
|
@Measurement(iterations = 100)
|
||||||
|
public class ObjectsCopyBenchmark {
|
||||||
|
|
||||||
|
@Param({ "10", "1000000" })
|
||||||
|
public int SIZE;
|
||||||
|
Integer[] src;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
Random r = new Random();
|
||||||
|
src = new Integer[SIZE];
|
||||||
|
|
||||||
|
for (int i = 0; i < SIZE; i++) {
|
||||||
|
src[i] = r.nextInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Integer[] systemArrayCopyBenchmark() {
|
||||||
|
Integer[] target = new Integer[SIZE];
|
||||||
|
System.arraycopy(src, 0, target, 0, SIZE);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Integer[] arraysCopyOfBenchmark() {
|
||||||
|
return Arrays.copyOf(src, SIZE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.copyarraymethodsperformance;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@Warmup(iterations = 10)
|
||||||
|
@Fork(1)
|
||||||
|
@Measurement(iterations = 100)
|
||||||
|
public class PrimitivesCopyBenchmark {
|
||||||
|
|
||||||
|
@Param({ "10", "1000000" })
|
||||||
|
public int SIZE;
|
||||||
|
|
||||||
|
int[] src;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
Random r = new Random();
|
||||||
|
src = new int[SIZE];
|
||||||
|
|
||||||
|
for (int i = 0; i < SIZE; i++) {
|
||||||
|
src[i] = r.nextInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] systemArrayCopyBenchmark() {
|
||||||
|
int[] target = new int[SIZE];
|
||||||
|
System.arraycopy(src, 0, target, 0, SIZE);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] arraysCopyOfBenchmark() {
|
||||||
|
return Arrays.copyOf(src, SIZE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -78,4 +78,5 @@
|
||||||
<guava.version>28.2-jre</guava.version>
|
<guava.version>28.2-jre</guava.version>
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -8,5 +8,5 @@ This module contains articles about Map data structures in Java.
|
||||||
- [The Map.computeIfAbsent() Method](https://www.baeldung.com/java-map-computeifabsent)
|
- [The Map.computeIfAbsent() Method](https://www.baeldung.com/java-map-computeifabsent)
|
||||||
- [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap)
|
- [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap)
|
||||||
- [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor)
|
- [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor)
|
||||||
- [Converting java.util.Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap)
|
- [Converting Java Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap)
|
||||||
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)
|
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
## Java Collections Cookbooks and Examples
|
||||||
|
|
||||||
|
This module contains articles about Map data structures in Java.
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Using a Custom Class as a Key in a Java HashMap](https://www.baeldung.com/custom-key-hashmap)
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>core-java-collections-maps-4</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>core-java-collections-maps-4</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
|
<artifactId>core-java-modules</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.0.0-M5</version>
|
||||||
|
<configuration>
|
||||||
|
<!-- those tests are not made for CI purposes, but for manual testing -->
|
||||||
|
<groups>!performance</groups>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.baeldung.maps;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class CoordinateKey {
|
||||||
|
|
||||||
|
private final int x;
|
||||||
|
private final int y;
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
|
public CoordinateKey(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.hashCode = Objects.hash(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
CoordinateKey that = (CoordinateKey) o;
|
||||||
|
return x == that.x && y == that.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.hashCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.baeldung.maps;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class CoordinateMutableKey {
|
||||||
|
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
|
||||||
|
public CoordinateMutableKey(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
CoordinateMutableKey that = (CoordinateMutableKey) o;
|
||||||
|
return x == that.x && y == that.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(x, y);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.maps;
|
||||||
|
|
||||||
|
public class CoordinateSlowKey extends CoordinateKey {
|
||||||
|
|
||||||
|
public CoordinateSlowKey(int x, int y) {
|
||||||
|
super(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.baeldung.maps;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
public class CoordinateKeyUnitTest {
|
||||||
|
|
||||||
|
private Map<CoordinateKey, Color> pixels = new HashMap<>();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOptimalKey() {
|
||||||
|
// setup
|
||||||
|
CoordinateKey coord = new CoordinateKey(1, 2);
|
||||||
|
pixels.put(coord, Color.CYAN);
|
||||||
|
// read out color correctly
|
||||||
|
assertEquals(Color.CYAN, pixels.get(coord));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSlowKey() {
|
||||||
|
// setup
|
||||||
|
CoordinateKey coord = new CoordinateSlowKey(1, 2);
|
||||||
|
pixels.put(coord, Color.CYAN);
|
||||||
|
// read out color correctly
|
||||||
|
assertEquals(Color.CYAN, pixels.get(coord));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performance Test Parameters - change here
|
||||||
|
private static final int MAX_X = 100;
|
||||||
|
private static final int MAX_Y = 100;
|
||||||
|
private static final int COUNT_OF_QUERIES = 1000;
|
||||||
|
private static final int QUERY_X = 1;
|
||||||
|
private static final int QUERY_Y = 1;
|
||||||
|
|
||||||
|
@Tag("performance")
|
||||||
|
@Test
|
||||||
|
void testKeyPerformance() {
|
||||||
|
// generate some sample keys and values
|
||||||
|
for (int x = 0; x < MAX_X; x++) {
|
||||||
|
for (int y = 0; y < MAX_Y; y++) {
|
||||||
|
pixels.put(new CoordinateKey(x, y), new Color(x % 255, y % 255, (x + y) % 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// read out multiple times and measure time
|
||||||
|
CoordinateKey coord = new CoordinateKey(QUERY_X, QUERY_Y);
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
for (int i = 0; i < COUNT_OF_QUERIES; i++) {
|
||||||
|
assertNotNull(pixels.get(coord));
|
||||||
|
}
|
||||||
|
long t2 = System.currentTimeMillis();
|
||||||
|
System.out.printf("Optimal key performance: %d ms%n", t2 - t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Tag("performance")
|
||||||
|
@Test
|
||||||
|
void testSlowKeyPerformance() {
|
||||||
|
// generate some sample keys and values
|
||||||
|
for (int x = 0; x < MAX_X; x++) {
|
||||||
|
for (int y = 0; y < MAX_Y; y++) {
|
||||||
|
pixels.put(new CoordinateSlowKey(x, y), new Color(x % 255, y % 255, (x + y) % 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// read out multiple times and measure time
|
||||||
|
CoordinateKey coord = new CoordinateSlowKey(QUERY_X, QUERY_Y);
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
for (int i = 0; i < COUNT_OF_QUERIES; i++) {
|
||||||
|
assertNotNull(pixels.get(coord));
|
||||||
|
}
|
||||||
|
long t2 = System.currentTimeMillis();
|
||||||
|
System.out.printf("Slow key performance: %d ms%n", t2 - t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.maps;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
public class CoordinateMutableKeyUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testKeyMutable() {
|
||||||
|
// setup
|
||||||
|
Map<CoordinateMutableKey, Color> pixels = new HashMap<>();
|
||||||
|
CoordinateMutableKey coord = new CoordinateMutableKey(1, 2);
|
||||||
|
pixels.put(coord, Color.CYAN);
|
||||||
|
// read out color correctly
|
||||||
|
assertEquals(Color.CYAN, pixels.get(coord));
|
||||||
|
// change key's hashcode should result in null value
|
||||||
|
coord.setX(10);
|
||||||
|
assertNull(pixels.get(coord));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,6 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Read and Write User Input in Java](http://www.baeldung.com/java-console-input-output)
|
- [Read and Write User Input in Java](http://www.baeldung.com/java-console-input-output)
|
||||||
- [Formatting with printf() in Java](https://www.baeldung.com/java-printstream-printf)
|
- [Formatting Output with printf() in Java](https://www.baeldung.com/java-printstream-printf)
|
||||||
- [ASCII Art in Java](http://www.baeldung.com/ascii-art-in-java)
|
- [ASCII Art in Java](http://www.baeldung.com/ascii-art-in-java)
|
||||||
- [System.console() vs. System.out](https://www.baeldung.com/java-system-console-vs-system-out)
|
- [System.console() vs. System.out](https://www.baeldung.com/java-system-console-vs-system-out)
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang3.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
<artifactId>assertj-core</artifactId>
|
<artifactId>assertj-core</artifactId>
|
||||||
|
|
|
@ -11,3 +11,4 @@ This module contains articles about parsing and formatting Java date and time ob
|
||||||
- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones)
|
- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones)
|
||||||
- [Convert between String and Timestamp](https://www.baeldung.com/java-string-to-timestamp)
|
- [Convert between String and Timestamp](https://www.baeldung.com/java-string-to-timestamp)
|
||||||
- [Convert String to Date in Java](http://www.baeldung.com/java-string-to-date)
|
- [Convert String to Date in Java](http://www.baeldung.com/java-string-to-date)
|
||||||
|
- [Format a Milliseconds Duration to HH:MM:SS](https://www.baeldung.com/java-ms-to-hhmmss)
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-validator.version>1.6</commons-validator.version>
|
<commons-validator.version>1.6</commons-validator.version>
|
||||||
<joda-time.version>2.10</joda-time.version>
|
<joda-time.version>2.10.10</joda-time.version>
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
<maven.compiler.source>1.9</maven.compiler.source>
|
<maven.compiler.source>1.9</maven.compiler.source>
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.baeldung.formatduration;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.time.DurationFormatUtils;
|
||||||
|
import org.joda.time.Period;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FormatDurationUnitTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInterval_WhenFormatInterval_formatDuration() {
|
||||||
|
long HH = TimeUnit.MILLISECONDS.toHours(38114000);
|
||||||
|
long MM = TimeUnit.MILLISECONDS.toMinutes(38114000) % 60;
|
||||||
|
long SS = TimeUnit.MILLISECONDS.toSeconds(38114000) % 60;
|
||||||
|
String timeInHHMMSS = String.format("%02d:%02d:%02d", HH, MM, SS);
|
||||||
|
|
||||||
|
assertThat(timeInHHMMSS).isEqualTo("10:35:14");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInterval_WhenFormatUsingDuration_formatDuration() {
|
||||||
|
Duration duration = Duration.ofMillis(38114000);
|
||||||
|
long seconds = duration.getSeconds();
|
||||||
|
long HH = seconds / 3600;
|
||||||
|
long MM = (seconds % 3600) / 60;
|
||||||
|
long SS = seconds % 60;
|
||||||
|
String timeInHHMMSS = String.format("%02d:%02d:%02d", HH, MM, SS);
|
||||||
|
assertThat(timeInHHMMSS).isEqualTo("10:35:14");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInterval_WhenFormatDurationUsingApacheCommons_formatDuration() {
|
||||||
|
assertThat(DurationFormatUtils.formatDuration(38114000, "HH:mm:ss"))
|
||||||
|
.isEqualTo("10:35:14");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInterval_WhenFormatDurationUsingJodaTime_formatDuration() {
|
||||||
|
org.joda.time.Duration duration = new org.joda.time.Duration(38114000);
|
||||||
|
Period period = duration.toPeriod();
|
||||||
|
long HH = period.getHours();
|
||||||
|
long MM = period.getMinutes();
|
||||||
|
long SS = period.getSeconds();
|
||||||
|
|
||||||
|
String timeInHHMMSS = String.format("%02d:%02d:%02d", HH, MM, SS);
|
||||||
|
assertThat(timeInHHMMSS).isEqualTo("10:35:14");
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,4 +36,5 @@
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -13,4 +13,5 @@ This module contains articles about core Java input/output(IO) conversions.
|
||||||
- [Java – Write a Reader to File](https://www.baeldung.com/java-write-reader-to-file)
|
- [Java – Write a Reader to File](https://www.baeldung.com/java-write-reader-to-file)
|
||||||
- [Java – Reader to Byte Array](https://www.baeldung.com/java-convert-reader-to-byte-array)
|
- [Java – Reader to Byte Array](https://www.baeldung.com/java-convert-reader-to-byte-array)
|
||||||
- [Java – Reader to InputStream](https://www.baeldung.com/java-convert-reader-to-inputstream)
|
- [Java – Reader to InputStream](https://www.baeldung.com/java-convert-reader-to-inputstream)
|
||||||
|
- [Java String to InputStream](https://www.baeldung.com/convert-string-to-input-stream)
|
||||||
- More articles: [[next -->]](/core-java-modules/core-java-io-conversions-2)
|
- More articles: [[next -->]](/core-java-modules/core-java-io-conversions-2)
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
<logger name="org.springframework" level="WARN" />
|
<logger name="org.springframework" level="WARN" />
|
||||||
<logger name="org.springframework.transaction" level="WARN" />
|
<logger name="org.springframework.transaction" level="WARN" />
|
||||||
|
<logger name="net.sf.jmimemagic" level="WARN" />
|
||||||
|
|
||||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>${maven-dependency-plugin.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>copy-dependencies</id>
|
<id>copy-dependencies</id>
|
||||||
|
@ -106,6 +107,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>${maven-assembly-plugin.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
|
@ -383,6 +385,8 @@
|
||||||
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
|
||||||
<onejar-maven-plugin.version>1.4.4</onejar-maven-plugin.version>
|
<onejar-maven-plugin.version>1.4.4</onejar-maven-plugin.version>
|
||||||
<maven-shade-plugin.version>3.1.1</maven-shade-plugin.version>
|
<maven-shade-plugin.version>3.1.1</maven-shade-plugin.version>
|
||||||
|
<maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
|
||||||
|
<maven-dependency-plugin.version>3.2.0</maven-dependency-plugin.version>
|
||||||
<spring-boot-maven-plugin.version>2.0.3.RELEASE</spring-boot-maven-plugin.version>
|
<spring-boot-maven-plugin.version>2.0.3.RELEASE</spring-boot-maven-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>
|
||||||
|
|
|
@ -8,7 +8,30 @@ import org.junit.Test;
|
||||||
public class IsInstanceIsAssignableFromUnitTest {
|
public class IsInstanceIsAssignableFromUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingIsInstanceProperly_desiredResultsHappen() {
|
public void whenUsingInstanceOfProperly_thenDesiredResultsHappen() {
|
||||||
|
Shape shape = new Triangle();
|
||||||
|
Triangle triangle = new Triangle();
|
||||||
|
IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle();
|
||||||
|
Shape nonspecificShape = null;
|
||||||
|
|
||||||
|
assertTrue(shape instanceof Shape);
|
||||||
|
assertTrue(triangle instanceof Shape);
|
||||||
|
assertTrue(isoscelesTriangle instanceof Shape);
|
||||||
|
assertFalse(nonspecificShape instanceof Shape);
|
||||||
|
|
||||||
|
assertTrue(shape instanceof Triangle);
|
||||||
|
assertTrue(triangle instanceof Triangle);
|
||||||
|
assertTrue(isoscelesTriangle instanceof Triangle);
|
||||||
|
assertFalse(nonspecificShape instanceof Triangle);
|
||||||
|
|
||||||
|
assertFalse(shape instanceof IsoscelesTriangle);
|
||||||
|
assertFalse(triangle instanceof IsoscelesTriangle);
|
||||||
|
assertTrue(isoscelesTriangle instanceof IsoscelesTriangle);
|
||||||
|
assertFalse(nonspecificShape instanceof IsoscelesTriangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingIsInstanceProperly_thenDesiredResultsHappen() {
|
||||||
Shape shape = new Triangle();
|
Shape shape = new Triangle();
|
||||||
Triangle triangle = new Triangle();
|
Triangle triangle = new Triangle();
|
||||||
IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle();
|
IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle();
|
||||||
|
@ -33,7 +56,7 @@ public class IsInstanceIsAssignableFromUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingIsAssignableFromProperly_desiredResultsHappen() {
|
public void whenUsingIsAssignableFromProperly_thenDesiredResultsHappen() {
|
||||||
Shape shape = new Triangle();
|
Shape shape = new Triangle();
|
||||||
Triangle triangle = new Triangle();
|
Triangle triangle = new Triangle();
|
||||||
IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle();
|
IsoscelesTriangle isoscelesTriangle = new IsoscelesTriangle();
|
||||||
|
@ -64,4 +87,31 @@ public class IsInstanceIsAssignableFromUnitTest {
|
||||||
assertTrue(isoscelesTriangle2.getClass().isAssignableFrom(isoscelesTriangle2.getClass()));
|
assertTrue(isoscelesTriangle2.getClass().isAssignableFrom(isoscelesTriangle2.getClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void whenUsingNull_thenDesiredResultsHappen() {
|
||||||
|
assertFalse(null instanceof Shape);
|
||||||
|
assertFalse(Shape.class.isInstance(null));
|
||||||
|
assertFalse(Shape.class.isAssignableFrom(null)); // NullPointerException
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingPrimitiveType_thenDesiredResultsHappen() {
|
||||||
|
//assertFalse(10 instanceof int); // illegal
|
||||||
|
assertFalse(int.class.isInstance(10));
|
||||||
|
assertTrue(Integer.class.isInstance(10));
|
||||||
|
assertTrue(int.class.isAssignableFrom(int.class));
|
||||||
|
assertFalse(float.class.isAssignableFrom(int.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingClassInstanceVariable_thenDesiredResultsHappen() {
|
||||||
|
Shape shape = new Triangle();
|
||||||
|
Triangle triangle = new Triangle();
|
||||||
|
Class<?> clazz = shape.getClass();
|
||||||
|
|
||||||
|
//assertFalse(triangle instanceof clazz); // illegal
|
||||||
|
assertTrue(clazz.isInstance(triangle));
|
||||||
|
assertTrue(clazz.isAssignableFrom(triangle.getClass()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,3 +8,4 @@ This module contains articles about core features in the Java language
|
||||||
- [Java Objects.hash() vs Objects.hashCode()](https://www.baeldung.com/java-objects-hash-vs-objects-hashcode)
|
- [Java Objects.hash() vs Objects.hashCode()](https://www.baeldung.com/java-objects-hash-vs-objects-hashcode)
|
||||||
- [Referencing a Method in Javadoc Comments](https://www.baeldung.com/java-method-in-javadoc)
|
- [Referencing a Method in Javadoc Comments](https://www.baeldung.com/java-method-in-javadoc)
|
||||||
- [Tiered Compilation in JVM](https://www.baeldung.com/jvm-tiered-compilation)
|
- [Tiered Compilation in JVM](https://www.baeldung.com/jvm-tiered-compilation)
|
||||||
|
- [Fixing the “Declared package does not match the expected package” Error](https://www.baeldung.com/java-declared-expected-package-error)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
// The next line is commented out to avoid the code to fail the build.
|
||||||
|
// package com.baeldung;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the below package declaration is commented out and the above incorrect package
|
||||||
|
* declaration is uncommented, then the problem will replicate.
|
||||||
|
*/
|
||||||
|
package com.baeldung.bookstore;
|
||||||
|
|
||||||
|
public class Book {
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
private String author;
|
||||||
|
private long isbn;
|
||||||
|
|
||||||
|
public Book(String title, String author, long isbn) {
|
||||||
|
this.title = title;
|
||||||
|
this.author = author;
|
||||||
|
this.isbn = isbn;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.bookstore;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class LibraryAdmin {
|
||||||
|
|
||||||
|
public Book createBook(String title, String author) {
|
||||||
|
|
||||||
|
final long isbn = new Random().nextLong();
|
||||||
|
|
||||||
|
return new Book(title, author, isbn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
<version>${commons-codec.version}</version>
|
<version>${commons-codec.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-codec.version>1.15</commons-codec.version>
|
<commons-codec.version>1.15</commons-codec.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -8,4 +8,5 @@ This module contains articles about networking in Java
|
||||||
- [Downloading Email Attachments in Java](https://www.baeldung.com/java-download-email-attachments)
|
- [Downloading Email Attachments in Java](https://www.baeldung.com/java-download-email-attachments)
|
||||||
- [Connection Timeout vs. Read Timeout for Java Sockets](https://www.baeldung.com/java-socket-connection-read-timeout)
|
- [Connection Timeout vs. Read Timeout for Java Sockets](https://www.baeldung.com/java-socket-connection-read-timeout)
|
||||||
- [Find Whether an IP Address Is in the Specified Range or Not in Java](https://www.baeldung.com/java-check-ip-address-range)
|
- [Find Whether an IP Address Is in the Specified Range or Not in Java](https://www.baeldung.com/java-check-ip-address-range)
|
||||||
|
- [Find the IP Address of a Client Connected to a Server](https://www.baeldung.com/java-client-get-ip-address)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-networking-2)
|
- [[<-- Prev]](/core-java-modules/core-java-networking-2)
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.baeldung.clientaddress;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class ApplicationClient {
|
||||||
|
|
||||||
|
private Socket clientSocket;
|
||||||
|
private PrintWriter out;
|
||||||
|
private BufferedReader in;
|
||||||
|
|
||||||
|
public void connect(String ip, int port) throws IOException {
|
||||||
|
clientSocket = new Socket(ip, port);
|
||||||
|
out = new PrintWriter(clientSocket.getOutputStream(), true);
|
||||||
|
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendGreetings(String msg) throws IOException {
|
||||||
|
out.println(msg);
|
||||||
|
String reply = in.readLine();
|
||||||
|
System.out.println("Reply received from the server :: " + reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() throws IOException {
|
||||||
|
in.close();
|
||||||
|
out.close();
|
||||||
|
clientSocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
ApplicationClient client = new ApplicationClient();
|
||||||
|
client.connect(args[0], Integer.parseInt(args[1])); // IP address and port number of the server
|
||||||
|
client.sendGreetings(args[2]); // greetings message
|
||||||
|
client.disconnect();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.clientaddress;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class ApplicationServer {
|
||||||
|
|
||||||
|
private ServerSocket serverSocket;
|
||||||
|
private Socket connectedSocket;
|
||||||
|
private PrintWriter out;
|
||||||
|
private BufferedReader in;
|
||||||
|
|
||||||
|
public void startServer(int port) throws IOException {
|
||||||
|
serverSocket = new ServerSocket(port);
|
||||||
|
connectedSocket = serverSocket.accept();
|
||||||
|
|
||||||
|
InetSocketAddress socketAddress = (InetSocketAddress) connectedSocket.getRemoteSocketAddress();
|
||||||
|
String clientIpAddress = socketAddress.getAddress()
|
||||||
|
.getHostAddress();
|
||||||
|
System.out.println("IP address of the connected client :: " + clientIpAddress);
|
||||||
|
|
||||||
|
out = new PrintWriter(connectedSocket.getOutputStream(), true);
|
||||||
|
in = new BufferedReader(new InputStreamReader(connectedSocket.getInputStream()));
|
||||||
|
String msg = in.readLine();
|
||||||
|
System.out.println("Message received from the client :: " + msg);
|
||||||
|
out.println("Hello Client !!");
|
||||||
|
|
||||||
|
closeIO();
|
||||||
|
stopServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeIO() throws IOException {
|
||||||
|
in.close();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopServer() throws IOException {
|
||||||
|
connectedSocket.close();
|
||||||
|
serverSocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
ApplicationServer server = new ApplicationServer();
|
||||||
|
server.startServer(5000);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,5 +13,6 @@ This module contains articles about working with the operating system (OS) in Ja
|
||||||
- [Pattern Search with Grep in Java](http://www.baeldung.com/grep-in-java)
|
- [Pattern Search with Grep in Java](http://www.baeldung.com/grep-in-java)
|
||||||
- [How to Run a Shell Command in Java](http://www.baeldung.com/run-shell-command-in-java)
|
- [How to Run a Shell Command in Java](http://www.baeldung.com/run-shell-command-in-java)
|
||||||
- [Taking Screenshots Using Java](https://www.baeldung.com/java-taking-screenshots)
|
- [Taking Screenshots Using Java](https://www.baeldung.com/java-taking-screenshots)
|
||||||
|
- [Java Sound API – Capturing Microphone](https://www.baeldung.com/java-sound-api-capture-mic)
|
||||||
|
|
||||||
This module uses Java 9, so make sure to have the JDK 9 installed to run it.
|
This module uses Java 9, so make sure to have the JDK 9 installed to run it.
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit-jupiter-engine.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-collections4</artifactId>
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
@ -88,6 +94,7 @@
|
||||||
<guava.version>25.1-jre</guava.version>
|
<guava.version>25.1-jre</guava.version>
|
||||||
<unix4j.version>0.4</unix4j.version>
|
<unix4j.version>0.4</unix4j.version>
|
||||||
<grep4j.version>1.8.7</grep4j.version>
|
<grep4j.version>1.8.7</grep4j.version>
|
||||||
|
<junit-jupiter-engine.version>5.7.2</junit-jupiter-engine.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.example.soundapi;
|
||||||
|
|
||||||
|
import javax.sound.sampled.AudioFileFormat;
|
||||||
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
AudioFormat format = buildAudioFormatInstance();
|
||||||
|
|
||||||
|
SoundRecorder soundRecorder = new SoundRecorder();
|
||||||
|
soundRecorder.build(format);
|
||||||
|
|
||||||
|
System.out.println("Start recording ....");
|
||||||
|
soundRecorder.start();
|
||||||
|
Thread.sleep(20000);
|
||||||
|
soundRecorder.stop();
|
||||||
|
|
||||||
|
WaveDataUtil wd = new WaveDataUtil();
|
||||||
|
Thread.sleep(3000);
|
||||||
|
wd.saveToFile("/SoundClip", AudioFileFormat.Type.WAVE, soundRecorder.getAudioInputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AudioFormat buildAudioFormatInstance() {
|
||||||
|
ApplicationProperties aConstants = new ApplicationProperties();
|
||||||
|
AudioFormat.Encoding encoding = aConstants.ENCODING;
|
||||||
|
float rate = aConstants.RATE;
|
||||||
|
int channels = aConstants.CHANNELS;
|
||||||
|
int sampleSize = aConstants.SAMPLE_SIZE;
|
||||||
|
boolean bigEndian = aConstants.BIG_ENDIAN;
|
||||||
|
|
||||||
|
return new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8) * channels, rate, bigEndian);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.baeldung.example.soundapi;
|
||||||
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
|
||||||
|
public class ApplicationProperties {
|
||||||
|
public final AudioFormat.Encoding ENCODING = AudioFormat.Encoding.PCM_SIGNED;
|
||||||
|
public final float RATE = 44100.0f;
|
||||||
|
public final int CHANNELS = 1;
|
||||||
|
public final int SAMPLE_SIZE = 16;
|
||||||
|
public final boolean BIG_ENDIAN = true;
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
package com.baeldung.example.soundapi;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
import javax.sound.sampled.AudioInputStream;
|
||||||
|
import javax.sound.sampled.AudioSystem;
|
||||||
|
import javax.sound.sampled.DataLine;
|
||||||
|
import javax.sound.sampled.TargetDataLine;
|
||||||
|
|
||||||
|
public class SoundRecorder implements Runnable {
|
||||||
|
private AudioInputStream audioInputStream;
|
||||||
|
private AudioFormat format;
|
||||||
|
public Thread thread;
|
||||||
|
private double duration;
|
||||||
|
|
||||||
|
public SoundRecorder() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundRecorder(AudioFormat format) {
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundRecorder build(AudioFormat format) {
|
||||||
|
this.format = format;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
thread = new Thread(this);
|
||||||
|
thread.setName("Capture Microphone");
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
thread = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
duration = 0;
|
||||||
|
|
||||||
|
try (final ByteArrayOutputStream out = new ByteArrayOutputStream(); final TargetDataLine line = getTargetDataLineForRecord();) {
|
||||||
|
|
||||||
|
int frameSizeInBytes = format.getFrameSize();
|
||||||
|
int bufferLengthInFrames = line.getBufferSize() / 8;
|
||||||
|
final int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
|
||||||
|
buildByteOutputStream(out, line, frameSizeInBytes, bufferLengthInBytes);
|
||||||
|
this.audioInputStream = new AudioInputStream(line);
|
||||||
|
setAudioInputStream(convertToAudioIStream(out, frameSizeInBytes));
|
||||||
|
audioInputStream.reset();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buildByteOutputStream(final ByteArrayOutputStream out, final TargetDataLine line, int frameSizeInBytes, final int bufferLengthInBytes) throws IOException {
|
||||||
|
final byte[] data = new byte[bufferLengthInBytes];
|
||||||
|
int numBytesRead;
|
||||||
|
|
||||||
|
line.start();
|
||||||
|
while (thread != null) {
|
||||||
|
if ((numBytesRead = line.read(data, 0, bufferLengthInBytes)) == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out.write(data, 0, numBytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAudioInputStream(AudioInputStream aStream) {
|
||||||
|
this.audioInputStream = aStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AudioInputStream convertToAudioIStream(final ByteArrayOutputStream out, int frameSizeInBytes) {
|
||||||
|
byte audioBytes[] = out.toByteArray();
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(audioBytes);
|
||||||
|
AudioInputStream audioStream = new AudioInputStream(bais, format, audioBytes.length / frameSizeInBytes);
|
||||||
|
long milliseconds = (long) ((audioInputStream.getFrameLength() * 1000) / format.getFrameRate());
|
||||||
|
duration = milliseconds / 1000.0;
|
||||||
|
System.out.println("Recorded duration in seconds:" + duration);
|
||||||
|
return audioStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TargetDataLine getTargetDataLineForRecord() {
|
||||||
|
TargetDataLine line;
|
||||||
|
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
|
||||||
|
if (!AudioSystem.isLineSupported(info)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
line = (TargetDataLine) AudioSystem.getLine(info);
|
||||||
|
line.open(format, line.getBufferSize());
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AudioInputStream getAudioInputStream() {
|
||||||
|
return audioInputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AudioFormat getFormat() {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFormat(AudioFormat format) {
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Thread getThread() {
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDuration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.example.soundapi;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import javax.sound.sampled.AudioFileFormat;
|
||||||
|
import javax.sound.sampled.AudioInputStream;
|
||||||
|
import javax.sound.sampled.AudioSystem;
|
||||||
|
|
||||||
|
public class WaveDataUtil {
|
||||||
|
public boolean saveToFile(String name, AudioFileFormat.Type fileType, AudioInputStream audioInputStream) {
|
||||||
|
System.out.println("Saving...");
|
||||||
|
if (null == name || null == fileType || audioInputStream == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
File myFile = new File(name + "." + fileType.getExtension());
|
||||||
|
try {
|
||||||
|
audioInputStream.reset();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
while (myFile.exists()) {
|
||||||
|
String temp = "" + i + myFile.getName();
|
||||||
|
myFile = new File(temp);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
AudioSystem.write(audioInputStream, fileType, myFile);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
System.out.println("Saved " + myFile.getAbsolutePath());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.baeldung.java9.process;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ProcessAPIEnhancements {
|
||||||
|
|
||||||
|
static Logger log = LoggerFactory.getLogger(ProcessAPIEnhancements.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
|
||||||
|
infoOfCurrentProcess();
|
||||||
|
infoOfLiveProcesses();
|
||||||
|
infoOfSpawnProcess();
|
||||||
|
infoOfExitCallback();
|
||||||
|
infoOfChildProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void infoOfCurrentProcess() {
|
||||||
|
ProcessHandle processHandle = ProcessHandle.current();
|
||||||
|
ProcessHandle.Info processInfo = processHandle.info();
|
||||||
|
|
||||||
|
log.info("PID: " + processHandle.pid());
|
||||||
|
log.info("Arguments: " + processInfo.arguments());
|
||||||
|
log.info("Command: " + processInfo.command());
|
||||||
|
log.info("Instant: " + processInfo.startInstant());
|
||||||
|
log.info("Total CPU duration: " + processInfo.totalCpuDuration());
|
||||||
|
log.info("User: " + processInfo.user());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void infoOfSpawnProcess() throws IOException {
|
||||||
|
|
||||||
|
String javaCmd = ProcessUtils.getJavaCmd().getAbsolutePath();
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder(javaCmd, "-version");
|
||||||
|
Process process = processBuilder.inheritIO().start();
|
||||||
|
ProcessHandle processHandle = process.toHandle();
|
||||||
|
ProcessHandle.Info processInfo = processHandle.info();
|
||||||
|
|
||||||
|
log.info("PID: " + processHandle.pid());
|
||||||
|
log.info("Arguments: " + processInfo.arguments());
|
||||||
|
log.info("Command: " + processInfo.command());
|
||||||
|
log.info("Instant: " + processInfo.startInstant());
|
||||||
|
log.info("Total CPU duration: " + processInfo.totalCpuDuration());
|
||||||
|
log.info("User: " + processInfo.user());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void infoOfLiveProcesses() {
|
||||||
|
Stream<ProcessHandle> liveProcesses = ProcessHandle.allProcesses();
|
||||||
|
liveProcesses.filter(ProcessHandle::isAlive)
|
||||||
|
.forEach(ph -> {
|
||||||
|
log.info("PID: " + ph.pid());
|
||||||
|
log.info("Instance: " + ph.info().startInstant());
|
||||||
|
log.info("User: " + ph.info().user());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void infoOfChildProcess() throws IOException {
|
||||||
|
int childProcessCount = 5;
|
||||||
|
for (int i = 0; i < childProcessCount; i++) {
|
||||||
|
String javaCmd = ProcessUtils.getJavaCmd()
|
||||||
|
.getAbsolutePath();
|
||||||
|
ProcessBuilder processBuilder
|
||||||
|
= new ProcessBuilder(javaCmd, "-version");
|
||||||
|
processBuilder.inheritIO().start();
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<ProcessHandle> children = ProcessHandle.current()
|
||||||
|
.children();
|
||||||
|
children.filter(ProcessHandle::isAlive)
|
||||||
|
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
|
||||||
|
.command()));
|
||||||
|
Stream<ProcessHandle> descendants = ProcessHandle.current()
|
||||||
|
.descendants();
|
||||||
|
descendants.filter(ProcessHandle::isAlive)
|
||||||
|
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
|
||||||
|
.command()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void infoOfExitCallback() throws IOException, InterruptedException, ExecutionException {
|
||||||
|
String javaCmd = ProcessUtils.getJavaCmd()
|
||||||
|
.getAbsolutePath();
|
||||||
|
ProcessBuilder processBuilder
|
||||||
|
= new ProcessBuilder(javaCmd, "-version");
|
||||||
|
Process process = processBuilder.inheritIO()
|
||||||
|
.start();
|
||||||
|
ProcessHandle processHandle = process.toHandle();
|
||||||
|
|
||||||
|
log.info("PID: {} has started", processHandle.pid());
|
||||||
|
CompletableFuture<ProcessHandle> onProcessExit = processHandle.onExit();
|
||||||
|
onProcessExit.get();
|
||||||
|
log.info("Alive: " + processHandle.isAlive());
|
||||||
|
onProcessExit.thenAccept(ph -> {
|
||||||
|
log.info("PID: {} has stopped", ph.pid());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.baeldung.example.soundapi;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
import javax.sound.sampled.AudioFileFormat;
|
||||||
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
import javax.sound.sampled.TargetDataLine;
|
||||||
|
|
||||||
|
public class AppUnitTest {
|
||||||
|
|
||||||
|
AudioFormat af = App.buildAudioFormatInstance();
|
||||||
|
SoundRecorder soundRecorder = new SoundRecorder();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void Given_SoundRecorderObject_When_Run_Then_ThrowsNoException() {
|
||||||
|
|
||||||
|
soundRecorder.build(af);
|
||||||
|
try {
|
||||||
|
soundRecorder.start();
|
||||||
|
Thread.sleep(20000);
|
||||||
|
soundRecorder.stop();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
fail("Exception: " + ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void Given_AudioFormatObject_When_NotNull_Then_ReturnsTargetDataLine() {
|
||||||
|
soundRecorder.setFormat(af);
|
||||||
|
Assertions.assertDoesNotThrow(() -> soundRecorder.getTargetDataLineForRecord());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void Given_TargetLineDataObject_When_Run_Then_GeneratesOutputStream() {
|
||||||
|
|
||||||
|
soundRecorder.setFormat(af);
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
TargetDataLine tLine = soundRecorder.getTargetDataLineForRecord();
|
||||||
|
|
||||||
|
int frameSizeInBytes = af.getFrameSize();
|
||||||
|
int bufferLengthInFrames = tLine.getBufferSize() / 8;
|
||||||
|
final int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
|
||||||
|
|
||||||
|
Assertions.assertDoesNotThrow(
|
||||||
|
() -> soundRecorder.buildByteOutputStream(out, tLine, frameSizeInBytes, bufferLengthInBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void Given_AudioInputStream_When_NotNull_Then_SaveToWavFile() {
|
||||||
|
soundRecorder.setFormat(af);
|
||||||
|
soundRecorder.build(af);
|
||||||
|
try {
|
||||||
|
soundRecorder.start();
|
||||||
|
Thread.sleep(20000);
|
||||||
|
soundRecorder.stop();
|
||||||
|
WaveDataUtil wd = new WaveDataUtil();
|
||||||
|
Thread.sleep(3000);
|
||||||
|
boolean saveFile = wd.saveToFile("/SoundClip", AudioFileFormat.Type.WAVE,
|
||||||
|
soundRecorder.getAudioInputStream());
|
||||||
|
|
||||||
|
assertEquals(saveFile, true);
|
||||||
|
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
fail("Exception: " + ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,132 +0,0 @@
|
||||||
package com.baeldung.java9.process;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by sanaulla on 2/23/2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ProcessAPIEnhancementsUnitTest {
|
|
||||||
|
|
||||||
Logger log = LoggerFactory.getLogger(ProcessAPIEnhancementsUnitTest.class);
|
|
||||||
|
|
||||||
// @Test
|
|
||||||
// OS / Java version dependent
|
|
||||||
public void givenCurrentProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
|
|
||||||
ProcessHandle processHandle = ProcessHandle.current();
|
|
||||||
ProcessHandle.Info processInfo = processHandle.info();
|
|
||||||
assertNotNull(processHandle.pid());
|
|
||||||
assertEquals(true, processInfo.arguments()
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(true, processInfo.command()
|
|
||||||
.isPresent());
|
|
||||||
assertTrue(processInfo.command()
|
|
||||||
.get()
|
|
||||||
.contains("java"));
|
|
||||||
|
|
||||||
assertEquals(true, processInfo.startInstant()
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(true, processInfo.totalCpuDuration()
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(true, processInfo.user()
|
|
||||||
.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Test
|
|
||||||
// OS / Java version dependent
|
|
||||||
public void givenSpawnProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
|
|
||||||
|
|
||||||
String javaCmd = ProcessUtils.getJavaCmd()
|
|
||||||
.getAbsolutePath();
|
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(javaCmd, "-version");
|
|
||||||
Process process = processBuilder.inheritIO()
|
|
||||||
.start();
|
|
||||||
ProcessHandle processHandle = process.toHandle();
|
|
||||||
ProcessHandle.Info processInfo = processHandle.info();
|
|
||||||
assertNotNull(processHandle.pid());
|
|
||||||
assertEquals(true, processInfo.arguments()
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(true, processInfo.command()
|
|
||||||
.isPresent());
|
|
||||||
assertTrue(processInfo.command()
|
|
||||||
.get()
|
|
||||||
.contains("java"));
|
|
||||||
assertEquals(true, processInfo.startInstant()
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(false, processInfo.totalCpuDuration()
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(true, processInfo.user()
|
|
||||||
.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Test
|
|
||||||
// OS / Java version dependent
|
|
||||||
public void givenLiveProcesses_whenInvokeGetInfo_thenSuccess() {
|
|
||||||
Stream<ProcessHandle> liveProcesses = ProcessHandle.allProcesses();
|
|
||||||
liveProcesses.filter(ProcessHandle::isAlive)
|
|
||||||
.forEach(ph -> {
|
|
||||||
assertNotNull(ph.pid());
|
|
||||||
assertEquals(true, ph.info()
|
|
||||||
.startInstant()
|
|
||||||
.isPresent());
|
|
||||||
assertEquals(true, ph.info()
|
|
||||||
.user()
|
|
||||||
.isPresent());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Test
|
|
||||||
// OS / Java version dependent
|
|
||||||
public void givenProcess_whenGetChildProcess_thenSuccess() throws IOException {
|
|
||||||
int childProcessCount = 5;
|
|
||||||
for (int i = 0; i < childProcessCount; i++) {
|
|
||||||
String javaCmd = ProcessUtils.getJavaCmd()
|
|
||||||
.getAbsolutePath();
|
|
||||||
ProcessBuilder processBuilder
|
|
||||||
= new ProcessBuilder(javaCmd, "-version");
|
|
||||||
processBuilder.inheritIO().start();
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<ProcessHandle> children = ProcessHandle.current()
|
|
||||||
.children();
|
|
||||||
children.filter(ProcessHandle::isAlive)
|
|
||||||
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
|
|
||||||
.command()));
|
|
||||||
Stream<ProcessHandle> descendants = ProcessHandle.current()
|
|
||||||
.descendants();
|
|
||||||
descendants.filter(ProcessHandle::isAlive)
|
|
||||||
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
|
|
||||||
.command()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Test
|
|
||||||
// OS / Java version dependent
|
|
||||||
public void givenProcess_whenAddExitCallback_thenSuccess() throws Exception {
|
|
||||||
String javaCmd = ProcessUtils.getJavaCmd()
|
|
||||||
.getAbsolutePath();
|
|
||||||
ProcessBuilder processBuilder
|
|
||||||
= new ProcessBuilder(javaCmd, "-version");
|
|
||||||
Process process = processBuilder.inheritIO()
|
|
||||||
.start();
|
|
||||||
ProcessHandle processHandle = process.toHandle();
|
|
||||||
|
|
||||||
log.info("PID: {} has started", processHandle.pid());
|
|
||||||
CompletableFuture<ProcessHandle> onProcessExit = processHandle.onExit();
|
|
||||||
onProcessExit.get();
|
|
||||||
assertEquals(false, processHandle.isAlive());
|
|
||||||
onProcessExit.thenAccept(ph -> {
|
|
||||||
log.info("PID: {} has stopped", ph.pid());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,4 +5,5 @@ This module contains articles about core Java Security
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Secret Key and String Conversion in Java](https://www.baeldung.com/java-secret-key-to-string)
|
- [Secret Key and String Conversion in Java](https://www.baeldung.com/java-secret-key-to-string)
|
||||||
|
- [Enabling Unlimited Strength Cryptography in Java](https://www.baeldung.com/jce-enable-unlimited-strength)
|
||||||
- More articles: [[<-- prev]](/core-java-modules/core-java-security-2)
|
- More articles: [[<-- prev]](/core-java-modules/core-java-security-2)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.cryptography;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class CryptographyStrengthUnitTest {
|
||||||
|
private static final int UNLIMITED_KEY_SIZE = 2147483647;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDefaultCheck_thenUnlimitedReturned() throws NoSuchAlgorithmException {
|
||||||
|
int maxKeySize = javax.crypto.Cipher.getMaxAllowedKeyLength("AES");
|
||||||
|
assertThat(maxKeySize).isEqualTo(UNLIMITED_KEY_SIZE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,11 @@
|
||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-validator</groupId>
|
||||||
|
<artifactId>commons-validator</artifactId>
|
||||||
|
<version>${validator.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -59,6 +64,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
<guava.version>28.1-jre</guava.version>
|
<guava.version>28.1-jre</guava.version>
|
||||||
|
<validator.version>1.7</validator.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.emailvalidation;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class EmailValidation {
|
||||||
|
|
||||||
|
public static boolean patternMatches(String emailAddress, String regexPattern) {
|
||||||
|
return Pattern.compile(regexPattern)
|
||||||
|
.matcher(emailAddress)
|
||||||
|
.matches();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.baeldung.emailvalidation;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.apache.commons.validator.routines.EmailValidator;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class EmailValidationUnitTest {
|
||||||
|
|
||||||
|
private String emailAddress;
|
||||||
|
private String regexPattern;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUsingEmailValidator() {
|
||||||
|
emailAddress = "username@domain.com";
|
||||||
|
assertTrue(EmailValidator.getInstance()
|
||||||
|
.isValid(emailAddress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUsingSimpleRegex() {
|
||||||
|
emailAddress = "username@domain.com";
|
||||||
|
regexPattern = "^(.+)@(\\S+)$";
|
||||||
|
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUsingStrictRegex() {
|
||||||
|
emailAddress = "username@domain.com";
|
||||||
|
regexPattern = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@"
|
||||||
|
+ "[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
|
||||||
|
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUsingUnicodeRegex() {
|
||||||
|
emailAddress = "用户名@领域.电脑";
|
||||||
|
regexPattern = "^(?=.{1,64}@)[\\p{L}0-9_-]+(\\.[\\p{L}0-9_-]+)*@"
|
||||||
|
+ "[^-][\\p{L}0-9-]+(\\.[\\p{L}0-9-]+)*(\\.[\\p{L}]{2,})$";
|
||||||
|
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUsingRFC5322Regex() {
|
||||||
|
emailAddress = "username@domain.com";
|
||||||
|
regexPattern = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$";
|
||||||
|
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRestrictDots() {
|
||||||
|
emailAddress = "username@domain.com";
|
||||||
|
regexPattern = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@"
|
||||||
|
+ "[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$";
|
||||||
|
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOwaspValidation() {
|
||||||
|
emailAddress = "username@domain.com";
|
||||||
|
regexPattern = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
|
||||||
|
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTopLevelDomain() {
|
||||||
|
emailAddress = "username@domain.com";
|
||||||
|
regexPattern = "^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*"
|
||||||
|
+ "@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$";
|
||||||
|
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGmailSpecialCase() {
|
||||||
|
emailAddress = "username+something@domain.com";
|
||||||
|
regexPattern = "^(?=.{1,64}@)[A-Za-z0-9\\+_-]+(\\.[A-Za-z0-9\\+_-]+)*@"
|
||||||
|
+ "[^-][A-Za-z0-9\\+-]+(\\.[A-Za-z0-9\\+-]+)*(\\.[A-Za-z]{2,})$";
|
||||||
|
assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,3 +5,4 @@
|
||||||
- [Split Java String by Newline](https://www.baeldung.com/java-string-split-by-newline)
|
- [Split Java String by Newline](https://www.baeldung.com/java-string-split-by-newline)
|
||||||
- [Split a String in Java and Keep the Delimiters](https://www.baeldung.com/java-split-string-keep-delimiters)
|
- [Split a String in Java and Keep the Delimiters](https://www.baeldung.com/java-split-string-keep-delimiters)
|
||||||
- [Validate String as Filename in Java](https://www.baeldung.com/java-validate-filename)
|
- [Validate String as Filename in Java](https://www.baeldung.com/java-validate-filename)
|
||||||
|
- [Count Spaces in a Java String](https://www.baeldung.com/java-string-count-spaces)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue