Merge branch 'eugenp:master' into master
This commit is contained in:
commit
5929902b1c
@ -19,11 +19,6 @@
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
|
@ -29,11 +29,7 @@
|
||||
<artifactId>tradukisto</artifactId>
|
||||
<version>${tradukisto.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- API, java.xml.bind module -->
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
|
@ -7,4 +7,9 @@
|
||||
- [Rotate Arrays in Java](https://www.baeldung.com/java-rotate-arrays)
|
||||
- [Find Missing Number From a Given Array in Java](https://www.baeldung.com/java-array-find-missing-number)
|
||||
- [Calculate Weighted Mean in Java](https://www.baeldung.com/java-compute-weighted-average)
|
||||
- [Check if Two Strings Are Rotations of Each Other](https://www.baeldung.com/java-string-check-strings-rotations)
|
||||
- [Find the Largest Prime Under the Given Number in Java](https://www.baeldung.com/java-largest-prime-lower-threshold)
|
||||
- [Count the Number of Unique Digits in an Integer using Java](https://www.baeldung.com/java-int-count-unique-digits)
|
||||
- [Generate Juggler Sequence in Java](https://www.baeldung.com/java-generate-juggler-sequence)
|
||||
- [Finding the Parent of a Node in a Binary Search Tree with Java](https://www.baeldung.com/java-find-parent-node-binary-search-tree)
|
||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-6)
|
||||
|
@ -0,0 +1,57 @@
|
||||
package com.baeldung.algorithms.largestNumberRemovingK;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class LargestNumberRemoveKDigits {
|
||||
public static int findLargestNumberUsingArithmetic(int num, int k) {
|
||||
for (int j = 0; j < k; j++) {
|
||||
|
||||
int result = 0;
|
||||
int i = 1;
|
||||
|
||||
while (num / i > 0) {
|
||||
int temp = (num / (i * 10))
|
||||
* i
|
||||
+ (num % i);
|
||||
i *= 10;
|
||||
|
||||
result = Math.max(result, temp);
|
||||
}
|
||||
num = result;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public static int findLargestNumberUsingStack(int num, int k) {
|
||||
String numStr = Integer.toString(num);
|
||||
int length = numStr.length();
|
||||
|
||||
if (k == length) return 0;
|
||||
|
||||
Stack<Character> stack = new Stack<>();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
char digit = numStr.charAt(i);
|
||||
|
||||
while (k > 0 && !stack.isEmpty() && stack.peek() < digit) {
|
||||
stack.pop();
|
||||
k--;
|
||||
}
|
||||
|
||||
stack.push(digit);
|
||||
}
|
||||
|
||||
while (k > 0) {
|
||||
stack.pop();
|
||||
k--;
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
while (!stack.isEmpty()) {
|
||||
result.insert(0, stack.pop());
|
||||
}
|
||||
|
||||
return Integer.parseInt(result.toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.baeldung.algorithms.parentnodebinarytree;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ParentKeeperTreeNode {
|
||||
|
||||
int value;
|
||||
ParentKeeperTreeNode parent;
|
||||
ParentKeeperTreeNode left;
|
||||
ParentKeeperTreeNode right;
|
||||
|
||||
public ParentKeeperTreeNode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ParentKeeperTreeNode treeNode = (ParentKeeperTreeNode) o;
|
||||
return value == treeNode.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
}
|
||||
|
||||
public void insert(int value) {
|
||||
insert(this, value);
|
||||
}
|
||||
|
||||
private void insert(ParentKeeperTreeNode currentNode, final int value) {
|
||||
if (currentNode.left == null && value < currentNode.value) {
|
||||
currentNode.left = new ParentKeeperTreeNode(value);
|
||||
currentNode.left.parent = currentNode;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentNode.right == null && value > currentNode.value) {
|
||||
currentNode.right = new ParentKeeperTreeNode(value);
|
||||
currentNode.right.parent = currentNode;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value > currentNode.value) {
|
||||
insert(currentNode.right, value);
|
||||
}
|
||||
|
||||
if (value < currentNode.value) {
|
||||
insert(currentNode.left, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.baeldung.algorithms.parentnodebinarytree;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
public class TreeNode {
|
||||
int value;
|
||||
TreeNode left;
|
||||
TreeNode right;
|
||||
|
||||
public TreeNode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
TreeNode treeNode = (TreeNode) o;
|
||||
return value == treeNode.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(value);
|
||||
}
|
||||
|
||||
public void insert(int value) {
|
||||
insert(this, value);
|
||||
}
|
||||
|
||||
private void insert(TreeNode currentNode, final int value) {
|
||||
if (currentNode.left == null && value < currentNode.value) {
|
||||
currentNode.left = new TreeNode(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentNode.right == null && value > currentNode.value) {
|
||||
currentNode.right = new TreeNode(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value > currentNode.value) {
|
||||
insert(currentNode.right, value);
|
||||
}
|
||||
|
||||
if (value < currentNode.value) {
|
||||
insert(currentNode.left, value);
|
||||
}
|
||||
}
|
||||
|
||||
public TreeNode parent(int target) throws NoSuchElementException {
|
||||
return parent(this, new TreeNode(target));
|
||||
}
|
||||
|
||||
private TreeNode parent(TreeNode current, TreeNode target) throws NoSuchElementException {
|
||||
if (target.equals(current) || current == null) {
|
||||
throw new NoSuchElementException(format("No parent node found for 'target.value=%s' " +
|
||||
"The target is not in the tree or the target is the topmost root node.",
|
||||
target.value));
|
||||
}
|
||||
|
||||
if (target.equals(current.left) || target.equals(current.right)) {
|
||||
return current;
|
||||
}
|
||||
|
||||
return parent(target.value < current.value ? current.left : current.right, target);
|
||||
}
|
||||
|
||||
public TreeNode iterativeParent(int target) {
|
||||
return iterativeParent(this, new TreeNode(target));
|
||||
}
|
||||
|
||||
private TreeNode iterativeParent(TreeNode current, TreeNode target) {
|
||||
Deque<TreeNode> parentCandidates = new LinkedList<>();
|
||||
|
||||
String notFoundMessage = format("No parent node found for 'target.value=%s' " +
|
||||
"The target is not in the tree or the target is the topmost root node.",
|
||||
target.value);
|
||||
|
||||
if (target.equals(current)) {
|
||||
throw new NoSuchElementException(notFoundMessage);
|
||||
}
|
||||
|
||||
while (current != null || !parentCandidates.isEmpty()) {
|
||||
|
||||
while (current != null) {
|
||||
parentCandidates.addFirst(current);
|
||||
current = current.left;
|
||||
}
|
||||
|
||||
current = parentCandidates.pollFirst();
|
||||
|
||||
if (target.equals(current.left) || target.equals(current.right)) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current = current.right;
|
||||
}
|
||||
|
||||
throw new NoSuchElementException(notFoundMessage);
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
package com.baeldung.algorithms.stringrotation;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class StringRotation {
|
||||
|
||||
public static boolean doubledOriginContainsRotation(String origin, String rotation) {
|
||||
if (origin.length() == rotation.length()) {
|
||||
return origin.concat(origin)
|
||||
.contains(rotation);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isRotationUsingCommonStartWithOrigin(String origin, String rotation) {
|
||||
|
||||
if (origin.length() == rotation.length()) {
|
||||
|
||||
List<Integer> indexes = IntStream.range(0, origin.length())
|
||||
.filter(i -> rotation.charAt(i) == origin.charAt(0))
|
||||
.boxed()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (int startingAt : indexes) {
|
||||
if (isRotation(startingAt, rotation, origin)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean isRotation(int startingAt, String rotation, String origin) {
|
||||
|
||||
for (int i = 0; i < origin.length(); i++) {
|
||||
if (rotation.charAt((startingAt + i) % origin.length()) != origin.charAt(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isRotationUsingQueue(String origin, String rotation) {
|
||||
|
||||
if (origin.length() == rotation.length()) {
|
||||
return checkWithQueue(origin, rotation);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean checkWithQueue(String origin, String rotation) {
|
||||
|
||||
if (origin.length() == rotation.length()) {
|
||||
|
||||
Queue<Character> originQueue = getCharactersQueue(origin);
|
||||
|
||||
Queue<Character> rotationQueue = getCharactersQueue(rotation);
|
||||
|
||||
int k = rotation.length();
|
||||
while (k > 0 && null != rotationQueue.peek()) {
|
||||
k--;
|
||||
char ch = rotationQueue.peek();
|
||||
rotationQueue.remove();
|
||||
rotationQueue.add(ch);
|
||||
if (rotationQueue.equals(originQueue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static Queue<Character> getCharactersQueue(String origin) {
|
||||
return origin.chars()
|
||||
.mapToObj(c -> (char) c)
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
public static boolean isRotationUsingSuffixAndPrefix(String origin, String rotation) {
|
||||
|
||||
if (origin.length() == rotation.length()) {
|
||||
return checkPrefixAndSuffix(origin, rotation);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean checkPrefixAndSuffix(String origin, String rotation) {
|
||||
if (origin.length() == rotation.length()) {
|
||||
|
||||
for (int i = 0; i < origin.length(); i++) {
|
||||
if (origin.charAt(i) == rotation.charAt(0)) {
|
||||
if (checkRotationPrefixWithOriginSuffix(origin, rotation, i)) {
|
||||
if (checkOriginPrefixWithRotationSuffix(origin, rotation, i))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean checkRotationPrefixWithOriginSuffix(String origin, String rotation, int i) {
|
||||
return origin.substring(i)
|
||||
.equals(rotation.substring(0, origin.length() - i));
|
||||
}
|
||||
|
||||
private static boolean checkOriginPrefixWithRotationSuffix(String origin, String rotation, int i) {
|
||||
return origin.substring(0, i)
|
||||
.equals(rotation.substring(origin.length() - i));
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.algorithms.uniquedigit;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class UniqueDigitCounter {
|
||||
|
||||
public static int countWithSet(int number) {
|
||||
number = Math.abs(number);
|
||||
Set<Character> uniqueDigits = new HashSet<>();
|
||||
String numberStr = String.valueOf(number);
|
||||
for (char digit : numberStr.toCharArray()) {
|
||||
uniqueDigits.add(digit);
|
||||
}
|
||||
return uniqueDigits.size();
|
||||
}
|
||||
|
||||
public static int countWithBitManipulation(int number) {
|
||||
if (number == 0) {
|
||||
return 1;
|
||||
}
|
||||
number = Math.abs(number);
|
||||
int mask = 0;
|
||||
while (number > 0) {
|
||||
int digit = number % 10;
|
||||
mask |= 1 << digit;
|
||||
number /= 10;
|
||||
}
|
||||
return Integer.bitCount(mask);
|
||||
}
|
||||
|
||||
public static long countWithStreamApi(int number) {
|
||||
return String.valueOf(Math.abs(number)).chars().distinct().count();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.baeldung.algorithms.jugglersequence;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class JugglerSequenceGenerator {
|
||||
|
||||
public static List<Integer> byLoop(int n) {
|
||||
if (n <= 0) {
|
||||
throw new IllegalArgumentException("The initial integer must be greater than zero.");
|
||||
}
|
||||
List<Integer> seq = new ArrayList<>();
|
||||
int current = n;
|
||||
seq.add(current);
|
||||
while (current != 1) {
|
||||
int next = (int) (Math.sqrt(current) * (current % 2 == 0 ? 1 : current));
|
||||
seq.add(next);
|
||||
current = next;
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
|
||||
public static List<Integer> byRecursion(int n) {
|
||||
if (n <= 0) {
|
||||
throw new IllegalArgumentException("The initial integer must be greater than zero.");
|
||||
}
|
||||
List<Integer> seq = new ArrayList<>();
|
||||
fillSeqRecursively(n, seq);
|
||||
return seq;
|
||||
}
|
||||
|
||||
private static void fillSeqRecursively(int current, List<Integer> result) {
|
||||
result.add(current);
|
||||
if (current == 1) {
|
||||
return;
|
||||
}
|
||||
int next = (int) (Math.sqrt(current) * (current % 2 == 0 ? 1 : current));
|
||||
fillSeqRecursively(next, result);
|
||||
}
|
||||
}
|
||||
|
||||
public class JugglerSequenceUnitTest {
|
||||
|
||||
@Test
|
||||
void whenGeneratingJugglerSeqUsingLoop_thenGetTheExpectedResult() {
|
||||
assertThrows(IllegalArgumentException.class, () -> JugglerSequenceGenerator.byLoop(0));
|
||||
assertEquals(List.of(3, 5, 11, 36, 6, 2, 1), JugglerSequenceGenerator.byLoop(3));
|
||||
assertEquals(List.of(4, 2, 1), JugglerSequenceGenerator.byLoop(4));
|
||||
assertEquals(List.of(9, 27, 140, 11, 36, 6, 2, 1), JugglerSequenceGenerator.byLoop(9));
|
||||
assertEquals(List.of(21, 96, 9, 27, 140, 11, 36, 6, 2, 1), JugglerSequenceGenerator.byLoop(21));
|
||||
assertEquals(List.of(42, 6, 2, 1), JugglerSequenceGenerator.byLoop(42));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenGeneratingJugglerSeqUsingRecursion_thenGetTheExpectedResult() {
|
||||
assertThrows(IllegalArgumentException.class, () -> JugglerSequenceGenerator.byRecursion(0));
|
||||
assertEquals(List.of(3, 5, 11, 36, 6, 2, 1), JugglerSequenceGenerator.byRecursion(3));
|
||||
assertEquals(List.of(4, 2, 1), JugglerSequenceGenerator.byRecursion(4));
|
||||
assertEquals(List.of(9, 27, 140, 11, 36, 6, 2, 1), JugglerSequenceGenerator.byRecursion(9));
|
||||
assertEquals(List.of(21, 96, 9, 27, 140, 11, 36, 6, 2, 1), JugglerSequenceGenerator.byRecursion(21));
|
||||
assertEquals(List.of(42, 6, 2, 1), JugglerSequenceGenerator.byRecursion(42));
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.baeldung.algorithms.largestNumberRemovingK;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class LargestNumberRemoveKDigitsUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenNumber_UsingArithmeticRemoveKDigits_thenReturnLargestNumber(){
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingArithmetic(9461, 1), 961);
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingArithmetic(463, 2), 6);
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingArithmetic(98625410, 6), 98);
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingArithmetic(20, 2), 0);
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingArithmetic(98989, 4), 9);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNumber_UsingStackRemoveKDigits_thenReturnLargestNumber(){
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingStack(9461, 1), 961);
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingStack(463, 2), 6);
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingStack(98625410, 6), 98);
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingStack(20, 2), 0);
|
||||
Assertions.assertEquals(LargestNumberRemoveKDigits.findLargestNumberUsingStack(98989, 4), 9);
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.baeldung.algorithms.parentnodebinarytree;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BinaryTreeParentNodeFinderUnitTest {
|
||||
|
||||
private TreeNode subject;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
subject = new TreeNode(8);
|
||||
subject.insert(5);
|
||||
subject.insert(12);
|
||||
subject.insert(3);
|
||||
subject.insert(7);
|
||||
subject.insert(1);
|
||||
subject.insert(4);
|
||||
subject.insert(11);
|
||||
subject.insert(14);
|
||||
subject.insert(13);
|
||||
subject.insert(16);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenBinaryTree_whenFindParentNode_thenReturnCorrectParentNode() {
|
||||
assertEquals(8, subject.parent(5).value);
|
||||
assertEquals(5, subject.parent(3).value);
|
||||
assertEquals(5, subject.parent(7).value);
|
||||
assertEquals(3, subject.parent(4).value);
|
||||
assertEquals(3, subject.parent(1).value);
|
||||
assertEquals(8, subject.parent(12).value);
|
||||
assertEquals(12, subject.parent(14).value);
|
||||
assertEquals(12, subject.parent(11).value);
|
||||
assertEquals(14, subject.parent(16).value);
|
||||
assertEquals(14, subject.parent(13).value);
|
||||
assertThrows(NoSuchElementException.class, () -> subject.parent(1231));
|
||||
assertThrows(NoSuchElementException.class, () -> subject.parent(8));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenBinaryTree_whenFindParentNodeIteratively_thenReturnCorrectParentNode() {
|
||||
assertEquals(8, subject.iterativeParent(5).value);
|
||||
assertEquals(5, subject.iterativeParent(3).value);
|
||||
assertEquals(5, subject.iterativeParent(7).value);
|
||||
assertEquals(3, subject.iterativeParent(4).value);
|
||||
assertEquals(3, subject.iterativeParent(1).value);
|
||||
assertEquals(8, subject.iterativeParent(12).value);
|
||||
assertEquals(12, subject.iterativeParent(14).value);
|
||||
assertEquals(12, subject.iterativeParent(11).value);
|
||||
assertEquals(14, subject.iterativeParent(16).value);
|
||||
assertEquals(14, subject.iterativeParent(13).value);
|
||||
assertThrows(NoSuchElementException.class, () -> subject.iterativeParent(1231));
|
||||
assertThrows(NoSuchElementException.class, () -> subject.iterativeParent(8));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenParentKeeperBinaryTree_whenGetParent_thenReturnCorrectParent() {
|
||||
ParentKeeperTreeNode subject = new ParentKeeperTreeNode(8);
|
||||
subject.insert(5);
|
||||
subject.insert(12);
|
||||
subject.insert(3);
|
||||
subject.insert(7);
|
||||
subject.insert(1);
|
||||
subject.insert(4);
|
||||
subject.insert(11);
|
||||
subject.insert(14);
|
||||
subject.insert(13);
|
||||
subject.insert(16);
|
||||
|
||||
assertNull(subject.parent);
|
||||
assertEquals(8, subject.left.parent.value);
|
||||
assertEquals(8, subject.right.parent.value);
|
||||
assertEquals(5, subject.left.left.parent.value);
|
||||
assertEquals(5, subject.left.right.parent.value);
|
||||
|
||||
// tests for other nodes
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.baeldung.algorithms.stringrotation;
|
||||
|
||||
import static com.baeldung.algorithms.stringrotation.StringRotation.doubledOriginContainsRotation;
|
||||
import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingCommonStartWithOrigin;
|
||||
import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingQueue;
|
||||
import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingSuffixAndPrefix;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class StringRotationUnitTest {
|
||||
|
||||
@Test
|
||||
void givenOriginAndRotationInput_whenCheckIfOriginContainsRotation_thenIsRotation() {
|
||||
assertTrue(doubledOriginContainsRotation("abcd", "cdab"));
|
||||
assertTrue(doubledOriginContainsRotation("abcd", "abcd"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOriginAndRotationInput_whenCheckIfOriginContainsRotation_thenNoRotation() {
|
||||
assertFalse(doubledOriginContainsRotation("abcd", "bbbb"));
|
||||
assertFalse(doubledOriginContainsRotation("abcd", "abcde"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOriginAndRotationInput_whenCheckingCommonStartWithOrigin_thenIsRotation() {
|
||||
assertTrue(isRotationUsingCommonStartWithOrigin("abcd", "cdab"));
|
||||
assertTrue(isRotationUsingCommonStartWithOrigin("abcd", "abcd"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOriginAndRotationInput_whenCheckingCommonStartWithOrigin_thenNoRotation() {
|
||||
assertFalse(isRotationUsingCommonStartWithOrigin("abcd", "bbbb"));
|
||||
assertFalse(isRotationUsingCommonStartWithOrigin("abcd", "abcde"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOriginAndRotationInput_whenCheckingUsingQueues_thenIsRotation() {
|
||||
assertTrue(isRotationUsingQueue("abcd", "cdab"));
|
||||
assertTrue(isRotationUsingQueue("abcd", "abcd"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOriginAndRotationInput_whenCheckingUsingQueues_thenNoRotation() {
|
||||
assertFalse(isRotationUsingQueue("abcd", "bbbb"));
|
||||
assertFalse(isRotationUsingQueue("abcd", "abcde"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOriginAndRotationInput_whenCheckingUsingSuffixAndPrefix_thenIsRotation() {
|
||||
assertTrue(isRotationUsingSuffixAndPrefix("abcd", "cdab"));
|
||||
assertTrue(isRotationUsingSuffixAndPrefix("abcd", "abcd"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOriginAndRotationInput_whenCheckingUsingSuffixAndPrefix_thenNoRotation() {
|
||||
assertFalse(isRotationUsingSuffixAndPrefix("abcd", "bbbb"));
|
||||
assertFalse(isRotationUsingSuffixAndPrefix("abcd", "abcde"));
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.baeldung.algorithms.uniquedigit;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class UniqueDigitCounterUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenNotNegativeNumber_whenCountUniqueDigits_thenCorrectCount() {
|
||||
assertEquals(3, UniqueDigitCounter.countWithSet(122333));
|
||||
assertEquals(1, UniqueDigitCounter.countWithSet(0));
|
||||
assertEquals(2, UniqueDigitCounter.countWithSet(101));
|
||||
|
||||
assertEquals(3, UniqueDigitCounter.countWithBitManipulation(122333));
|
||||
assertEquals(1, UniqueDigitCounter.countWithBitManipulation(0));
|
||||
assertEquals(2, UniqueDigitCounter.countWithBitManipulation(101));
|
||||
|
||||
assertEquals(3, UniqueDigitCounter.countWithStreamApi(122333));
|
||||
assertEquals(1, UniqueDigitCounter.countWithStreamApi(0));
|
||||
assertEquals(2, UniqueDigitCounter.countWithStreamApi(101));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNegativeNumber_whenCountUniqueDigits_thenCorrectCount() {
|
||||
assertEquals(3, UniqueDigitCounter.countWithSet(-122333));
|
||||
assertEquals(3, UniqueDigitCounter.countWithBitManipulation(-122333));
|
||||
assertEquals(3, UniqueDigitCounter.countWithStreamApi(-122333));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLargeNumber_whenCountUniqueDigits_thenCorrectCount() {
|
||||
assertEquals(2, UniqueDigitCounter.countWithSet(1000000000));
|
||||
assertEquals(2, UniqueDigitCounter.countWithBitManipulation(1000000000));
|
||||
assertEquals(2, UniqueDigitCounter.countWithStreamApi(1000000000));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.baeldung.algorithms.vigenere;
|
||||
|
||||
public class VigenereCipher {
|
||||
private final String characters;
|
||||
|
||||
public VigenereCipher() {
|
||||
this("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
}
|
||||
|
||||
public VigenereCipher(String characters) {
|
||||
this.characters = characters;
|
||||
}
|
||||
|
||||
public String encode(String input, String key) {
|
||||
String result = "";
|
||||
|
||||
int keyPosition = 0;
|
||||
for (char c : input.toCharArray()) {
|
||||
char k = key.charAt(keyPosition % key.length());
|
||||
|
||||
int charIndex = characters.indexOf(c);
|
||||
int keyIndex = characters.indexOf(k);
|
||||
|
||||
if (charIndex >= 0) {
|
||||
if (keyIndex >= 0) {
|
||||
int newCharIndex = (charIndex + keyIndex + 1) % characters.length();
|
||||
c = characters.charAt(newCharIndex);
|
||||
|
||||
}
|
||||
|
||||
keyPosition++;
|
||||
}
|
||||
|
||||
result += c;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String decode(String input, String key) {
|
||||
String result = "";
|
||||
|
||||
int keyPosition = 0;
|
||||
for (char c : input.toCharArray()) {
|
||||
char k = key.charAt(keyPosition % key.length());
|
||||
|
||||
int charIndex = characters.indexOf(c);
|
||||
int keyIndex = characters.indexOf(k);
|
||||
|
||||
if (charIndex >= 0) {
|
||||
if (keyIndex >= 0) {
|
||||
int newCharIndex = charIndex - keyIndex - 1;
|
||||
if (newCharIndex < 0) {
|
||||
newCharIndex = characters.length() + newCharIndex;
|
||||
}
|
||||
c = characters.charAt(newCharIndex);
|
||||
|
||||
}
|
||||
|
||||
keyPosition++;
|
||||
}
|
||||
|
||||
result += c;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.baeldung.algorithms.vigenere;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class VigenereCipherUnitTest {
|
||||
|
||||
@Test
|
||||
void encodeBaeldung() {
|
||||
VigenereCipher cipher = new VigenereCipher();
|
||||
String output = cipher.encode("BAELDUNG", "HELLO");
|
||||
|
||||
Assertions.assertEquals("JFQXSCSS", output);
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeBaeldungMixedCharacters() {
|
||||
VigenereCipher cipher = new VigenereCipher("JQFVHPWORZSLNMKYCGBUXIEDTA");
|
||||
String output = cipher.encode("BAELDUNG", "HELLO");
|
||||
|
||||
Assertions.assertEquals("DERDPTZV", output);
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeArticleTitle() {
|
||||
VigenereCipher cipher = new VigenereCipher();
|
||||
String output = cipher.encode("VEGENERE CIPHER IN JAVA", "BAELDUNG");
|
||||
|
||||
Assertions.assertEquals("XFLQRZFL EJUTIM WU LBAM", output);
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeArticleTitleMoreCharacters() {
|
||||
VigenereCipher cipher = new VigenereCipher("ABCDEFGHIJKLMNOPQRSTUVWXYZ ");
|
||||
String output = cipher.encode("VEGENERE CIPHER IN JAVA", "BAELDUNG");
|
||||
|
||||
Assertions.assertEquals("XFLQRZELBDNALZEGKOEVEPO", output);
|
||||
}
|
||||
|
||||
@Test
|
||||
void decodeBaeldung() {
|
||||
VigenereCipher cipher = new VigenereCipher();
|
||||
String output = cipher.decode("JFQXSCSS", "HELLO");
|
||||
|
||||
Assertions.assertEquals("BAELDUNG", output);
|
||||
}
|
||||
|
||||
@Test
|
||||
void decodeBaeldungMixedCharacters() {
|
||||
VigenereCipher cipher = new VigenereCipher("JQFVHPWORZSLNMKYCGBUXIEDTA");
|
||||
String output = cipher.decode("DERDPTZV", "HELLO");
|
||||
|
||||
Assertions.assertEquals("BAELDUNG", output);
|
||||
}
|
||||
|
||||
@Test
|
||||
void decodeArticleTitleMoreCharacters() {
|
||||
VigenereCipher cipher = new VigenereCipher("ABCDEFGHIJKLMNOPQRSTUVWXYZ ");
|
||||
String output = cipher.decode("XFLQRZELBDNALZEGKOEVEPO", "BAELDUNG");
|
||||
|
||||
Assertions.assertEquals("VEGENERE CIPHER IN JAVA", output);
|
||||
}
|
||||
}
|
@ -82,7 +82,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-oxm</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<version>${spring-oxm.version}</version>
|
||||
</dependency>
|
||||
<!-- marshalling -->
|
||||
<dependency>
|
||||
@ -176,12 +176,6 @@
|
||||
<version>${jstl.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- util -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<!-- test scoped -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
@ -233,6 +227,7 @@
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<spring-oxm.version>6.1.4</spring-oxm.version>
|
||||
<!-- util -->
|
||||
<commons-codec.version>1.16.0</commons-codec.version>
|
||||
<httpasyncclient.version>4.1.5</httpasyncclient.version>
|
||||
|
@ -16,3 +16,4 @@ You can build the project from the command line using: *mvn clean install*, or i
|
||||
- [Introduction to Apache Kafka](https://www.baeldung.com/apache-kafka)
|
||||
- [Ensuring Message Ordering in Kafka: Strategies and Configurations](https://www.baeldung.com/kafka-message-ordering)
|
||||
- [Read Multiple Messages with Apache Kafka](https://www.baeldung.com/kafka-read-multiple-messages)
|
||||
- [Creating a Kafka Listener Using the Consumer API](https://www.baeldung.com/kafka-create-listener-consumer-api)
|
||||
|
@ -71,11 +71,6 @@
|
||||
<version>${flink.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
|
@ -1,2 +1,5 @@
|
||||
## 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)
|
||||
|
||||
- More articles: [[<-- prev]](../apache-libraries)
|
||||
|
@ -19,10 +19,29 @@
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>${javax.validation.validation-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-core</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-test-junit5</artifactId>
|
||||
<version>${camel.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.camel</groupId>
|
||||
<artifactId>camel-main</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>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,29 @@
|
||||
package com.baeldung.dynamicrouter;
|
||||
|
||||
import org.apache.camel.ExchangeProperties;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class DynamicRouterBean {
|
||||
public String route(String body, @ExchangeProperties Map<String, Object> properties) {
|
||||
int invoked = (int) properties.getOrDefault("invoked", 0) + 1;
|
||||
|
||||
properties.put("invoked", invoked);
|
||||
|
||||
if (invoked == 1) {
|
||||
switch (body.toLowerCase()) {
|
||||
case "mock":
|
||||
return "mock:dynamicRouter";
|
||||
case "direct":
|
||||
return "mock:directDynamicRouter";
|
||||
case "seda":
|
||||
return "mock:sedaDynamicRouter";
|
||||
case "file":
|
||||
return "mock:fileDynamicRouter";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.baeldung.dynamicrouter;
|
||||
|
||||
import org.apache.camel.builder.RouteBuilder;
|
||||
|
||||
public class DynamicRouterRoute extends RouteBuilder {
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
|
||||
from("direct:dynamicRouter").dynamicRouter(method(DynamicRouterBean.class, "route"));
|
||||
|
||||
}
|
||||
}
|
@ -10,4 +10,6 @@
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<logger name="org.apache.camel.impl.engine" level="WARN"/>
|
||||
</configuration>
|
@ -0,0 +1,61 @@
|
||||
package dynamicrouter;
|
||||
|
||||
import com.baeldung.dynamicrouter.DynamicRouterRoute;
|
||||
import org.apache.camel.RoutesBuilder;
|
||||
import org.apache.camel.component.mock.MockEndpoint;
|
||||
import org.apache.camel.test.junit5.CamelTestSupport;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class DynamicRouterRouteUnitTest extends CamelTestSupport {
|
||||
|
||||
@Override
|
||||
protected RoutesBuilder createRouteBuilder() {
|
||||
return new DynamicRouterRoute();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndMockAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException {
|
||||
|
||||
MockEndpoint mockDynamicEndpoint = getMockEndpoint("mock:dynamicRouter");
|
||||
mockDynamicEndpoint.expectedMessageCount(1);
|
||||
|
||||
template.send("direct:dynamicRouter", exchange -> exchange.getIn()
|
||||
.setBody("mock"));
|
||||
MockEndpoint.assertIsSatisfied(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndDirectAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException {
|
||||
|
||||
MockEndpoint mockDynamicEndpoint = context.getEndpoint("mock:directDynamicRouter", MockEndpoint.class);
|
||||
mockDynamicEndpoint.expectedMessageCount(1);
|
||||
|
||||
template.send("direct:dynamicRouter", exchange -> exchange.getIn()
|
||||
.setBody("direct"));
|
||||
|
||||
MockEndpoint.assertIsSatisfied(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndSedaAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException {
|
||||
|
||||
MockEndpoint mockDynamicEndpoint = context.getEndpoint("mock:sedaDynamicRouter", MockEndpoint.class);
|
||||
mockDynamicEndpoint.expectedMessageCount(1);
|
||||
|
||||
template.send("direct:dynamicRouter", exchange -> exchange.getIn()
|
||||
.setBody("seda"));
|
||||
MockEndpoint.assertIsSatisfied(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndBookAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException {
|
||||
|
||||
MockEndpoint mockDynamicEndpoint = getMockEndpoint("mock:fileDynamicRouter");
|
||||
mockDynamicEndpoint.expectedMessageCount(1);
|
||||
|
||||
template.send("direct:dynamicRouter", exchange -> exchange.getIn()
|
||||
.setBody("file"));
|
||||
MockEndpoint.assertIsSatisfied(context);
|
||||
}
|
||||
|
||||
}
|
15
apache-libraries-2/src/test/resources/logback-test.xml
Normal file
15
apache-libraries-2/src/test/resources/logback-test.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<logger name="ch.qos.logback.classic.joran.action" level="WARN"/>
|
||||
</configuration>
|
@ -13,3 +13,5 @@ This module contains articles about various Apache libraries and utilities
|
||||
- [Introduction to Apache Curator](https://www.baeldung.com/apache-curator)
|
||||
- [A Quick Guide to Apache Geode](https://www.baeldung.com/apache-geode)
|
||||
- [Guide To Solr in Java With Apache SolrJ](https://www.baeldung.com/apache-solrj)
|
||||
|
||||
- More articles: [[next -->]](../apache-libraries-2)
|
@ -191,7 +191,7 @@
|
||||
<bval.version>2.0.6</bval.version>
|
||||
<javax.validation.validation-api.version>2.0.1.Final</javax.validation.validation-api.version>
|
||||
<meecrowave-junit.version>1.2.15</meecrowave-junit.version>
|
||||
<okhttp.version>4.12.0</okhttp.version>
|
||||
<okhttp.version>5.0.0-alpha.12</okhttp.version>
|
||||
<meecrowave-jpa.version>1.2.15</meecrowave-jpa.version>
|
||||
<meecrowave-core.version>1.2.15</meecrowave-core.version>
|
||||
<meecrowave-maven-plugin.version>1.2.15</meecrowave-maven-plugin.version>
|
||||
|
@ -14,4 +14,4 @@ This module contains articles about Apache POI.
|
||||
- [Set the Date Format Using Apache POI](https://www.baeldung.com/java-apache-poi-date-format)
|
||||
- [Replacing Variables in a Document Template with Java](https://www.baeldung.com/java-replace-pattern-word-document-doc-docx)
|
||||
- [Lock Header Rows With Apache POI](https://www.baeldung.com/java-apache-poi-lock-header-rows)
|
||||
- More articles: [[<-- prev]](../apache-poi)
|
||||
- More articles: [[<-- prev]](../apache-poi)[[next -->]](../apache-poi-3)
|
||||
|
@ -27,7 +27,7 @@
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<poi.version>5.2.3</poi.version>
|
||||
<poi.version>5.2.5</poi.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -1,4 +1,10 @@
|
||||
## Relevant Articles
|
||||
## Apache POI
|
||||
|
||||
This module contains articles about Apache POI.
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [How To Convert Excel Data Into List Of Java Objects](https://www.baeldung.com/java-convert-excel-data-into-list)
|
||||
- [Expand Columns with Apache POI](https://www.baeldung.com/java-apache-poi-expand-columns)
|
||||
- [Apply Bold Text Style for an Entire Row Using Apache POI](https://www.baeldung.com/appache-poi-apply-bold-text-style-entire-row)
|
||||
- More articles: [[<-- prev]](../apache-poi-2)
|
@ -24,50 +24,41 @@
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.github.ozlerhakan/poiji -->
|
||||
<dependency>
|
||||
<groupId>com.github.ozlerhakan</groupId>
|
||||
<artifactId>poiji</artifactId>
|
||||
<version>${poiji.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi/5.2.3 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas/4.1.2 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml-schemas</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>${poi-ooxml-schemas.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans/5.1.1 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlbeans</groupId>
|
||||
<artifactId>xmlbeans</artifactId>
|
||||
<version>5.1.1</version>
|
||||
<version>${xmlbeans.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.4</version>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.dhatim/fastexcel/0.15.7 -->
|
||||
<dependency>
|
||||
<groupId>org.dhatim</groupId>
|
||||
<artifactId>fastexcel</artifactId>
|
||||
<version>${fastexcel.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.dhatim/fastexcel-reader/0.15.7 -->
|
||||
<dependency>
|
||||
<groupId>org.dhatim</groupId>
|
||||
<artifactId>fastexcel-reader</artifactId>
|
||||
<version>${fastexcel.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl/2.6.12 -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jexcelapi</groupId>
|
||||
<artifactId>jxl</artifactId>
|
||||
@ -77,8 +68,11 @@
|
||||
|
||||
<properties>
|
||||
<poi.version>5.2.5</poi.version>
|
||||
<poiji.version>4.1.1</poiji.version>
|
||||
<fastexcel.version>0.15.7</fastexcel.version>
|
||||
<poi-ooxml-schemas.version>4.1.2</poi-ooxml-schemas.version>
|
||||
<poiji.version>4.2.0</poiji.version>
|
||||
<xmlbeans.version>5.2.0</xmlbeans.version>
|
||||
<commons-collections4.version>4.4</commons-collections4.version>
|
||||
<fastexcel.version>0.17.0</fastexcel.version>
|
||||
<jxl.version>2.6.12</jxl.version>
|
||||
</properties>
|
||||
|
||||
|
@ -60,10 +60,10 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<poi.version>5.2.0</poi.version>
|
||||
<jexcel.version>1.0.6</jexcel.version>
|
||||
<fastexcel.version>0.15.3</fastexcel.version>
|
||||
<maven.resources.plugin.version>3.2.0</maven.resources.plugin.version>
|
||||
<poi.version>5.2.5</poi.version>
|
||||
<jexcel.version>1.0.9</jexcel.version>
|
||||
<fastexcel.version>0.17.0</fastexcel.version>
|
||||
<maven.resources.plugin.version>3.3.1</maven.resources.plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -28,7 +28,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${org.apache.httpcomponents.version}</version>
|
||||
<version>${httpclient.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -60,7 +60,7 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<org.apache.httpcomponents.version>4.5.2</org.apache.httpcomponents.version>
|
||||
<httpclient.version>4.5.2</httpclient.version>
|
||||
<velocity-version>1.7</velocity-version>
|
||||
<velocity-tools-version>2.0</velocity-tools-version>
|
||||
</properties>
|
||||
|
@ -37,7 +37,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>${maven-plugins-version}</version>
|
||||
<version>${maven-dependency-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy</id>
|
||||
@ -58,10 +58,7 @@
|
||||
|
||||
<properties>
|
||||
<gson.version>2.10.1</gson.version>
|
||||
<dynamodblocal.version>1.21.1</dynamodblocal.version>
|
||||
<commons-codec-version>1.16.0</commons-codec-version>
|
||||
<jets3t-version>0.9.4.0006L</jets3t-version>
|
||||
<maven-plugins-version>3.1.1</maven-plugins-version>
|
||||
<maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -27,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>bom</artifactId>
|
||||
<version>${awssdk.version}</version>
|
||||
<version>${aws-java-sdk-v2.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
@ -93,7 +93,6 @@
|
||||
|
||||
<properties>
|
||||
<spring.version>2.2.1.RELEASE</spring.version>
|
||||
<awssdk.version>2.17.283</awssdk.version>
|
||||
<reactor.version>3.6.0</reactor.version>
|
||||
</properties>
|
||||
|
||||
|
@ -12,3 +12,4 @@ This module contains articles about Simple Storage Service (S3) on AWS
|
||||
- [Update an Existing Amazon S3 Object Using Java](https://www.baeldung.com/java-update-amazon-s3-object)
|
||||
- [How To Rename Files and Folders in Amazon S3](https://www.baeldung.com/java-amazon-s3-rename-files-folders)
|
||||
- [Update an Existing Amazon S3 Object Using Java](https://www.baeldung.com/java-update-amazon-s3-object)
|
||||
- [How to Mock Amazon S3 for Integration Test](https://www.baeldung.com/java-amazon-simple-storage-service-mock-testing)
|
||||
|
@ -18,7 +18,13 @@
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>s3</artifactId>
|
||||
<version>${aws-java-sdk-v2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>url-connection-client</artifactId>
|
||||
<version>${aws.java.sdk.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -30,19 +36,41 @@
|
||||
<dependency>
|
||||
<groupId>org.lucee</groupId>
|
||||
<artifactId>jets3t</artifactId>
|
||||
<version>${jets3t-version}</version>
|
||||
<version>${jets3t.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lucee</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec-version}</version>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
<!-- adobe s3mock -->
|
||||
<dependency>
|
||||
<groupId>com.adobe.testing</groupId>
|
||||
<artifactId>s3mock</artifactId>
|
||||
<version>${com.adobe.testing.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.adobe.testing</groupId>
|
||||
<artifactId>s3mock-testcontainers</artifactId>
|
||||
<version>${com.adobe.testing.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${org.testcontainers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<aws.java.sdk.version>2.20.52</aws.java.sdk.version>
|
||||
<commons-codec-version>1.10.L001</commons-codec-version>
|
||||
<jets3t-version>0.9.4.0006L</jets3t-version>
|
||||
<com.adobe.testing.version>3.3.0</com.adobe.testing.version>
|
||||
<org.testcontainers.version>1.19.4</org.testcontainers.version>
|
||||
<commons-codec.version>1.10.L001</commons-codec.version>
|
||||
<jets3t.version>0.9.4.0014L</jets3t.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,65 @@
|
||||
package com.baeldung.s3;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import software.amazon.awssdk.core.ResponseBytes;
|
||||
import software.amazon.awssdk.core.sync.RequestBody;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
|
||||
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.S3Exception;
|
||||
|
||||
public class S3CrudService {
|
||||
|
||||
private final S3Client s3Client;
|
||||
|
||||
public S3CrudService(S3Client s3Client) {
|
||||
this.s3Client = s3Client;
|
||||
}
|
||||
|
||||
public void createBucket(String bucketName) {
|
||||
CreateBucketRequest bucketRequest = CreateBucketRequest.builder()
|
||||
.bucket(bucketName)
|
||||
.build();
|
||||
|
||||
s3Client.createBucket(bucketRequest);
|
||||
}
|
||||
|
||||
public void createObject(String bucketName, File inMemoryObject) {
|
||||
PutObjectRequest request = PutObjectRequest.builder()
|
||||
.bucket(bucketName)
|
||||
.key(inMemoryObject.getName())
|
||||
.build();
|
||||
s3Client.putObject(request, RequestBody.fromByteBuffer(inMemoryObject.getContent()));
|
||||
}
|
||||
|
||||
public Optional<byte[]> getObject(String bucketName, String objectKey) {
|
||||
try {
|
||||
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
|
||||
.bucket(bucketName)
|
||||
.key(objectKey)
|
||||
.build();
|
||||
ResponseBytes<GetObjectResponse> responseResponseBytes = s3Client.getObjectAsBytes(getObjectRequest);
|
||||
return Optional.of(responseResponseBytes.asByteArray());
|
||||
} catch (S3Exception e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteObject(String bucketName, String objectKey) {
|
||||
try {
|
||||
DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()
|
||||
.bucket(bucketName)
|
||||
.key(objectKey)
|
||||
.build();
|
||||
|
||||
s3Client.deleteObject(deleteObjectRequest);
|
||||
return true;
|
||||
} catch (S3Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.baeldung.s3;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import com.adobe.testing.s3mock.testcontainers.S3MockContainer;
|
||||
|
||||
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.s3.S3Configuration;
|
||||
import software.amazon.awssdk.utils.AttributeMap;
|
||||
|
||||
// This live test needs a running Docker instance so that a S3Mock Container can be started
|
||||
|
||||
@Testcontainers
|
||||
public class S3CrudServiceLiveTest {
|
||||
|
||||
private static final String TEST_BUCKET_NAME = "test-bucket";
|
||||
|
||||
@Container
|
||||
private final S3MockContainer s3Mock = new S3MockContainer("latest");
|
||||
private S3Client s3Client;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
var endpoint = s3Mock.getHttpsEndpoint();
|
||||
var serviceConfig = S3Configuration.builder()
|
||||
.pathStyleAccessEnabled(true)
|
||||
.build();
|
||||
var httpClient = UrlConnectionHttpClient.builder()
|
||||
.buildWithDefaults(AttributeMap.builder()
|
||||
.put(TRUST_ALL_CERTIFICATES, Boolean.TRUE)
|
||||
.build());
|
||||
s3Client = S3Client.builder()
|
||||
.endpointOverride(URI.create(endpoint))
|
||||
.serviceConfiguration(serviceConfig)
|
||||
.httpClient(httpClient)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenVerifyingCreationOfS3Bucket_thenCorrect() {
|
||||
var s3CrudService = new S3CrudService(s3Client);
|
||||
s3CrudService.createBucket(TEST_BUCKET_NAME);
|
||||
|
||||
var createdBucketName = s3Client.listBuckets()
|
||||
.buckets()
|
||||
.get(0)
|
||||
.name();
|
||||
assertThat(TEST_BUCKET_NAME).isEqualTo(createdBucketName);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCreatingAnObjectOnS3Bucket_thenSameObjectIsRetrived() {
|
||||
var s3CrudService = new S3CrudService(s3Client);
|
||||
s3CrudService.createBucket(TEST_BUCKET_NAME);
|
||||
|
||||
var fileToSave = FileGenerator.generateFiles(1, 100)
|
||||
.get(0);
|
||||
s3CrudService.createObject(TEST_BUCKET_NAME, fileToSave);
|
||||
|
||||
var savedFileContent = s3CrudService.getObject(TEST_BUCKET_NAME, fileToSave.getName());
|
||||
|
||||
assertThat(Arrays.equals(fileToSave.getContent()
|
||||
.array(), savedFileContent.orElse(new byte[] {}))).isTrue();
|
||||
|
||||
s3CrudService.deleteObject(TEST_BUCKET_NAME, fileToSave.getName());
|
||||
|
||||
var deletedFileContent = s3CrudService.getObject(TEST_BUCKET_NAME, fileToSave.getName());
|
||||
assertThat(deletedFileContent).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
<properties>
|
||||
<aws-java-sdk.version>1.12.331</aws-java-sdk.version>
|
||||
<aws-java-sdk-v2.version>2.20.147</aws-java-sdk-v2.version>
|
||||
<aws-java-sdk-v2.version>2.24.9</aws-java-sdk-v2.version>
|
||||
<maven-shade-plugin.version>3.0.0</maven-shade-plugin.version>
|
||||
</properties>
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>checker-framework</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>checker-framework</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>checker-framework</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
@ -55,9 +55,7 @@
|
||||
<arg>-Awarns</arg>
|
||||
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
|
||||
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
|
||||
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
|
||||
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
|
||||
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
|
||||
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
|
||||
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
|
||||
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
|
||||
|
@ -157,7 +157,7 @@
|
||||
<properties>
|
||||
<groovy-wslite.version>1.1.3</groovy-wslite.version>
|
||||
<assembly.plugin.version>3.4.2</assembly.plugin.version>
|
||||
<compiler.plugin.version>3.8.1</compiler.plugin.version>
|
||||
<compiler.plugin.version>3.12.1</compiler.plugin.version>
|
||||
<groovy.compiler.version>3.9.0</groovy.compiler.version>
|
||||
<groovy-eclipse-batch.version>3.0.9-03</groovy-eclipse-batch.version>
|
||||
</properties>
|
||||
|
@ -1,61 +1,71 @@
|
||||
package com.baeldung.io
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import groovy.io.FileType
|
||||
import groovy.io.FileVisitResult
|
||||
import org.junit.Test
|
||||
|
||||
import static org.junit.Assert.assertTrue
|
||||
|
||||
class TraverseFileTreeUnitTest {
|
||||
@Test
|
||||
void whenUsingEachFile_filesAreListed() {
|
||||
var files = []
|
||||
new File('src/main/resources').eachFile { file ->
|
||||
println file.name
|
||||
files.add(file.name)
|
||||
}
|
||||
assertTrue(files.size() > 1)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void whenUsingEachFileOnAFile_anErrorOccurs() {
|
||||
var files = []
|
||||
new File('src/main/resources/ioInput.txt').eachFile { file ->
|
||||
println file.name
|
||||
files.add(file.name)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEachFileMatch_filesAreListed() {
|
||||
var files = []
|
||||
new File('src/main/resources').eachFileMatch(~/io.*\.txt/) { file ->
|
||||
println file.name
|
||||
files.add(file.name)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEachFileRecurse_thenFilesInSubfoldersAreListed() {
|
||||
var files = []
|
||||
new File('src/main').eachFileRecurse(FileType.FILES) { file ->
|
||||
println "$file.parent $file.name"
|
||||
files.add("$file.parent $file.name")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEachFileRecurse_thenDirsInSubfoldersAreListed() {
|
||||
var files = []
|
||||
new File('src/main').eachFileRecurse(FileType.DIRECTORIES) { file ->
|
||||
println "$file.parent $file.name"
|
||||
files.add("$file.parent $file.name")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEachDirRecurse_thenDirsAndSubDirsAreListed() {
|
||||
var files = []
|
||||
new File('src/main').eachDirRecurse { dir ->
|
||||
println "$dir.parent $dir.name"
|
||||
files.add("$dir.parent $dir.name")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingTraverse_thenDirectoryIsTraversed() {
|
||||
var files = []
|
||||
new File('src/main').traverse { file ->
|
||||
if (file.directory && file.name == 'groovy') {
|
||||
FileVisitResult.SKIP_SUBTREE
|
||||
} else {
|
||||
println "$file.parent - $file.name"
|
||||
files.add("$file.parent - $file.name")
|
||||
}
|
||||
}
|
||||
assertTrue(files.size() > 1)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package groovy.com.baeldung.stringtypes
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import static org.junit.Assert.assertFalse
|
||||
|
||||
class DollarSlashyString {
|
||||
|
||||
@Test
|
||||
@ -19,6 +21,7 @@ class DollarSlashyString {
|
||||
- $/$$
|
||||
/$
|
||||
|
||||
print(dollarSlashy)
|
||||
//print(dollarSlashy)
|
||||
assertFalse(dollarSlashy.isEmpty())
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-10</artifactId>
|
||||
<name>core-java-10</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-10</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-11-2</artifactId>
|
||||
<name>core-java-11-2</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-11-2</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
@ -15,11 +15,6 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-junit-jupiter</artifactId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-11-3</artifactId>
|
||||
<name>core-java-11-3</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-11-3</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
@ -45,7 +45,6 @@
|
||||
<properties>
|
||||
<maven.compiler.source.version>11</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>11</maven.compiler.target.version>
|
||||
<jackson.version>2.16.0</jackson.version>
|
||||
<gson.version>2.10.1</gson.version>
|
||||
</properties>
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-11</artifactId>
|
||||
<name>core-java-11</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-11</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
@ -15,11 +15,6 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-12</artifactId>
|
||||
<name>core-java-12</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-12</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-13</artifactId>
|
||||
<name>core-java-13</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-13</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-14</artifactId>
|
||||
<name>core-java-14</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-14</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-15</artifactId>
|
||||
<name>core-java-15</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-15</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
@ -13,7 +13,6 @@
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-16</artifactId>
|
||||
<name>core-java-16</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-16</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-17</artifactId>
|
||||
<name>core-java-17</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-17</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
@ -1,2 +1,3 @@
|
||||
## Relevant Articles
|
||||
- [Deprecate Finalization in Java 18](https://www.baeldung.com/java-18-deprecate-finalization)
|
||||
- [Simple Web Server in Java 18](https://www.baeldung.com/simple-web-server-java-18)
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-18</artifactId>
|
||||
<name>core-java-18</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-18</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
@ -0,0 +1,59 @@
|
||||
package com.baeldung.simplewebserver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.sun.net.httpserver.Filter;
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpHandlers;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.Request;
|
||||
import com.sun.net.httpserver.SimpleFileServer;
|
||||
|
||||
public class WebServer {
|
||||
|
||||
private final InetSocketAddress address = new InetSocketAddress(8080);
|
||||
private final Path path = Path.of("/");
|
||||
|
||||
public static void main(String[] args) {
|
||||
WebServer webServer = new WebServer();
|
||||
HttpServer server = webServer.createWithHandler401Response();
|
||||
server.start();
|
||||
}
|
||||
|
||||
private HttpServer createBasic() {
|
||||
return SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
|
||||
}
|
||||
|
||||
private HttpServer createWithHandler() throws IOException {
|
||||
HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
|
||||
HttpHandler handler = SimpleFileServer.createFileHandler(Path.of("/Users"));
|
||||
server.createContext("/test", handler);
|
||||
return server;
|
||||
}
|
||||
|
||||
private HttpServer createWithHandler401Response() {
|
||||
Predicate<Request> findAllowedPath = r -> r.getRequestURI()
|
||||
.getPath()
|
||||
.equals("/test/allowed");
|
||||
|
||||
HttpHandler allowedResponse = HttpHandlers.of(200, Headers.of("Allow", "GET"), "Welcome");
|
||||
HttpHandler deniedResponse = HttpHandlers.of(401, Headers.of("Deny", "GET"), "Denied");
|
||||
|
||||
HttpHandler handler = HttpHandlers.handleOrElse(findAllowedPath, allowedResponse, deniedResponse);
|
||||
|
||||
HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
|
||||
server.createContext("/test", handler);
|
||||
return server;
|
||||
}
|
||||
|
||||
private HttpServer createWithFilter() throws IOException {
|
||||
Filter filter = SimpleFileServer.createOutputFilter(System.out, SimpleFileServer.OutputLevel.INFO);
|
||||
HttpHandler handler = SimpleFileServer.createFileHandler(Path.of("/Users"));
|
||||
return HttpServer.create(new InetSocketAddress(8080), 10, "/test", handler, filter);
|
||||
}
|
||||
|
||||
}
|
@ -4,8 +4,8 @@
|
||||
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-8-datetime-2</artifactId>
|
||||
<name>core-java-8-datetime-2</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-8-datetime-2</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-8-datetime</artifactId>
|
||||
<name>core-java-8-datetime</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-8-datetime</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
|
@ -5,7 +5,7 @@ This module contains articles about Project Jigsaw and the Java Platform Module
|
||||
### Relevant Articles:
|
||||
|
||||
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
|
||||
- [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity)
|
||||
- [A Guide to Java Modularity](https://www.baeldung.com/java-modularity)
|
||||
- [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api)
|
||||
- [Java 9 Illegal Reflective Access Warning](https://www.baeldung.com/java-illegal-reflective-access)
|
||||
- [Java Modularity and Unit Testing](https://www.baeldung.com/java-modularity-unit-testing)
|
||||
|
@ -3,20 +3,14 @@
|
||||
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>library-core</artifactId>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-9-jigsaw</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>library-core</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>19</maven.compiler.source>
|
||||
<maven.compiler.target>19</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
@ -52,4 +46,11 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>19</maven.compiler.source>
|
||||
<maven.compiler.target>19</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -4,8 +4,9 @@
|
||||
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-9-jigsaw</artifactId>
|
||||
<name>core-java-9-jigsaw</name>
|
||||
<packaging>pom</packaging>
|
||||
<name>core-java-9-jigsaw</name>
|
||||
|
||||
<modules>
|
||||
<module>library-core</module>
|
||||
</modules>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-9-streams</artifactId>
|
||||
<name>core-java-9-streams</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-9-streams</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
|
@ -4,8 +4,8 @@
|
||||
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-annotations</artifactId>
|
||||
<name>core-java-annotations</name>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-annotations</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
|
@ -0,0 +1,95 @@
|
||||
package com.baeldung.majorityelement;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class FindMajorityElement {
|
||||
|
||||
public static Integer findMajorityElementUsingForLoop(int[] nums) {
|
||||
int majorityThreshold = nums.length / 2;
|
||||
Integer majorityElement = null;
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
int count = 0;
|
||||
for (int j = 0; j < nums.length; j++) {
|
||||
if (nums[i] == nums[j]) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > majorityThreshold) {
|
||||
return majorityElement = nums[i];
|
||||
}
|
||||
}
|
||||
return majorityElement;
|
||||
}
|
||||
|
||||
public static Integer findMajorityElementUsingSorting(int[] nums) {
|
||||
Arrays.sort(nums);
|
||||
int majorityThreshold = nums.length / 2;
|
||||
int count = 0;
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
if (nums[i] == nums[majorityThreshold]) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count > majorityThreshold) {
|
||||
return nums[majorityThreshold];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Integer findMajorityElementUsingHashMap(int[] nums) {
|
||||
Map<Integer, Integer> frequencyMap = new HashMap<>();
|
||||
|
||||
for (int num : nums) {
|
||||
frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
|
||||
}
|
||||
|
||||
int majorityThreshold = nums.length / 2;
|
||||
for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {
|
||||
if (entry.getValue() > majorityThreshold) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Integer findMajorityElementUsingMooreVoting(int[] nums) {
|
||||
int majorityThreshold = nums.length / 2;
|
||||
int candidate = nums[0];
|
||||
int count = 1;
|
||||
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
if (count == 0) {
|
||||
candidate = nums[i];
|
||||
count = 1;
|
||||
} else if (candidate == nums[i]) {
|
||||
count++;
|
||||
} else {
|
||||
count--;
|
||||
}
|
||||
|
||||
System.out.println("Iteration " + i + ": [candidate - " + candidate + ", count - " + count + ", element - " + nums[i] + "]");
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for (int num : nums) {
|
||||
if (num == candidate) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count > majorityThreshold ? candidate : null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] nums = { 2, 3, 2, 4, 2, 5, 2 };
|
||||
Integer majorityElement = findMajorityElementUsingMooreVoting(nums);
|
||||
|
||||
if (majorityElement != null) {
|
||||
System.out.println("Majority element with maximum occurrences: " + majorityElement);
|
||||
} else {
|
||||
System.out.println("No majority element found");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.baeldung.majorityelement;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class FindMajorityElementUnitTest {
|
||||
|
||||
@Test
|
||||
void givenArrayWithMajorityElement_WhenUsingForLoop_ThenReturnFound() {
|
||||
int[] nums = { 2, 3, 2, 4, 2, 5, 2 };
|
||||
Integer result = FindMajorityElement.findMajorityElementUsingForLoop(nums);
|
||||
assertEquals(2, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenArrayWithoutMajorityElement_WhenUsingForLoop_ThenNotFound() {
|
||||
int[] nums = { 2, 2, 3, 3 };
|
||||
Integer result = FindMajorityElement.findMajorityElementUsingForLoop(nums);
|
||||
assertEquals(null, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenArrayWithMajorityElement_WhenUsingSorting_ThenReturnFound() {
|
||||
int[] nums = { 2, 3, 2, 4, 2, 5, 2 };
|
||||
Integer result = FindMajorityElement.findMajorityElementUsingSorting(nums);
|
||||
assertEquals(2, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenArrayWithoutMajorityElement_WhenUsingSorting_ThenNotFound() {
|
||||
int[] nums = { 2, 2, 3, 3 };
|
||||
Integer result = FindMajorityElement.findMajorityElementUsingSorting(nums);
|
||||
assertEquals(null, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenArrayWithMajorityElement_WhenUsingHashMap_ThenReturnFound() {
|
||||
int[] nums = { 2, 3, 2, 4, 2, 5, 2 };
|
||||
Integer result = FindMajorityElement.findMajorityElementUsingHashMap(nums);
|
||||
assertEquals(2, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenArrayWithoutMajorityElement_WhenUsingHashMap_ThenNotFound() {
|
||||
int[] nums = { 2, 2, 3, 3 };
|
||||
Integer result = FindMajorityElement.findMajorityElementUsingHashMap(nums);
|
||||
assertEquals(null, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenArrayWithMajorityElement_WhenUsingMooreVoting_ThenReturnFound() {
|
||||
int[] nums = { 2, 3, 2, 4, 2, 5, 2 };
|
||||
Integer result = FindMajorityElement.findMajorityElementUsingMooreVoting(nums);
|
||||
assertEquals(2, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenArrayWithoutMajorityElement_WhenUsingMooreVoting_ThenNotFound() {
|
||||
int[] nums = { 2, 2, 3, 3 };
|
||||
Integer result = FindMajorityElement.findMajorityElementUsingMooreVoting(nums);
|
||||
assertEquals(null, result);
|
||||
}
|
||||
}
|
@ -19,12 +19,6 @@
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.1-jre</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -60,7 +60,5 @@
|
||||
<properties>
|
||||
<jmh.version>1.21</jmh.version>
|
||||
<gson.version>2.10.1</gson.version>
|
||||
<jackson.version>2.16.0</jackson.version>
|
||||
<org.json.version>20230618</org.json.version>
|
||||
</properties>
|
||||
</project>
|
@ -4,3 +4,4 @@
|
||||
- [Call a Method on Each Element of a List in Java](https://www.baeldung.com/java-call-method-each-list-item)
|
||||
- [Sorting One List Based on Another List in Java](https://www.baeldung.com/java-sorting-one-list-using-another)
|
||||
- [Reset ListIterator to First Element of the List in Java](https://www.baeldung.com/java-reset-listiterator)
|
||||
- [Modify and Print List Items With Java Streams](https://www.baeldung.com/java-stream-list-update-print-elements)
|
||||
|
@ -14,11 +14,6 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vavr</groupId>
|
||||
<artifactId>vavr</artifactId>
|
||||
|
@ -0,0 +1,54 @@
|
||||
package com.baeldung.modifyandprint;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class ModifyAndPrintListElementsUnitTest {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(ModifyAndPrintListElementsUnitTest.class);
|
||||
|
||||
@Test
|
||||
void whenPrintingInForEach_thenListIsPrinted() {
|
||||
List<String> theList = Lists.newArrayList("Kai", "Liam", "Eric", "Kevin");
|
||||
theList.forEach(element -> log.info(element));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingModifyAndPrintingSeparately_thenListIsModifiedAndPrinted() {
|
||||
List<String> theList = Lists.newArrayList("Kai", "Liam", "Eric", "Kevin");
|
||||
theList.replaceAll(element -> element.toUpperCase());
|
||||
theList.forEach(element -> log.info(element));
|
||||
assertEquals(List.of("KAI", "LIAM", "ERIC", "KEVIN"), theList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPrintingInMap_thenStreamIsModifiedAndPrinted() {
|
||||
List<String> theList = List.of("Kai", "Liam", "Eric", "Kevin");
|
||||
List<String> newList = theList.stream()
|
||||
.map(element -> {
|
||||
String newElement = element.toUpperCase();
|
||||
log.info(newElement);
|
||||
return newElement;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(List.of("KAI", "LIAM", "ERIC", "KEVIN"), newList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPrintingInPeek_thenStreamIsModifiedAndPrinted() {
|
||||
List<String> theList = List.of("Kai", "Liam", "Eric", "Kevin");
|
||||
List<String> newList = theList.stream()
|
||||
.map(element -> element.toUpperCase())
|
||||
.peek(element-> log.info(element))
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(List.of("KAI", "LIAM", "ERIC", "KEVIN"), newList);
|
||||
}
|
||||
}
|
@ -24,11 +24,6 @@
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
@ -32,7 +32,7 @@
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20230227</version>
|
||||
<version>${org.json.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
@ -1,6 +1,5 @@
|
||||
## Relevant Articles:
|
||||
- [Difference Between putIfAbsent() and computeIfAbsent() in Java’s Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent)
|
||||
- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/how-to-write-and-read-a-file-with-a-java-hashmap/)
|
||||
- [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv)
|
||||
- [How to Get First or Last Entry From a LinkedHashMap in Java](https://www.baeldung.com/java-linkedhashmap-first-last-key-value-pair)
|
||||
- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/java-hashmap-write-read-file)
|
||||
@ -8,4 +7,5 @@
|
||||
- [How to Sort LinkedHashMap by Values in Java](https://www.baeldung.com/java-sort-linkedhashmap-using-values)
|
||||
- [How to Increment a Map Value in Java](https://www.baeldung.com/java-increment-map-value)
|
||||
- [Collect Stream of entrySet() to a LinkedHashMap](https://www.baeldung.com/java-linkedhashmap-entryset-stream)
|
||||
- [How to Pretty-Print a Map in Java](https://www.baeldung.com/java-map-pretty-print)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-6)
|
||||
|
@ -29,20 +29,21 @@
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>${csv.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>32.1.2-jre</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>1.37</version>
|
||||
<version>${jmh.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>1.37</version>
|
||||
<version>${jmh.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@ -63,6 +64,9 @@
|
||||
<properties>
|
||||
<gson.version>2.10.1</gson.version>
|
||||
<csv.version>1.5</csv.version>
|
||||
<guava.version>32.1.2-jre</guava.version>
|
||||
<jmh.version>1.37</jmh.version>
|
||||
<commons-collections.version>4.4</commons-collections.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
@ -0,0 +1,202 @@
|
||||
package com.baeldung.map.prettyprintmap;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class PrettyPrintMapUnitTest {
|
||||
|
||||
private static final Map<String, Object> MAP;
|
||||
|
||||
static {
|
||||
// using LinkedHashMap to keep insertion order, helpful in assertions
|
||||
MAP = new LinkedHashMap<>();
|
||||
MAP.put("one", 1);
|
||||
MAP.put("two", 2);
|
||||
|
||||
Map<String, Integer> innerMap = new LinkedHashMap<>();
|
||||
innerMap.put("ten", 10);
|
||||
innerMap.put("eleven", 11);
|
||||
|
||||
MAP.put("inner", innerMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenToString_thenOneLine() {
|
||||
String result = MAP.toString();
|
||||
|
||||
String expected = "{one=1, two=2, inner={ten=10, eleven=11}}";
|
||||
Assertions.assertThat(result).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenSimpleForEachLoop_thenPrettyPrintWithoutNested() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
for (Map.Entry<?, ?> entry : MAP.entrySet()) {
|
||||
result.append(String.format("%-15s : %s%n", entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
String expected =
|
||||
"one : 1\n" +
|
||||
"two : 2\n" +
|
||||
"inner : {ten=10, eleven=11}\n";
|
||||
Assertions.assertThat(result.toString()).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenRecursionForEachLoop_thenPrettyPrint() {
|
||||
String result = printMap(0, MAP);
|
||||
|
||||
String expected =
|
||||
"one : 1\n" +
|
||||
"two : 2\n" +
|
||||
"inner :\n" +
|
||||
" ten : 10\n" +
|
||||
" eleven : 11\n";
|
||||
Assertions.assertThat(result).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenStream_thenPrettyPrintWithoutNested() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
MAP.forEach((k, v) -> result.append(String.format("%-15s : %s%n", k, v)));
|
||||
|
||||
String expected =
|
||||
"one : 1\n" +
|
||||
"two : 2\n" +
|
||||
"inner : {ten=10, eleven=11}\n";
|
||||
Assertions.assertThat(result.toString()).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenExtendedStream_thenPrettyPrintWithoutNested() {
|
||||
String result = MAP.entrySet().stream()
|
||||
.map(entry -> String.format("%-15s : %s", entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
String expected =
|
||||
"one : 1\n" +
|
||||
"two : 2\n" +
|
||||
"inner : {ten=10, eleven=11}\n";
|
||||
Assertions.assertThat(result).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
@Test
|
||||
void givenMap_whenJackson_thenPrettyPrint() throws JsonProcessingException {
|
||||
String result = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(MAP);
|
||||
|
||||
String expected =
|
||||
"{\n" +
|
||||
" \"one\" : 1,\n" +
|
||||
" \"two\" : 2,\n" +
|
||||
" \"inner\" : {\n" +
|
||||
" \"ten\" : 10,\n" +
|
||||
" \"eleven\" : 11\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
Assertions.assertThat(result).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenGson_thenPrettyPrint() {
|
||||
String result = new GsonBuilder().setPrettyPrinting().create().toJson(MAP);
|
||||
|
||||
String expected =
|
||||
"{\n" +
|
||||
" \"one\": 1,\n" +
|
||||
" \"two\": 2,\n" +
|
||||
" \"inner\": {\n" +
|
||||
" \"ten\": 10,\n" +
|
||||
" \"eleven\": 11\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
Assertions.assertThat(result).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenApacheCommonsCollectionsDebugPrint_thenPrettyPrintWithClassNames() throws IOException {
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(baos)) {
|
||||
|
||||
MapUtils.debugPrint(ps, "map", MAP);
|
||||
String result = baos.toString();
|
||||
|
||||
String expected =
|
||||
"map = \n" +
|
||||
"{\n" +
|
||||
" one = 1 java.lang.Integer\n" +
|
||||
" two = 2 java.lang.Integer\n" +
|
||||
" inner = \n" +
|
||||
" {\n" +
|
||||
" ten = 10 java.lang.Integer\n" +
|
||||
" eleven = 11 java.lang.Integer\n" +
|
||||
" } java.util.LinkedHashMap\n" +
|
||||
"} java.util.LinkedHashMap\n";
|
||||
Assertions.assertThat(result).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenApacheCommonsCollectionsVerbosePrint_thenPrettyPrint() throws IOException {
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(baos)) {
|
||||
|
||||
MapUtils.verbosePrint(ps, "map", MAP);
|
||||
String result = baos.toString();
|
||||
|
||||
String expected =
|
||||
"map = \n" +
|
||||
"{\n" +
|
||||
" one = 1\n" +
|
||||
" two = 2\n" +
|
||||
" inner = \n" +
|
||||
" {\n" +
|
||||
" ten = 10\n" +
|
||||
" eleven = 11\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
Assertions.assertThat(result).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMap_whenGuavaJoiner_thenPrettyPrintWithoutNested() {
|
||||
String result = Joiner.on(",\n").withKeyValueSeparator("=").join(MAP);
|
||||
|
||||
String expected =
|
||||
"one=1,\n" +
|
||||
"two=2,\n" +
|
||||
"inner={ten=10, eleven=11}";
|
||||
Assertions.assertThat(result).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
|
||||
private static String printMap(int leftPadding, Map<?, ?> map) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
if (entry.getValue() instanceof Map) {
|
||||
ret.append(String.format("%-15s :%n", entry.getKey()));
|
||||
ret.append(printMap(leftPadding + 4, (Map<?, ?>) entry.getValue()));
|
||||
}
|
||||
else {
|
||||
ret.append(String.format("%" + (leftPadding > 0 ? leftPadding : "") + "s" // adding padding
|
||||
+ "%-15s : %s%n",
|
||||
"", entry.getKey(), entry.getValue()));
|
||||
}
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.baeldung.writehashmaptocsvfile;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
@ -63,4 +64,16 @@ public class WriteHashmaptoCVSFileUnitTest {
|
||||
// Ensure the CSV file exists
|
||||
assertTrue(new File("employee_data2.csv").exists());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void cleanUp() {
|
||||
final File employeeData = new File("employee_data.csv");
|
||||
if (employeeData.exists()) {
|
||||
employeeData.deleteOnExit();
|
||||
}
|
||||
final File employeeData2 = new File("employee_data2.csv");
|
||||
if (employeeData2.exists()) {
|
||||
employeeData2.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,11 +32,6 @@
|
||||
<version>7.7.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>32.1.1-jre</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -60,14 +60,15 @@ public class HashtableUnitTest {
|
||||
table.put(new Word("dog"), "another animal");
|
||||
|
||||
Iterator<Word> it = table.keySet().iterator();
|
||||
System.out.println("iterator created");
|
||||
// System.out.println("iterator created");
|
||||
|
||||
table.remove(new Word("dog"));
|
||||
System.out.println("element removed");
|
||||
// System.out.println("element removed");
|
||||
|
||||
while (it.hasNext()) {
|
||||
Word key = it.next();
|
||||
System.out.println(table.get(key));
|
||||
// System.out.println(table.get(key));
|
||||
assertNotNull(table.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,12 +86,13 @@ public class HashtableUnitTest {
|
||||
table.put(new Word("8"), "eight");
|
||||
|
||||
Enumeration<Word> enumKey = table.keys();
|
||||
System.out.println("Enumeration created");
|
||||
// System.out.println("Enumeration created");
|
||||
table.remove(new Word("1"));
|
||||
System.out.println("element removed");
|
||||
// System.out.println("element removed");
|
||||
while (enumKey.hasMoreElements()) {
|
||||
Word key = enumKey.nextElement();
|
||||
System.out.println(table.get(key));
|
||||
// System.out.println(table.get(key));
|
||||
assertNotNull(table.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +112,8 @@ public class HashtableUnitTest {
|
||||
Iterator<Map.Entry<Word, String>> it = table.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<Word, String> entry = it.next();
|
||||
System.out.println(entry.getValue());
|
||||
// System.out.println(entry.getValue());
|
||||
assertNotNull(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
package com.baeldung.listiteration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
|
||||
|
||||
public class ListIterationUnitTest {
|
||||
|
||||
List<String> programmingLanguages = new ArrayList<>(List.of("Java", "Python", "C++"));
|
||||
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
|
||||
|
||||
@Test
|
||||
public void givenStringList_whenAddElementWithListIterator_thenModifiedList() {
|
||||
ListIterator<String> listIterator = programmingLanguages.listIterator();
|
||||
while (listIterator.hasNext()) {
|
||||
String language = listIterator.next();
|
||||
if (language.equals("Python")) {
|
||||
listIterator.add("JavaScript");
|
||||
}
|
||||
}
|
||||
|
||||
assertIterableEquals(Arrays.asList("Java", "Python", "JavaScript", "C++"), programmingLanguages);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNumericalList_whenMultiplyElementWithListIterator_thenModifiedList() {
|
||||
ListIterator<Integer> listIterator = numbers.listIterator();
|
||||
while (listIterator.hasNext()) {
|
||||
int num = listIterator.next();
|
||||
if (num == 2) {
|
||||
listIterator.add(num * 10);
|
||||
}
|
||||
}
|
||||
assertIterableEquals(Arrays.asList(1, 2, 20, 3), numbers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringList_whenAddElementWithEnhancedForLoopAndCopy_thenModifiedList() {
|
||||
List<String> copyOfWords = new ArrayList<>(programmingLanguages);
|
||||
for (String word : copyOfWords) {
|
||||
programmingLanguages.add(word.toUpperCase()); // Modified: Convert to uppercase
|
||||
}
|
||||
assertIterableEquals(Arrays.asList("Java", "Python", "C++", "JAVA", "PYTHON", "C++"), programmingLanguages);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNumericalList_whenMultiplyElementWithEnhancedForLoopAndCopy_thenModifiedList() {
|
||||
List<Integer> copyOfNumbers = new ArrayList<>(numbers);
|
||||
for (int num : copyOfNumbers) {
|
||||
numbers.add(num * 2);
|
||||
}
|
||||
assertIterableEquals(Arrays.asList(1, 2, 3, 2, 4, 6), numbers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringList_whenConvertToUpperCaseWithJava8Stream_thenModifiedList() {
|
||||
programmingLanguages = programmingLanguages.stream().map(String::toUpperCase).collect(Collectors.toList());
|
||||
assertIterableEquals(Arrays.asList("JAVA", "PYTHON", "C++"), programmingLanguages);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNumericalList_whenMultiplyByThreeWithJava8Stream_thenModifiedList() {
|
||||
numbers = numbers.stream().map(num -> num * 3).collect(Collectors.toList());
|
||||
assertIterableEquals(Arrays.asList(3, 6, 9), numbers);
|
||||
}
|
||||
|
||||
}
|
@ -9,3 +9,5 @@
|
||||
- [Parallelize for Loop in Java](https://www.baeldung.com/java-for-loop-parallel)
|
||||
- [How to Effectively Unit Test CompletableFuture](https://www.baeldung.com/java-completablefuture-unit-test)
|
||||
- [How to Collect All Results and Handle Exceptions With CompletableFuture in a Loop](https://www.baeldung.com/java-completablefuture-collect-results-handle-exceptions)
|
||||
- [CompletableFuture runAsync() vs. supplyAsync() in Java](https://www.baeldung.com/java-completablefuture-runasync-supplyasync)
|
||||
- [Difference Between thenApply() and thenApplyAsync() in CompletableFuture](https://www.baeldung.com/java-completablefuture-thenapply-thenapplyasync)
|
||||
|
@ -0,0 +1,79 @@
|
||||
package com.baeldung.runvssupply;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class RunAndSupplyCompare {
|
||||
|
||||
public static void main(String args[]) throws ExecutionException, InterruptedException {
|
||||
chainingOperationCompare();
|
||||
}
|
||||
|
||||
public static void inputAndReturnCompare() throws ExecutionException, InterruptedException {
|
||||
CompletableFuture<Void> runAsyncFuture = CompletableFuture.runAsync(() -> {
|
||||
// Perform non-result producing task
|
||||
System.out.println("Task executed asynchronously");
|
||||
});
|
||||
|
||||
CompletableFuture<String> supplyAsyncFuture = CompletableFuture.supplyAsync(() -> {
|
||||
// Perform result-producing task
|
||||
return "Result of the asynchronous computation";
|
||||
});
|
||||
// Get the result later
|
||||
String result = supplyAsyncFuture.get();
|
||||
System.out.println("Result: " + result);
|
||||
}
|
||||
|
||||
public static void exceptionHandlingCompare() {
|
||||
CompletableFuture<Void> runAsyncFuture = CompletableFuture.runAsync(() -> {
|
||||
// Task that may throw an exception
|
||||
throw new RuntimeException("Exception occurred in asynchronous task");
|
||||
});
|
||||
try {
|
||||
runAsyncFuture.get();
|
||||
// Exception will be thrown here
|
||||
} catch (ExecutionException ex) {
|
||||
Throwable cause = ex.getCause();
|
||||
System.out.println("Exception caught: " + cause.getMessage());
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
CompletableFuture<Object> supplyAsyncFuture = CompletableFuture.supplyAsync(() -> {
|
||||
// Task that may throw an exception
|
||||
throw new RuntimeException("Exception occurred in asynchronous task");
|
||||
})
|
||||
.exceptionally(ex -> {
|
||||
// Exception handling logic
|
||||
return "Default value";
|
||||
});
|
||||
|
||||
Object result = supplyAsyncFuture.join();
|
||||
// Get the result or default value
|
||||
System.out.println("Result: " + result);
|
||||
}
|
||||
|
||||
public static void chainingOperationCompare() {
|
||||
CompletableFuture<Void> runAsyncFuture = CompletableFuture.runAsync(() -> {
|
||||
// Perform non-result producing task
|
||||
System.out.println("Task executed asynchronously");
|
||||
});
|
||||
runAsyncFuture.thenRun(() -> {
|
||||
// Execute another task after the completion of runAsync()
|
||||
System.out.println("Another task executed after runAsync() completes");
|
||||
});
|
||||
|
||||
CompletableFuture<String> supplyAsyncFuture = CompletableFuture.supplyAsync(() -> {
|
||||
// Perform result-producing task
|
||||
return "Result of the asynchronous computation";
|
||||
});
|
||||
supplyAsyncFuture.thenApply(result -> {
|
||||
// Transform the result
|
||||
return result.toUpperCase();
|
||||
})
|
||||
.thenAccept(transformedResult -> {
|
||||
// Consume the transformed result
|
||||
System.out.println("Transformed Result: " + transformedResult);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package com.baeldung.concurrent.applyvsapplyasync;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class ThenApplyAndThenApplyAsyncUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenCompletableFuture_whenUsingThenApply_thenResultIsAsExpected() {
|
||||
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5);
|
||||
CompletableFuture<String> thenApplyResultFuture = future.thenApply(num -> "Result: " + num);
|
||||
|
||||
String thenApplyResult = thenApplyResultFuture.join();
|
||||
assertEquals("Result: 5", thenApplyResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCompletableFuture_whenUsingThenApplyAsync_thenResultIsAsExpected() {
|
||||
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5);
|
||||
CompletableFuture<String> thenApplyAsyncResultFuture = future.thenApplyAsync(num -> "Result: " + num);
|
||||
|
||||
String thenApplyAsyncResult = thenApplyAsyncResultFuture.join();
|
||||
assertEquals("Result: 5", thenApplyAsyncResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCompletableFuture_whenUsingThenApply_thenExceptionIsPropagated() {
|
||||
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5);
|
||||
CompletableFuture<String> resultFuture = future.thenApply(num -> "Result: " + num / 0);
|
||||
assertThrows(CompletionException.class, () -> resultFuture.join());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCompletableFuture_whenUsingThenApply_thenExceptionIsHandledAsExpected() {
|
||||
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5);
|
||||
CompletableFuture<String> resultFuture = future.thenApply(num -> "Result: " + num / 0);
|
||||
try {
|
||||
// Accessing the result
|
||||
String result = resultFuture.join();
|
||||
assertEquals("Result: 5", result);
|
||||
} catch (CompletionException e) {
|
||||
assertEquals("java.lang.ArithmeticException: / by zero", e.getMessage());
|
||||
System.err.println("Exception caught: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCompletableFuture_whenUsingThenApplyAsync_thenExceptionIsHandledAsExpected() {
|
||||
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5);
|
||||
CompletableFuture<String> thenApplyAsyncResultFuture = future.thenApplyAsync(num -> "Result: " + num / 0);
|
||||
|
||||
String result = thenApplyAsyncResultFuture.handle((res, error) -> {
|
||||
if (error != null) {
|
||||
// Handle the error appropriately, e.g., return a default value
|
||||
return "Error occurred";
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
})
|
||||
.join(); // Now join() won't throw the exception
|
||||
assertEquals("Error occurred", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCompletableFutureWithExecutor_whenUsingThenApplyAsync_thenThreadExecutesAsExpected() {
|
||||
ExecutorService customExecutor = Executors.newFixedThreadPool(4);
|
||||
|
||||
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 5;
|
||||
}, customExecutor);
|
||||
|
||||
CompletableFuture<String> resultFuture = future.thenApplyAsync(num -> "Result: " + num, customExecutor);
|
||||
|
||||
String result = resultFuture.join();
|
||||
assertEquals("Result: 5", result);
|
||||
|
||||
customExecutor.shutdown();
|
||||
}
|
||||
}
|
@ -3,3 +3,4 @@
|
||||
- [Why wait() Requires Synchronization?](https://www.baeldung.com/java-wait-necessary-synchronization)
|
||||
- [Working with Exceptions in Java CompletableFuture](https://www.baeldung.com/java-exceptions-completablefuture)
|
||||
- [CountDownLatch vs. Semaphore](https://www.baeldung.com/java-countdownlatch-vs-semaphore)
|
||||
- [Callbacks in ListenableFuture and CompletableFuture](https://www.baeldung.com/java-callbacks-listenablefuture-completablefuture)
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
@ -4,7 +4,7 @@ import java.util.function.Function;
|
||||
|
||||
public class Currying {
|
||||
|
||||
private static Function<Double, Function<Double, Double>> weight = mass -> gravity -> mass * gravity;
|
||||
private static Function<Double, Function<Double, Double>> weight = gravity -> mass -> mass * gravity;
|
||||
|
||||
private static Function<Double, Double> weightOnEarth = weight.apply(9.81);
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<logger name="org.eclipse.jetty.server.handler" level="WARN"/>
|
||||
<logger name="org.mockserver.log" level="WARN"/>
|
||||
</configuration>
|
@ -25,11 +25,6 @@
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
@ -9,5 +9,6 @@ This module contains articles about core Java input and output (IO)
|
||||
- [How to Write Strings to OutputStream in Java](https://www.baeldung.com/java-write-string-outputstream)
|
||||
- [Read a File and Split It Into Multiple Files in Java](https://www.baeldung.com/java-read-file-split-into-several)
|
||||
- [Read and Write Files in Java Using Separate Threads](https://www.baeldung.com/java-read-write-files-different-threads)
|
||||
- [Convert an OutputStream to a Byte Array in Java](https://www.baeldung.com/java-outputstream-byte-array)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io-4)
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>${json.version}</version>
|
||||
<version>${org.json.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.opencsv</groupId>
|
||||
@ -55,7 +55,6 @@
|
||||
<properties>
|
||||
<source.version>11</source.version>
|
||||
<target.version>11</target.version>
|
||||
<json.version>20200518</json.version>
|
||||
<opencsv.version>5.8</opencsv.version>
|
||||
</properties>
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<compiler.plugin.version>3.8.0</compiler.plugin.version>
|
||||
<compiler.plugin.version>3.12.1</compiler.plugin.version>
|
||||
<source.version>11</source.version>
|
||||
<target.version>11</target.version>
|
||||
</properties>
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.plugin.version>3.8.0</compiler.plugin.version>
|
||||
<compiler.plugin.version>3.12.1</compiler.plugin.version>
|
||||
<source.version>11</source.version>
|
||||
<target.version>11</target.version>
|
||||
</properties>
|
||||
|
@ -17,4 +17,5 @@
|
||||
- [Validate if a String Is a Valid Geo Coordinate](https://www.baeldung.com/java-geo-coordinates-validation)
|
||||
- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point)
|
||||
- [Calculating the Power of Any Number in Java Without Using Math pow() Method](https://www.baeldung.com/java-calculating-the-power-without-math-pow)
|
||||
- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem)
|
||||
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
|
||||
|
@ -14,4 +14,4 @@ This module contains articles about networking in Java
|
||||
- [Handling java.net.ConnectException](https://www.baeldung.com/java-net-connectexception)
|
||||
- [Getting MAC Addresses in Java](https://www.baeldung.com/java-mac-address)
|
||||
- [Sending Emails with Attachments in Java](https://www.baeldung.com/java-send-emails-attachments)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-networking)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-networking) [[Next --> ]](/core-java-modules/core-java-networking-3)
|
||||
|
@ -14,4 +14,4 @@ This module contains articles about networking in Java
|
||||
- [Get Domain Name From Given URL in Java](https://www.baeldung.com/java-domain-name-from-url)
|
||||
- [Java HttpClient Timeout](https://www.baeldung.com/java-httpclient-timeout)
|
||||
- [Port Scanning With Java](https://www.baeldung.com/java-port-scanning)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-networking-2)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-networking-2) [[Next --> ]](/core-java-modules/core-java-networking-4)
|
||||
|
@ -52,12 +52,6 @@
|
||||
<artifactId>java-ipv6</artifactId>
|
||||
<version>${googlecode.ipv6.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/commons-validator/commons-validator -->
|
||||
<dependency>
|
||||
<groupId>commons-validator</groupId>
|
||||
|
@ -8,3 +8,4 @@
|
||||
- [Normalize a URL in Java](https://www.baeldung.com/java-url-normalization)
|
||||
- [Translating Space Characters in URLEncoder](https://www.baeldung.com/java-urlencoder-translate-space-characters)
|
||||
- [Creating a Custom URL Connection](https://www.baeldung.com/java-custom-url-connection)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-networking-3)
|
@ -17,46 +17,43 @@
|
||||
<dependency>
|
||||
<groupId>commons-validator</groupId>
|
||||
<artifactId>commons-validator</artifactId>
|
||||
<version>${apache.commons-validator.version}</version>
|
||||
<version>${commons-validator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>${jsoup.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.2</version>
|
||||
<version>${httpclient.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<version>${javax.ws.rs-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-common</artifactId>
|
||||
<version>2.22.2</version>
|
||||
<version>${jersey-common.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>6.0.6</version>
|
||||
<version>${spring-web.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-networking-4</finalName>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<apache.commons-validator.version>1.7</apache.commons-validator.version>
|
||||
<jsoup.version>1.16.2</jsoup.version>
|
||||
<commons-validator.version>1.7</commons-validator.version>
|
||||
<jsoup.version>1.17.2</jsoup.version>
|
||||
<httpclient.version>4.5.2</httpclient.version>
|
||||
<javax.ws.rs-api.version>2.1.1</javax.ws.rs-api.version>
|
||||
<jersey-common.version>2.22.2</jersey-common.version>
|
||||
<spring-web.version>6.0.6</spring-web.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,72 @@
|
||||
package com.baeldung.obtainlastsegmentofurl;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class ObtainLastSegmentOfURLUnitTest {
|
||||
@Test
|
||||
public void givenURL_whenUsingURIClass_thenGetLastPathSegment() throws URISyntaxException {
|
||||
URI uri = new URI("https://www.example.com/path/to/resource");
|
||||
String path = uri.getPath();
|
||||
|
||||
String[] segments = path.split("/");
|
||||
String lastSegment = segments[segments.length - 1];
|
||||
|
||||
assertEquals("resource", lastSegment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenURL_whenUsingPathClass_thenGetLastPathSegment() {
|
||||
String exampleURI = "https://www.example.com/path/to/resource";
|
||||
|
||||
try {
|
||||
URI uri = new URI(exampleURI);
|
||||
String pathString = uri.getPath();
|
||||
Path path = Paths.get(pathString);
|
||||
Path lastSegment = path.getName(path.getNameCount() - 1);
|
||||
|
||||
assertEquals("resource", lastSegment.toString());
|
||||
} catch (Exception e) {
|
||||
fail("Exception occurred: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenURL_whenUsingRegularExpression_thenGetLastPathSegment() throws URISyntaxException {
|
||||
URI uri = new URI("https://www.example.com/path/to/resource");
|
||||
String path = uri.getPath();
|
||||
|
||||
Pattern pattern = Pattern.compile(".*/(.+)");
|
||||
Matcher matcher = pattern.matcher(path);
|
||||
|
||||
if (!matcher.find()) {
|
||||
fail("Regex pattern didn't match.");
|
||||
}
|
||||
|
||||
String lastSegment = matcher.group(1);
|
||||
assertEquals("resource", lastSegment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenURL_whenUsingFilenameUtilsClass_thenGetLastPathSegment() throws URISyntaxException {
|
||||
String exampleURI = "https://www.example.com/path/to/resource";
|
||||
|
||||
URI uri = new URI(exampleURI);
|
||||
String path = uri.getPath();
|
||||
|
||||
String lastSegment = FilenameUtils.getName(path);
|
||||
|
||||
assertEquals("resource", lastSegment);
|
||||
}
|
||||
}
|
@ -23,11 +23,6 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user