Merge branch 'eugenp:master' into master

This commit is contained in:
Wynn Teo
2024-04-05 09:10:23 +08:00
committed by GitHub
313 changed files with 3304 additions and 1715 deletions
@@ -5,6 +5,18 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>algorithms-miscellaneous-5</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
<name>algorithms-miscellaneous-5</name>
<parent>
@@ -1,15 +1,12 @@
package com.baeldung.algorithms.conversion;
import java.math.BigInteger;
import com.google.common.io.BaseEncoding;
import jakarta.xml.bind.DatatypeConverter;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import com.google.common.io.BaseEncoding;
import jakarta.xml.bind.DatatypeConverter;
import java.math.BigInteger;
import java.util.HexFormat;
public class HexStringConverter {
@@ -109,4 +106,14 @@ public class HexStringConverter {
return BaseEncoding.base16()
.decode(hexString.toUpperCase());
}
public String encodeUsingHexFormat(byte[] bytes) {
HexFormat hexFormat = HexFormat.of();
return hexFormat.formatHex(bytes);
}
public byte[] decodeUsingHexFormat(String hexString) {
HexFormat hexFormat = HexFormat.of();
return hexFormat.parseHex(hexString);
}
}
@@ -1,15 +1,13 @@
package com.baeldung.algorithms.conversion;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.apache.commons.codec.DecoderException;
import org.hamcrest.text.IsEqualIgnoringCase;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.baeldung.algorithms.conversion.HexStringConverter;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class ByteArrayConverterUnitTest {
@@ -24,7 +22,7 @@ class ByteArrayConverterUnitTest {
void shouldEncodeByteArrayToHexStringUsingBigIntegerToString() {
byte[] bytes = getSampleBytes();
String hexString = getSampleHexString();
if(hexString.charAt(0) == '0') {
if (hexString.charAt(0) == '0') {
hexString = hexString.substring(1);
}
String output = hexStringConverter.encodeUsingBigIntegerToString(bytes);
@@ -46,7 +44,7 @@ class ByteArrayConverterUnitTest {
byte[] output = hexStringConverter.decodeUsingBigInteger(hexString);
assertArrayEquals(bytes, output);
}
@Test
void shouldEncodeByteArrayToHexStringUsingCharacterConversion() {
byte[] bytes = getSampleBytes();
@@ -62,7 +60,7 @@ class ByteArrayConverterUnitTest {
byte[] output = hexStringConverter.decodeHexString(hexString);
assertArrayEquals(bytes, output);
}
@Test
void shouldDecodeHexToByteWithInvalidHexCharacter() {
assertThrows(IllegalArgumentException.class, () -> {
@@ -118,12 +116,28 @@ class ByteArrayConverterUnitTest {
assertArrayEquals(bytes, output);
}
@Test
void shouldEncodeByteArrayToHexStringUsingHexFormat() throws DecoderException {
byte[] bytes = getSampleBytes();
String hexString = getSampleHexString();
String output = hexStringConverter.encodeUsingHexFormat(bytes);
assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString));
}
@Test
void shouldDecodeHexStringToByteArrayUsingHexFormat() throws DecoderException {
byte[] bytes = getSampleBytes();
String hexString = getSampleHexString();
byte[] output = hexStringConverter.decodeUsingHexFormat(hexString);
assertArrayEquals(bytes, output);
}
private String getSampleHexString() {
return "0af50c0e2d10";
}
private byte[] getSampleBytes() {
return new byte[] { 10, -11, 12, 14, 45, 16 };
return new byte[]{10, -11, 12, 14, 45, 16};
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 160 KiB

@@ -0,0 +1,3 @@
### Relevant Articles:
- [Vigenère Cipher in Java](https://www.baeldung.com/java-vigenere-cipher)
- [Merge Overlapping Intervals in a Java Collection](https://www.baeldung.com/java-collection-merge-overlapping-intervals)
@@ -0,0 +1,37 @@
package com.baeldung.algorithms.mergeintervals;
import java.util.Objects;
public class Interval {
int start;
int end;
Interval(int start, int end) {
this.start = start;
this.end = end;
}
public void setEnd(int end) {
this.end = end;
}
@Override
public String toString() {
return "Interval{" + "start=" + start + ", end=" + end + '}';
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Interval interval = (Interval) o;
return start == interval.start && end == interval.end;
}
@Override
public int hashCode() {
return Objects.hash(start, end);
}
}
@@ -0,0 +1,29 @@
package com.baeldung.algorithms.mergeintervals;
import java.util.ArrayList;
import java.util.List;
public class MergeOverlappingIntervals {
public List<Interval> doMerge(List<Interval> intervals) {
// Sort the intervals based on start time
intervals.sort((one, two) -> one.start - two.start);
// Create somewhere to put the merged list, start it off with the earliest starting interval
ArrayList<Interval> merged = new ArrayList<>();
merged.add(intervals.get(0));
// Loop over each interval and merge if start time is before the end time of the
// previous interval
intervals.forEach(interval -> {
if (merged.get(merged.size() - 1).end > interval.start) {
merged.get(merged.size() - 1).setEnd(interval.end);
} else {
merged.add(interval);
}
});
return merged;
}
}
@@ -0,0 +1,11 @@
package com.baeldung.algorithms.skiplist;
class Node {
int value;
Node[] forward; // array to hold references to different levels
public Node(int value, int level) {
this.value = value;
this.forward = new Node[level + 1]; // level + 1 because level is 0-based
}
}
@@ -0,0 +1,92 @@
package com.baeldung.algorithms.skiplist;
import java.util.Random;
public class SkipList {
private Node head;
private int maxLevel;
private int level;
private Random random;
public SkipList() {
maxLevel = 16; // maximum number of levels
level = 0; // current level of SkipList
head = new Node(Integer.MIN_VALUE, maxLevel);
random = new Random();
}
public void insert(int value) {
Node[] update = new Node[maxLevel + 1];
Node current = this.head;
for (int i = level; i >= 0; i--) {
while (current.forward[i] != null && current.forward[i].value < value) {
current = current.forward[i];
}
update[i] = current;
}
current = current.forward[0];
if (current == null || current.value != value) {
int lvl = randomLevel();
if (lvl > level) {
for (int i = level + 1; i <= lvl; i++) {
update[i] = head;
}
level = lvl;
}
Node newNode = new Node(value, lvl);
for (int i = 0; i <= lvl; i++) {
newNode.forward[i] = update[i].forward[i];
update[i].forward[i] = newNode;
}
}
}
public boolean search(int value) {
Node current = this.head;
for (int i = level; i >= 0; i--) {
while (current.forward[i] != null && current.forward[i].value < value) {
current = current.forward[i];
}
}
current = current.forward[0];
return current != null && current.value == value;
}
public void delete(int value) {
Node[] update = new Node[maxLevel + 1];
Node current = this.head;
for (int i = level; i >= 0; i--) {
while (current.forward[i] != null && current.forward[i].value < value) {
current = current.forward[i];
}
update[i] = current;
}
current = current.forward[0];
if (current != null && current.value == value) {
for (int i = 0; i <= level; i++) {
if (update[i].forward[i] != current) break;
update[i].forward[i] = current.forward[i];
}
while (level > 0 && head.forward[level] == null) {
level--;
}
}
}
private int randomLevel() {
int lvl = 0;
while (lvl < maxLevel && random.nextDouble() < 0.5) {
lvl++;
}
return lvl;
}
}
@@ -0,0 +1,30 @@
package com.baeldung.algorithms.mergeintervals;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import java.util.ArrayList;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
class MergeIntervalsUnitTest {
private ArrayList<Interval> intervals = new ArrayList<>(Arrays.asList(
new Interval(2, 5),
new Interval(13, 20),
new Interval(11, 15),
new Interval(1, 3)
));
private ArrayList<Interval> intervalsMerged = new ArrayList<>(Arrays.asList(
new Interval(1, 5),
new Interval(11, 20)
));
@Test
void givenIntervals_whenMerging_thenReturnMergedIntervals() {
MergeOverlappingIntervals merger = new MergeOverlappingIntervals();
ArrayList<Interval> result = (ArrayList<Interval>) merger.doMerge(intervals);
assertArrayEquals(intervalsMerged.toArray(), result.toArray());
}
}
@@ -0,0 +1,34 @@
package com.baeldung.algorithms.skiplist;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class SkipListUnitTest {
@Test
public void givenSkipList_WhenInsert_ThenSearchFound() {
SkipList skipList = new SkipList();
skipList.insert(3);
assertTrue(skipList.search(3), "Should find 3");
assertFalse(skipList.search(99), "Should not find 99");
}
@Test
public void givenSkipList_WhenDeleteElement_ThenRemoveFromList() {
SkipList skipList = new SkipList();
skipList.insert(3);
skipList.insert(7);
skipList.delete(3);
assertFalse(skipList.search(3), "3 should have been deleted");
skipList.delete(99);
assertTrue(skipList.search(7), "7 should still exist");
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
## Relevant Articles
- [Understanding XSLT Processing in Java](https://www.baeldung.com/java-extensible-stylesheet-language-transformations)
- [Add Camel Route at Runtime in Java](https://www.baeldung.com/java-camel-dynamic-route)
- [Logging in Apache Camel](https://www.baeldung.com/java-apache-camel-logging)
- More articles: [[<-- prev]](../apache-libraries)
@@ -0,0 +1 @@
Welcome to Baeldung
+4
View File
@@ -0,0 +1,4 @@
{
"name" : "phillip",
"age" : 5
}
@@ -0,0 +1 @@
WELCOME TO BAELDUNG
+1
View File
@@ -0,0 +1 @@
{"name":"phillip","age":5,"transformedName":"PHILLIP","transformedAge":15}
+6 -1
View File
@@ -35,11 +35,16 @@
<artifactId>camel-main</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jackson</artifactId>
<version>${camel.version}</version>
</dependency>
</dependencies>
<properties>
<javax.validation.validation-api.version>2.0.1.Final</javax.validation.validation-api.version>
<camel.version>4.3.0</camel.version>
<camel.version>4.4.1</camel.version>
</properties>
</project>
@@ -0,0 +1,13 @@
package com.baeldung.apachecamellogging;
import org.apache.camel.main.Main;
public class CamelLoggingMainApp {
public static void main(String[] args) throws Exception {
Main main = new Main();
main.configure()
.addRoutesBuilder(new FileCopierCamelRoute());
main.run(args);
}
}
@@ -0,0 +1,25 @@
package com.baeldung.apachecamellogging;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileCopierCamelRoute extends RouteBuilder {
private static final Logger LOGGER = LoggerFactory.getLogger(FileCopierCamelRoute.class);
public void configure() {
from("file:data/inbox?noop=true").log("We got an incoming file ${file:name} containing: ${body}")
.to("log:com.baeldung.apachecamellogging?level=INFO")
.process(process -> {
LOGGER.info("We are passing the message to a FileProcesor bean to capitalize the message body");
})
.bean(FileProcessor.class)
.to("file:data/outbox")
.to("log:com.baeldung.apachecamellogging?showBodyType=false&maxChars=20")
.log(LoggingLevel.DEBUG, "Output Process", "The Process ${id}")
.log("Successfully transfer file: ${file:name}");
}
}
@@ -0,0 +1,22 @@
package com.baeldung.apachecamellogging;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.dataformat.JsonLibrary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileCopierTracerCamelRoute extends RouteBuilder {
Logger logger = LoggerFactory.getLogger(FileCopierTracerCamelRoute.class);
public void configure() {
getContext().setTracing(true);
from("file:data/json?noop=true").to("log:input?level=INFO")
.unmarshal()
.json(JsonLibrary.Jackson)
.bean(FileProcessor.class, "transform")
.marshal()
.json(JsonLibrary.Jackson)
.to("file:data/output");
}
}
@@ -0,0 +1,23 @@
package com.baeldung.apachecamellogging;
import org.apache.camel.Body;
import java.util.Map;
public class FileProcessor {
public String process(@Body String fileContent) {
String processedContent = fileContent.toUpperCase();
return processedContent;
}
public Map<String, Object> transform(Map<String, Object> input) {
String name = (String) input.get("name");
int age = (int) input.get("age");
input.put("transformedName", name.toUpperCase());
input.put("transformedAge", age + 10);
return input;
}
}
@@ -1,4 +1,4 @@
package dynamicrouter;
package com.baeldung.dynamicrouter;
import com.baeldung.dynamicrouter.DynamicRouterRoute;
import org.apache.camel.RoutesBuilder;
@@ -0,0 +1,44 @@
package com.baeldung.inetspi;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.stream.Stream;
import com.baeldung.inetspi.providers.CustomAddressResolverImpl;
public class InetAddressSPI {
public String usingGetByName(String host) throws UnknownHostException {
InetAddress inetAddress = InetAddress.getByName(host);
return inetAddress.getHostAddress();
}
public String[] usingGetAllByName(String host) throws UnknownHostException {
InetAddress[] inetAddresses = InetAddress.getAllByName(host);
return Arrays.stream(inetAddresses).map(InetAddress::getHostAddress).toArray(String[]::new);
}
public String usingGetByIp(byte[] ip) throws UnknownHostException {
InetAddress inetAddress = InetAddress.getByAddress(ip);
return inetAddress.getHostName();
}
public String usingGetByIpAndReturnsCannonName(byte[] ip) throws UnknownHostException {
InetAddress inetAddress = InetAddress.getByAddress(ip);
return inetAddress.getCanonicalHostName();
}
public String getHostUsingCustomImpl(byte[] ip) throws UnknownHostException {
CustomAddressResolverImpl imp = new CustomAddressResolverImpl();
return imp.get(null).lookupByAddress(ip);
}
public Stream<InetAddress> getIpUsingCustomImpl(String host) throws UnknownHostException {
CustomAddressResolverImpl imp = new CustomAddressResolverImpl();
return imp.get(null).lookupByName(host, null);
}
}
@@ -0,0 +1,56 @@
package com.baeldung.inetspi;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.stream.Stream;
public class Registry {
private final Map<String, List<byte[]>> registry;
private static final Logger LOGGER = Logger.getLogger(Registry.class.getName());
public Registry() {
registry = loadMapWithData();
}
public Stream<InetAddress> getAddressesfromHost(String host) throws UnknownHostException {
LOGGER.info("Performing Forward Lookup for HOST : " + host);
if (!registry.containsKey(host)) {
throw new UnknownHostException("Missing Host information in Resolver");
}
return registry.get(host)
.stream()
.map(add -> constructInetAddress(host, add))
.filter(Objects::nonNull);
}
public String getHostFromAddress(byte[] arr) throws UnknownHostException {
LOGGER.info("Performing Reverse Lookup for Address : " + Arrays.toString(arr));
for (Map.Entry<String, List<byte[]>> entry : registry.entrySet()) {
if (entry.getValue()
.stream()
.anyMatch(ba -> Arrays.equals(ba, arr))) {
return entry.getKey();
}
}
throw new UnknownHostException("Address Not Found");
}
private Map<String, List<byte[]>> loadMapWithData() {
return Map.of("baeldung-local.org", List.of(new byte[] { 1, 2, 3, 4 }));
}
private static InetAddress constructInetAddress(String host, byte[] address) {
try {
return InetAddress.getByAddress(host, address);
} catch (UnknownHostException unknownHostException) {
return null;
}
}
}
@@ -0,0 +1,42 @@
package com.baeldung.inetspi.providers;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.spi.InetAddressResolver;
import java.net.spi.InetAddressResolverProvider;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Stream;
import com.baeldung.inetspi.Registry;
public class CustomAddressResolverImpl extends InetAddressResolverProvider {
private static Logger LOGGER = Logger.getLogger(CustomAddressResolverImpl.class.getName());
private static Registry registry = new Registry();
@Override
public InetAddressResolver get(Configuration configuration) {
LOGGER.info("Using Custom Address Resolver :: " + this.name());
LOGGER.info("Registry initialised");
return new InetAddressResolver() {
@Override
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy) throws UnknownHostException {
return registry.getAddressesfromHost(host);
}
@Override
public String lookupByAddress(byte[] addr) throws UnknownHostException {
return registry.getHostFromAddress(addr);
}
};
}
@Override
public String name() {
return "CustomInternetAddressResolverImpl";
}
}
@@ -0,0 +1,31 @@
package com.baeldung.inetspi;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Test;
public class InetAddressSPIUnitTest {
@Test
public void givenInetAddress_whenUsingInetAddress_thenPerformResolution() throws UnknownHostException {
InetAddressSPI spi = new InetAddressSPI();
Assert.assertNotNull(spi.usingGetByName("www.google.com"));
Assert.assertTrue(spi.usingGetAllByName("www.google.com").length > 1);
Assert.assertNotNull(spi.usingGetByIp(InetAddress.getByName("www.google.com")
.getAddress()));
Assert.assertNotNull(spi.usingGetByIpAndReturnsCannonName(InetAddress.getByName("www.google.com")
.getAddress()));
}
@Test
public void givenCustomInetAddressImplementation_whenUsingInetAddress_thenPerformResolution() throws UnknownHostException {
InetAddressSPI spi = new InetAddressSPI();
Assert.assertEquals("baeldung-local.org", spi.getHostUsingCustomImpl(new byte[] { 1, 2, 3, 4 }));
Stream<InetAddress> response = spi.getIpUsingCustomImpl("baeldung-local.org");
Assert.assertArrayEquals(new byte[] { 1, 2, 3, 4 }, response.findFirst()
.get()
.getAddress());
}
}
@@ -0,0 +1,32 @@
package com.baeldung.java21;
public class PatternCaseLabels {
static String processInputOld(String input) {
String output;
switch (input) {
case null -> output = "Oops, null";
case String s -> {
if ("Yes".equalsIgnoreCase(s)) {
output = "It's Yes";
} else if ("No".equalsIgnoreCase(s)) {
output = "It's No";
} else {
output = "Try Again";
}
}
}
return output;
}
static String processInputNew(String input) {
String output;
switch (input) {
case null -> output = "Oops, null";
case String s when "Yes".equalsIgnoreCase(s) -> output = "It's Yes";
case String s when "No".equalsIgnoreCase(s) -> output = "It's No";
case String s -> output = "Try Again";
}
return output;
}
}
@@ -0,0 +1,36 @@
package com.baeldung.java21;
public class RecordPattern {
record Point(int x, int y) {}
public static int beforeRecordPattern(Object obj) {
int sum = 0;
if(obj instanceof Point p) {
int x = p.x();
int y = p.y();
sum = x+y;
}
return sum;
}
public static int afterRecordPattern(Object obj) {
if(obj instanceof Point(int x, int y)) {
return x+y;
}
return 0;
}
enum Color {RED, GREEN, BLUE}
record ColoredPoint(Point point, Color color) {}
record RandomPoint(ColoredPoint cp) {}
public static Color getRamdomPointColor(RandomPoint r) {
if(r instanceof RandomPoint(ColoredPoint cp)) {
return cp.color();
}
return null;
}
}
@@ -0,0 +1,9 @@
package com.baeldung.java21;
public class StringTemplates {
public String getStringTemplate() {
String name = "Baeldung";
return STR."Welcome to \{name}";
}
}
@@ -0,0 +1,56 @@
package com.baeldung.java21;
public class SwitchPattern {
static class Account{
double getBalance() {
return 0;
}
}
static class SavingsAccount extends Account {
@Override
double getBalance() {
return 100;
}
}
static class TermAccount extends Account {
@Override
double getBalance() {
return 1000;
}
}
static class CurrentAccount extends Account {
@Override
double getBalance() {
return 10000;
}
}
static double getBalanceWithOutSwitchPattern(Account account) {
double balance = 0;
if(account instanceof SavingsAccount sa) {
balance = sa.getBalance();
}
else if(account instanceof TermAccount ta) {
balance = ta.getBalance();
}
else if(account instanceof CurrentAccount ca) {
balance = ca.getBalance();
}
return balance;
}
static double getBalanceWithSwitchPattern(Account account) {
double result;
switch (account) {
case null -> throw new IllegalArgumentException("Oops, account is null");
case SavingsAccount sa -> result = sa.getBalance();
case TermAccount ta -> result = ta.getBalance();
case CurrentAccount ca -> result = ca.getBalance();
default -> result = account.getBalance();
}
return result;
}
}

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