Merge remote-tracking branch 'central/master'
This commit is contained in:
commit
2db8ba463e
2
.gitignore
vendored
2
.gitignore
vendored
@ -41,3 +41,5 @@ SpringDataInjectionDemo/.mvn/wrapper/maven-wrapper.properties
|
|||||||
spring-call-getters-using-reflection/.mvn/wrapper/maven-wrapper.properties
|
spring-call-getters-using-reflection/.mvn/wrapper/maven-wrapper.properties
|
||||||
|
|
||||||
spring-check-if-a-property-is-null/.mvn/wrapper/maven-wrapper.properties
|
spring-check-if-a-property-is-null/.mvn/wrapper/maven-wrapper.properties
|
||||||
|
*.springBeans
|
||||||
|
|
||||||
|
@ -23,4 +23,4 @@ Any IDE can be used to work with the projects, but if you're using Eclipse, cons
|
|||||||
|
|
||||||
CI - Jenkins
|
CI - Jenkins
|
||||||
================================
|
================================
|
||||||
This tutorials project is being built **[>> HERE](https://rest-security.ci.cloudbees.com/job/tutorials/)**
|
This tutorials project is being built **[>> HERE](https://rest-security.ci.cloudbees.com/job/github%20projects%20Jobs/job/tutorials/)**
|
||||||
|
@ -8,3 +8,4 @@
|
|||||||
- [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers)
|
- [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers)
|
||||||
- [Example of Hill Climbing Algorithm](http://www.baeldung.com/java-hill-climbing-algorithm)
|
- [Example of Hill Climbing Algorithm](http://www.baeldung.com/java-hill-climbing-algorithm)
|
||||||
- [Monte Carlo Tree Search for Tic-Tac-Toe Game](http://www.baeldung.com/java-monte-carlo-tree-search)
|
- [Monte Carlo Tree Search for Tic-Tac-Toe Game](http://www.baeldung.com/java-monte-carlo-tree-search)
|
||||||
|
- [String Search Algorithms for Large Texts](http://www.baeldung.com/java-full-text-search-algorithms)
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
public class BinarySearch {
|
|
||||||
|
|
||||||
public int runBinarySearch() {
|
|
||||||
int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
|
|
||||||
int key = 6;
|
|
||||||
|
|
||||||
int low = 0;
|
|
||||||
int high = sortedArray.length - 1;
|
|
||||||
int index = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
while (low <= high) {
|
|
||||||
|
|
||||||
int mid = (low + high) / 2;
|
|
||||||
|
|
||||||
if (sortedArray[mid] < key) {
|
|
||||||
low = mid + 1;
|
|
||||||
} else if (sortedArray[mid] > key) {
|
|
||||||
high = mid - 1;
|
|
||||||
} else if (sortedArray[mid] == key) {
|
|
||||||
index = mid;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.baeldung.algorithms.binarysearch;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BinarySearch {
|
||||||
|
|
||||||
|
public int runBinarySearchIteratively(int[] sortedArray, int key, int low, int high) {
|
||||||
|
|
||||||
|
int index = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
|
||||||
|
int mid = (low + high) / 2;
|
||||||
|
|
||||||
|
if (sortedArray[mid] < key) {
|
||||||
|
low = mid + 1;
|
||||||
|
} else if (sortedArray[mid] > key) {
|
||||||
|
high = mid - 1;
|
||||||
|
} else if (sortedArray[mid] == key) {
|
||||||
|
index = mid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int runBinarySearchRecursively(int[] sortedArray, int key, int low, int high) {
|
||||||
|
|
||||||
|
int middle = (low + high) / 2;
|
||||||
|
if (high < low) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == sortedArray[middle]) {
|
||||||
|
return middle;
|
||||||
|
} else if (key < sortedArray[middle]) {
|
||||||
|
return runBinarySearchRecursively(sortedArray, key, low, middle - 1);
|
||||||
|
} else {
|
||||||
|
return runBinarySearchRecursively(sortedArray, key, middle + 1, high);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int runBinarySearchUsingJavaArrays(int[] sortedArray, Integer key) {
|
||||||
|
int index = Arrays.binarySearch(sortedArray, key);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int runBinarySearchUsingJavaCollections(List<Integer> sortedList, Integer key) {
|
||||||
|
int index = Collections.binarySearch(sortedList, key);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleDetectionBruteForce {
|
||||||
|
|
||||||
|
public static <T> CycleDetectionResult<T> detectCycle(Node<T> head) {
|
||||||
|
if (head == null) {
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> it1 = head;
|
||||||
|
int nodesTraversedByOuter = 0;
|
||||||
|
while (it1 != null && it1.next != null) {
|
||||||
|
it1 = it1.next;
|
||||||
|
nodesTraversedByOuter++;
|
||||||
|
|
||||||
|
int x = nodesTraversedByOuter;
|
||||||
|
Node<T> it2 = head;
|
||||||
|
int noOfTimesCurrentNodeVisited = 0;
|
||||||
|
|
||||||
|
while (x > 0) {
|
||||||
|
it2 = it2.next;
|
||||||
|
|
||||||
|
if (it2 == it1) {
|
||||||
|
noOfTimesCurrentNodeVisited++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noOfTimesCurrentNodeVisited == 2) {
|
||||||
|
return new CycleDetectionResult<>(true, it1);
|
||||||
|
}
|
||||||
|
|
||||||
|
x--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleDetectionByFastAndSlowIterators {
|
||||||
|
|
||||||
|
public static <T> CycleDetectionResult<T> detectCycle(Node<T> head) {
|
||||||
|
if (head == null) {
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> slow = head;
|
||||||
|
Node<T> fast = head;
|
||||||
|
|
||||||
|
while (fast != null && fast.next != null) {
|
||||||
|
slow = slow.next;
|
||||||
|
fast = fast.next.next;
|
||||||
|
|
||||||
|
if (slow == fast) {
|
||||||
|
return new CycleDetectionResult<>(true, fast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class CycleDetectionByHashing {
|
||||||
|
|
||||||
|
public static <T> CycleDetectionResult<T> detectCycle(Node<T> head) {
|
||||||
|
if (head == null) {
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Node<T>> set = new HashSet<>();
|
||||||
|
Node<T> node = head;
|
||||||
|
|
||||||
|
while (node != null) {
|
||||||
|
if (set.contains(node)) {
|
||||||
|
return new CycleDetectionResult<>(true, node);
|
||||||
|
}
|
||||||
|
set.add(node);
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleDetectionResult<T> {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<T> node;
|
||||||
|
|
||||||
|
public CycleDetectionResult(boolean cycleExists, Node<T> node) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleRemovalBruteForce {
|
||||||
|
|
||||||
|
public static <T> boolean detectAndRemoveCycle(Node<T> head) {
|
||||||
|
CycleDetectionResult<T> result = CycleDetectionByFastAndSlowIterators.detectCycle(head);
|
||||||
|
|
||||||
|
if (result.cycleExists) {
|
||||||
|
removeCycle(result.node, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.cycleExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param loopNodeParam - reference to the node where Flyods cycle
|
||||||
|
* finding algorithm ends, i.e. the fast and the slow iterators
|
||||||
|
* meet.
|
||||||
|
* @param head - reference to the head of the list
|
||||||
|
*/
|
||||||
|
private static <T> void removeCycle(Node<T> loopNodeParam, Node<T> head) {
|
||||||
|
Node<T> it = head;
|
||||||
|
|
||||||
|
while (it != null) {
|
||||||
|
if (isNodeReachableFromLoopNode(it, loopNodeParam)) {
|
||||||
|
Node<T> loopStart = it;
|
||||||
|
findEndNodeAndBreakCycle(loopStart);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
it = it.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> boolean isNodeReachableFromLoopNode(Node<T> it, Node<T> loopNodeParam) {
|
||||||
|
Node<T> loopNode = loopNodeParam;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (it == loopNode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
loopNode = loopNode.next;
|
||||||
|
} while (loopNode.next != loopNodeParam);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void findEndNodeAndBreakCycle(Node<T> loopStartParam) {
|
||||||
|
Node<T> loopStart = loopStartParam;
|
||||||
|
|
||||||
|
while (loopStart.next != loopStartParam) {
|
||||||
|
loopStart = loopStart.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
loopStart.next = null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleRemovalByCountingLoopNodes {
|
||||||
|
|
||||||
|
public static <T> boolean detectAndRemoveCycle(Node<T> head) {
|
||||||
|
CycleDetectionResult<T> result = CycleDetectionByFastAndSlowIterators.detectCycle(head);
|
||||||
|
|
||||||
|
if (result.cycleExists) {
|
||||||
|
removeCycle(result.node, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.cycleExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void removeCycle(Node<T> loopNodeParam, Node<T> head) {
|
||||||
|
int cycleLength = calculateCycleLength(loopNodeParam);
|
||||||
|
Node<T> cycleLengthAdvancedIterator = head;
|
||||||
|
Node<T> it = head;
|
||||||
|
|
||||||
|
for (int i = 0; i < cycleLength; i++) {
|
||||||
|
cycleLengthAdvancedIterator = cycleLengthAdvancedIterator.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (it.next != cycleLengthAdvancedIterator.next) {
|
||||||
|
it = it.next;
|
||||||
|
cycleLengthAdvancedIterator = cycleLengthAdvancedIterator.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
cycleLengthAdvancedIterator.next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> int calculateCycleLength(Node<T> loopNodeParam) {
|
||||||
|
Node<T> loopNode = loopNodeParam;
|
||||||
|
int length = 1;
|
||||||
|
|
||||||
|
while (loopNode.next != loopNodeParam) {
|
||||||
|
length++;
|
||||||
|
loopNode = loopNode.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleRemovalWithoutCountingLoopNodes {
|
||||||
|
|
||||||
|
public static <T> boolean detectAndRemoveCycle(Node<T> head) {
|
||||||
|
CycleDetectionResult<T> result = CycleDetectionByFastAndSlowIterators.detectCycle(head);
|
||||||
|
|
||||||
|
if (result.cycleExists) {
|
||||||
|
removeCycle(result.node, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.cycleExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void removeCycle(Node<T> meetingPointParam, Node<T> head) {
|
||||||
|
Node<T> loopNode = meetingPointParam;
|
||||||
|
Node<T> it = head;
|
||||||
|
|
||||||
|
while (loopNode.next != it.next) {
|
||||||
|
it = it.next;
|
||||||
|
loopNode = loopNode.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
loopNode.next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class Node<T> {
|
||||||
|
T data;
|
||||||
|
Node<T> next;
|
||||||
|
|
||||||
|
public static <T> Node<T> createNewNode(T data, Node<T> next) {
|
||||||
|
Node<T> node = new Node<T>();
|
||||||
|
node.data = data;
|
||||||
|
node.next = next;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void traverseList(Node<T> root) {
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> node = root;
|
||||||
|
while (node != null) {
|
||||||
|
System.out.println(node.data);
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Node<T> getTail(Node<T> root) {
|
||||||
|
if (root == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> node = root;
|
||||||
|
while (node.next != null) {
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,194 @@
|
|||||||
|
package com.baeldung.algorithms.string.search;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class StringSearchAlgorithms {
|
||||||
|
public static long getBiggerPrime(int m) {
|
||||||
|
BigInteger prime = BigInteger.probablePrime(getNumberOfBits(m) + 1, new Random());
|
||||||
|
return prime.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getLowerPrime(long number) {
|
||||||
|
BigInteger prime = BigInteger.probablePrime(getNumberOfBits(number) - 1, new Random());
|
||||||
|
return prime.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getNumberOfBits(final int number) {
|
||||||
|
return Integer.SIZE - Integer.numberOfLeadingZeros(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getNumberOfBits(final long number) {
|
||||||
|
return Long.SIZE - Long.numberOfLeadingZeros(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int simpleTextSearch(char[] pattern, char[] text) {
|
||||||
|
int patternSize = pattern.length;
|
||||||
|
int textSize = text.length;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while ((i + patternSize) <= textSize) {
|
||||||
|
int j = 0;
|
||||||
|
while (text[i + j] == pattern[j]) {
|
||||||
|
j += 1;
|
||||||
|
if (j >= patternSize)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int RabinKarpMethod(char[] pattern, char[] text) {
|
||||||
|
int patternSize = pattern.length; // m
|
||||||
|
int textSize = text.length; // n
|
||||||
|
|
||||||
|
long prime = getBiggerPrime(patternSize);
|
||||||
|
|
||||||
|
long r = 1;
|
||||||
|
for (int i = 0; i < patternSize - 1; i++) {
|
||||||
|
r *= 2;
|
||||||
|
r = r % prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
long[] t = new long[textSize];
|
||||||
|
t[0] = 0;
|
||||||
|
|
||||||
|
long pfinger = 0;
|
||||||
|
|
||||||
|
for (int j = 0; j < patternSize; j++) {
|
||||||
|
t[0] = (2 * t[0] + text[j]) % prime;
|
||||||
|
pfinger = (2 * pfinger + pattern[j]) % prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
boolean passed = false;
|
||||||
|
|
||||||
|
int diff = textSize - patternSize;
|
||||||
|
for (i = 0; i <= diff; i++) {
|
||||||
|
if (t[i] == pfinger) {
|
||||||
|
passed = true;
|
||||||
|
for (int k = 0; k < patternSize; k++) {
|
||||||
|
if (text[i + k] != pattern[k]) {
|
||||||
|
passed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passed) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < diff) {
|
||||||
|
long value = 2 * (t[i] - r * text[i]) + text[i + patternSize];
|
||||||
|
t[i + 1] = ((value % prime) + prime) % prime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int KnuthMorrisPrattSearch(char[] pattern, char[] text) {
|
||||||
|
int patternSize = pattern.length; // m
|
||||||
|
int textSize = text.length; // n
|
||||||
|
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
|
int[] shift = KnuthMorrisPrattShift(pattern);
|
||||||
|
|
||||||
|
while ((i + patternSize) <= textSize) {
|
||||||
|
while (text[i + j] == pattern[j]) {
|
||||||
|
j += 1;
|
||||||
|
if (j >= patternSize)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
i += shift[j - 1];
|
||||||
|
j = Math.max(j - shift[j - 1], 0);
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] KnuthMorrisPrattShift(char[] pattern) {
|
||||||
|
int patternSize = pattern.length;
|
||||||
|
|
||||||
|
int[] shift = new int[patternSize];
|
||||||
|
shift[0] = 1;
|
||||||
|
|
||||||
|
int i = 1, j = 0;
|
||||||
|
|
||||||
|
while ((i + j) < patternSize) {
|
||||||
|
if (pattern[i + j] == pattern[j]) {
|
||||||
|
shift[i + j] = i;
|
||||||
|
j++;
|
||||||
|
} else {
|
||||||
|
if (j == 0)
|
||||||
|
shift[i] = i + 1;
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
i = i + shift[j - 1];
|
||||||
|
j = Math.max(j - shift[j - 1], 0);
|
||||||
|
} else {
|
||||||
|
i = i + 1;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int BoyerMooreHorspoolSimpleSearch(char[] pattern, char[] text) {
|
||||||
|
int patternSize = pattern.length;
|
||||||
|
int textSize = text.length;
|
||||||
|
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
|
while ((i + patternSize) <= textSize) {
|
||||||
|
j = patternSize - 1;
|
||||||
|
while (text[i + j] == pattern[j]) {
|
||||||
|
j--;
|
||||||
|
if (j < 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int BoyerMooreHorspoolSearch(char[] pattern, char[] text) {
|
||||||
|
|
||||||
|
int shift[] = new int[256];
|
||||||
|
|
||||||
|
for (int k = 0; k < 256; k++) {
|
||||||
|
shift[k] = pattern.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < pattern.length - 1; k++) {
|
||||||
|
shift[pattern[k]] = pattern.length - 1 - k;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
|
while ((i + pattern.length) <= text.length) {
|
||||||
|
j = pattern.length - 1;
|
||||||
|
|
||||||
|
while (text[i + j] == pattern[j]) {
|
||||||
|
j -= 1;
|
||||||
|
if (j < 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = i + shift[text[i + pattern.length - 1]];
|
||||||
|
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
|
|
||||||
public class BinarySearchTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenASortedArrayOfIntegers_whenBinarySearchRunForANumber_thenGetIndexOfTheNumber() {
|
|
||||||
BinarySearch binSearch = new BinarySearch();
|
|
||||||
int expectedIndexForSearchKey = 7;
|
|
||||||
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearch());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
25
algorithms/src/test/java/algorithms/StringSearchAlgorithmsTest.java
Executable file
25
algorithms/src/test/java/algorithms/StringSearchAlgorithmsTest.java
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
package algorithms;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.string.search.StringSearchAlgorithms;
|
||||||
|
|
||||||
|
public class StringSearchAlgorithmsTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringSearchAlgorithms(){
|
||||||
|
String text = "This is some nice text.";
|
||||||
|
String pattern = "some";
|
||||||
|
|
||||||
|
int realPosition = text.indexOf(pattern);
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.simpleTextSearch(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.RabinKarpMethod(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.KnuthMorrisPrattSearch(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSimpleSearch(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSearch(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package algorithms.binarysearch;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import com.baeldung.algorithms.binarysearch.BinarySearch;
|
||||||
|
|
||||||
|
public class BinarySearchTest {
|
||||||
|
|
||||||
|
int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
|
||||||
|
int key = 6;
|
||||||
|
int expectedIndexForSearchKey = 7;
|
||||||
|
int low = 0;
|
||||||
|
int high = sortedArray.length - 1;
|
||||||
|
List<Integer> sortedList = Arrays.asList(0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenBinarySearchRunIterativelyForANumber_thenGetIndexOfTheNumber() {
|
||||||
|
BinarySearch binSearch = new BinarySearch();
|
||||||
|
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchIteratively(sortedArray, key, low, high));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenBinarySearchRunRecursivelyForANumber_thenGetIndexOfTheNumber() {
|
||||||
|
BinarySearch binSearch = new BinarySearch();
|
||||||
|
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchRecursively(sortedArray, key, low, high));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenBinarySearchRunUsingArraysClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
|
||||||
|
BinarySearch binSearch = new BinarySearch();
|
||||||
|
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaArrays(sortedArray, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedListOfIntegers_whenBinarySearchRunUsingCollectionsClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
|
||||||
|
BinarySearch binSearch = new BinarySearch();
|
||||||
|
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaCollections(sortedList, key));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleDetectionBruteForceTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleDetectionBruteForceTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_detectLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleDetectionBruteForce.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleDetectionByFastAndSlowIteratorsTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleDetectionByFastAndSlowIteratorsTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_detectLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleDetectionByHashingTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleDetectionByHashingTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_detectLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleDetectionByHashing.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
|
public class CycleDetectionTestBase {
|
||||||
|
|
||||||
|
@Parameters
|
||||||
|
public static Collection<Object[]> getLists() {
|
||||||
|
return Arrays.asList(new Object[][] {
|
||||||
|
{ createList(), false },
|
||||||
|
{ createListWithLoop(), true },
|
||||||
|
{ createListWithFullCycle(), true },
|
||||||
|
{ createListWithSingleNodeInCycle(), true }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node<Integer> createList() {
|
||||||
|
Node<Integer> root = Node.createNewNode(10, null);
|
||||||
|
|
||||||
|
for (int i = 9; i >= 1; --i) {
|
||||||
|
Node<Integer> current = Node.createNewNode(i, root);
|
||||||
|
root = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node<Integer> createListWithLoop() {
|
||||||
|
Node<Integer> node = createList();
|
||||||
|
createLoop(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node<Integer> createListWithFullCycle() {
|
||||||
|
Node<Integer> head = createList();
|
||||||
|
Node<Integer> tail = Node.getTail(head);
|
||||||
|
tail.next = head;
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node<Integer> createListWithSingleNodeInCycle() {
|
||||||
|
Node<Integer> head = createList();
|
||||||
|
Node<Integer> tail = Node.getTail(head);
|
||||||
|
tail.next = tail;
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createLoop(Node<Integer> root) {
|
||||||
|
Node<Integer> tail = Node.getTail(root);
|
||||||
|
|
||||||
|
Node<Integer> middle = root;
|
||||||
|
for (int i = 1; i <= 4; i++) {
|
||||||
|
middle = middle.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail.next = middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleRemovalBruteForceTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleRemovalBruteForceTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleRemovalBruteForce.detectAndRemoveCycle(head));
|
||||||
|
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleRemovalByCountingLoopNodesTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleRemovalByCountingLoopNodesTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(head));
|
||||||
|
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleRemovalWithoutCountingLoopNodesTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleRemovalWithoutCountingLoopNodesTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(head));
|
||||||
|
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
59
apache-cayenne/pom.xml
Normal file
59
apache-cayenne/pom.xml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>apache-cayenne</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>apache-cayenne</name>
|
||||||
|
<description>Introduction to Apache Cayenne</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<mysql.connector.version>5.1.44</mysql.connector.version>
|
||||||
|
<cayenne.version>4.0.M5</cayenne.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cayenne</groupId>
|
||||||
|
<artifactId>cayenne-server</artifactId>
|
||||||
|
<version>${cayenne.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>${mysql.connector.version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.cayenne.plugins</groupId>
|
||||||
|
<artifactId>cayenne-modeler-maven-plugin</artifactId>
|
||||||
|
<version>${cayenne.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.apachecayenne.persistent;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.auto._Article;
|
||||||
|
|
||||||
|
public class Article extends _Article {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.apachecayenne.persistent;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.auto._Author;
|
||||||
|
|
||||||
|
public class Author extends _Author {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.baeldung.apachecayenne.persistent.auto;
|
||||||
|
|
||||||
|
import org.apache.cayenne.CayenneDataObject;
|
||||||
|
import org.apache.cayenne.exp.Property;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.Author;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class _Article was generated by Cayenne.
|
||||||
|
* It is probably a good idea to avoid changing this class manually,
|
||||||
|
* since it may be overwritten next time code is regenerated.
|
||||||
|
* If you need to make any customizations, please use subclass.
|
||||||
|
*/
|
||||||
|
public abstract class _Article extends CayenneDataObject {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final String ID_PK_COLUMN = "id";
|
||||||
|
|
||||||
|
public static final Property<String> CONTENT = Property.create("content", String.class);
|
||||||
|
public static final Property<String> TITLE = Property.create("title", String.class);
|
||||||
|
public static final Property<Author> AUTHOR = Property.create("author", Author.class);
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
writeProperty("content", content);
|
||||||
|
}
|
||||||
|
public String getContent() {
|
||||||
|
return (String)readProperty("content");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
writeProperty("title", title);
|
||||||
|
}
|
||||||
|
public String getTitle() {
|
||||||
|
return (String)readProperty("title");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(Author author) {
|
||||||
|
setToOneTarget("author", author, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Author getAuthor() {
|
||||||
|
return (Author)readProperty("author");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.apachecayenne.persistent.auto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.cayenne.CayenneDataObject;
|
||||||
|
import org.apache.cayenne.exp.Property;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.Article;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class _Author was generated by Cayenne.
|
||||||
|
* It is probably a good idea to avoid changing this class manually,
|
||||||
|
* since it may be overwritten next time code is regenerated.
|
||||||
|
* If you need to make any customizations, please use subclass.
|
||||||
|
*/
|
||||||
|
public abstract class _Author extends CayenneDataObject {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final String ID_PK_COLUMN = "id";
|
||||||
|
|
||||||
|
public static final Property<String> NAME = Property.create("name", String.class);
|
||||||
|
public static final Property<List<Article>> ARTICLES = Property.create("articles", List.class);
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
writeProperty("name", name);
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return (String)readProperty("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToArticles(Article obj) {
|
||||||
|
addToManyTarget("articles", obj, true);
|
||||||
|
}
|
||||||
|
public void removeFromArticles(Article obj) {
|
||||||
|
removeToManyTarget("articles", obj, true);
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List<Article> getArticles() {
|
||||||
|
return (List<Article>)readProperty("articles");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
17
apache-cayenne/src/main/resources/cayenne-project.xml
Normal file
17
apache-cayenne/src/main/resources/cayenne-project.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<domain project-version="9">
|
||||||
|
<map name="datamap"/>
|
||||||
|
|
||||||
|
<node name="datanode"
|
||||||
|
factory="org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory"
|
||||||
|
schema-update-strategy="org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy"
|
||||||
|
>
|
||||||
|
<map-ref name="datamap"/>
|
||||||
|
<data-source>
|
||||||
|
<driver value="com.mysql.jdbc.Driver"/>
|
||||||
|
<url value="jdbc:mysql://localhost:3306/intro_cayenne"/>
|
||||||
|
<connectionPool min="1" max="1"/>
|
||||||
|
<login userName="root" password="root"/>
|
||||||
|
</data-source>
|
||||||
|
</node>
|
||||||
|
</domain>
|
32
apache-cayenne/src/main/resources/datamap.map.xml
Normal file
32
apache-cayenne/src/main/resources/datamap.map.xml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<data-map xmlns="http://cayenne.apache.org/schema/9/modelMap"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://cayenne.apache.org/schema/9/modelMap http://cayenne.apache.org/schema/9/modelMap.xsd"
|
||||||
|
project-version="9">
|
||||||
|
<property name="defaultPackage" value="com.baeldung.apachecayenne.persistent"/>
|
||||||
|
<db-entity name="article" catalog="intro_cayenne">
|
||||||
|
<db-attribute name="author_id" type="INTEGER" isMandatory="true" length="10"/>
|
||||||
|
<db-attribute name="content" type="VARCHAR" isMandatory="true" length="254"/>
|
||||||
|
<db-attribute name="id" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="10"/>
|
||||||
|
<db-attribute name="title" type="VARCHAR" isMandatory="true" length="254"/>
|
||||||
|
</db-entity>
|
||||||
|
<db-entity name="author" catalog="intro_cayenne">
|
||||||
|
<db-attribute name="id" type="INTEGER" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="10"/>
|
||||||
|
<db-attribute name="name" type="VARCHAR" isMandatory="true" length="254"/>
|
||||||
|
</db-entity>
|
||||||
|
<obj-entity name="Article" className="com.baeldung.apachecayenne.persistent.Article" dbEntityName="article">
|
||||||
|
<obj-attribute name="content" type="java.lang.String" db-attribute-path="content"/>
|
||||||
|
<obj-attribute name="title" type="java.lang.String" db-attribute-path="title"/>
|
||||||
|
</obj-entity>
|
||||||
|
<obj-entity name="Author" className="com.baeldung.apachecayenne.persistent.Author" dbEntityName="author">
|
||||||
|
<obj-attribute name="name" type="java.lang.String" db-attribute-path="name"/>
|
||||||
|
</obj-entity>
|
||||||
|
<db-relationship name="author" source="article" target="author" toMany="false">
|
||||||
|
<db-attribute-pair source="author_id" target="id"/>
|
||||||
|
</db-relationship>
|
||||||
|
<db-relationship name="articles" source="author" target="article" toMany="true">
|
||||||
|
<db-attribute-pair source="id" target="author_id"/>
|
||||||
|
</db-relationship>
|
||||||
|
<obj-relationship name="author" source="Article" target="Author" deleteRule="Nullify" db-relationship-path="author"/>
|
||||||
|
<obj-relationship name="articles" source="Author" target="Article" deleteRule="Deny" db-relationship-path="articles"/>
|
||||||
|
</data-map>
|
@ -0,0 +1,131 @@
|
|||||||
|
package com.baeldung.apachecayenne;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.Article;
|
||||||
|
import com.baeldung.apachecayenne.persistent.Author;
|
||||||
|
import org.apache.cayenne.ObjectContext;
|
||||||
|
import org.apache.cayenne.configuration.server.ServerRuntime;
|
||||||
|
import org.apache.cayenne.query.ObjectSelect;
|
||||||
|
import org.apache.cayenne.query.SQLTemplate;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class CayenneOperationTests {
|
||||||
|
private static ObjectContext context = null;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setupTheCayenneContext() {
|
||||||
|
ServerRuntime cayenneRuntime = ServerRuntime.builder()
|
||||||
|
.addConfig("cayenne-project.xml")
|
||||||
|
.build();
|
||||||
|
context = cayenneRuntime.newContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void deleteAllRecords() {
|
||||||
|
SQLTemplate deleteArticles = new SQLTemplate(Article.class, "delete from article");
|
||||||
|
SQLTemplate deleteAuthors = new SQLTemplate(Author.class, "delete from author");
|
||||||
|
|
||||||
|
context.performGenericQuery(deleteArticles);
|
||||||
|
context.performGenericQuery(deleteAuthors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAuthor_whenInsert_thenWeGetOneRecordInTheDatabase() {
|
||||||
|
Author author = context.newObject(Author.class);
|
||||||
|
author.setName("Paul");
|
||||||
|
|
||||||
|
context.commitChanges();
|
||||||
|
|
||||||
|
long records = ObjectSelect.dataRowQuery(Author.class).selectCount(context);
|
||||||
|
assertEquals(1, records);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAuthor_whenInsert_andQueryByFirstName_thenWeGetTheAuthor() {
|
||||||
|
Author author = context.newObject(Author.class);
|
||||||
|
author.setName("Paul");
|
||||||
|
|
||||||
|
context.commitChanges();
|
||||||
|
|
||||||
|
Author expectedAuthor = ObjectSelect.query(Author.class)
|
||||||
|
.where(Author.NAME.eq("Paul"))
|
||||||
|
.selectOne(context);
|
||||||
|
|
||||||
|
assertEquals("Paul", expectedAuthor.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoAuthor_whenInsert_andQueryAll_thenWeGetTwoAuthors() {
|
||||||
|
Author firstAuthor = context.newObject(Author.class);
|
||||||
|
firstAuthor.setName("Paul");
|
||||||
|
|
||||||
|
Author secondAuthor = context.newObject(Author.class);
|
||||||
|
secondAuthor.setName("Ludovic");
|
||||||
|
|
||||||
|
context.commitChanges();
|
||||||
|
|
||||||
|
List<Author> authors = ObjectSelect.query(Author.class).select(context);
|
||||||
|
assertEquals(2, authors.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAuthor_whenUpdating_thenWeGetAnUpatedeAuthor() {
|
||||||
|
Author author = context.newObject(Author.class);
|
||||||
|
author.setName("Paul");
|
||||||
|
context.commitChanges();
|
||||||
|
|
||||||
|
Author expectedAuthor = ObjectSelect.query(Author.class)
|
||||||
|
.where(Author.NAME.eq("Paul"))
|
||||||
|
.selectOne(context);
|
||||||
|
expectedAuthor.setName("Garcia");
|
||||||
|
context.commitChanges();
|
||||||
|
|
||||||
|
assertEquals(author.getName(), expectedAuthor.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAuthor_whenDeleting_thenWeLostHisDetails() {
|
||||||
|
Author author = context.newObject(Author.class);
|
||||||
|
author.setName("Paul");
|
||||||
|
context.commitChanges();
|
||||||
|
|
||||||
|
Author savedAuthor = ObjectSelect.query(Author.class)
|
||||||
|
.where(Author.NAME.eq("Paul")).selectOne(context);
|
||||||
|
if(savedAuthor != null) {
|
||||||
|
context.deleteObjects(author);
|
||||||
|
context.commitChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
Author expectedAuthor = ObjectSelect.query(Author.class)
|
||||||
|
.where(Author.NAME.eq("Paul")).selectOne(context);
|
||||||
|
assertNull(expectedAuthor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAuthor_whenAttachingToArticle_thenTheRelationIsMade() {
|
||||||
|
Author author = context.newObject(Author.class);
|
||||||
|
author.setName("Paul");
|
||||||
|
|
||||||
|
Article article = context.newObject(Article.class);
|
||||||
|
article.setTitle("My post title");
|
||||||
|
article.setContent("The content");
|
||||||
|
article.setAuthor(author);
|
||||||
|
|
||||||
|
context.commitChanges();
|
||||||
|
|
||||||
|
Author expectedAuthor = ObjectSelect.query(Author.class)
|
||||||
|
.where(Author.NAME.eq("Paul"))
|
||||||
|
.selectOne(context);
|
||||||
|
|
||||||
|
Article expectedArticle = (expectedAuthor.getArticles()).get(0);
|
||||||
|
assertEquals(article.getTitle(), expectedArticle.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
### Relevant articles
|
||||||
|
- [Introduction to Apache Shiro](http://www.baeldung.com/apache-shiro)
|
@ -9,9 +9,9 @@
|
|||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>parent-modules</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.5.2.RELEASE</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@ -21,6 +21,19 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.shiro</groupId>
|
||||||
|
<artifactId>shiro-spring-boot-web-starter</artifactId>
|
||||||
|
<version>${apache-shiro-core-version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.shiro</groupId>
|
<groupId>org.apache.shiro</groupId>
|
||||||
<artifactId>shiro-core</artifactId>
|
<artifactId>shiro-core</artifactId>
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.apache.shiro.realm.Realm;
|
||||||
|
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
|
||||||
|
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by smatt on 21/08/2017.
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ShiroSpringApplication {
|
||||||
|
|
||||||
|
private static final transient Logger log = LoggerFactory.getLogger(ShiroSpringApplication.class);
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
SpringApplication.run(ShiroSpringApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Realm realm() {
|
||||||
|
return new MyCustomRealm();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
|
||||||
|
DefaultShiroFilterChainDefinition filter
|
||||||
|
= new DefaultShiroFilterChainDefinition();
|
||||||
|
|
||||||
|
filter.addPathDefinition("/secure", "authc");
|
||||||
|
filter.addPathDefinition("/**", "anon");
|
||||||
|
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
package com.baeldung.controllers;
|
||||||
|
|
||||||
|
import com.baeldung.models.UserCredentials;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class ShiroSpringController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping( value = "/login", method = {RequestMethod.GET, RequestMethod.POST})
|
||||||
|
public String login(HttpServletRequest req, UserCredentials cred, RedirectAttributes attr) {
|
||||||
|
|
||||||
|
if(req.getMethod().equals(RequestMethod.GET.toString())) {
|
||||||
|
return "login";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
Subject subject = SecurityUtils.getSubject();
|
||||||
|
|
||||||
|
if(!subject.isAuthenticated()) {
|
||||||
|
UsernamePasswordToken token = new UsernamePasswordToken(
|
||||||
|
cred.getUsername(), cred.getPassword(), cred.isRememberMe());
|
||||||
|
try {
|
||||||
|
subject.login(token);
|
||||||
|
} catch (AuthenticationException ae) {
|
||||||
|
ae.printStackTrace();
|
||||||
|
attr.addFlashAttribute("error", "Invalid Credentials");
|
||||||
|
return "redirect:/login";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "redirect:/secure";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/secure")
|
||||||
|
public String secure(ModelMap modelMap) {
|
||||||
|
|
||||||
|
Subject currentUser = SecurityUtils.getSubject();
|
||||||
|
String role = "", permission = "";
|
||||||
|
|
||||||
|
if(currentUser.hasRole("admin")) {
|
||||||
|
role = role + "You are an Admin";
|
||||||
|
}
|
||||||
|
else if(currentUser.hasRole("editor")) {
|
||||||
|
role = role + "You are an Editor";
|
||||||
|
}
|
||||||
|
else if(currentUser.hasRole("author")) {
|
||||||
|
role = role + "You are an Author";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:compose")) {
|
||||||
|
permission = permission + "You can compose an article, ";
|
||||||
|
} else {
|
||||||
|
permission = permission + "You are not permitted to compose an article!, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:save")) {
|
||||||
|
permission = permission + "You can save articles, ";
|
||||||
|
} else {
|
||||||
|
permission = permission + "\nYou can not save articles, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUser.isPermitted("articles:publish")) {
|
||||||
|
permission = permission + "\nYou can publish articles";
|
||||||
|
} else {
|
||||||
|
permission = permission + "\nYou can not publish articles";
|
||||||
|
}
|
||||||
|
|
||||||
|
modelMap.addAttribute("username", currentUser.getPrincipal());
|
||||||
|
modelMap.addAttribute("permission", permission);
|
||||||
|
modelMap.addAttribute("role", role);
|
||||||
|
|
||||||
|
return "secure";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/logout")
|
||||||
|
public String logout() {
|
||||||
|
Subject subject = SecurityUtils.getSubject();
|
||||||
|
subject.logout();
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung.models;
|
||||||
|
|
||||||
|
public class UserCredentials {
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private boolean rememberMe = false;
|
||||||
|
|
||||||
|
public UserCredentials() {}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRememberMe() {
|
||||||
|
return rememberMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRememberMe(boolean rememberMe) {
|
||||||
|
this.rememberMe = rememberMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "username = " + getUsername()
|
||||||
|
+ "\nrememberMe = " + isRememberMe();
|
||||||
|
}
|
||||||
|
}
|
11
apache-shiro/src/main/resources/application.properties
Normal file
11
apache-shiro/src/main/resources/application.properties
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
server.port=9000
|
||||||
|
server.servlet-path=/
|
||||||
|
server.context-path=/
|
||||||
|
|
||||||
|
#shiro-spring-boot-config
|
||||||
|
shiro.loginUrl = /login
|
||||||
|
shiro.successUrl = /secure
|
||||||
|
shiro.unauthorizedUrl = /login
|
||||||
|
|
||||||
|
#freemarker
|
||||||
|
spring.freemarker.suffix=.ftl
|
10
apache-shiro/src/main/resources/templates/index.ftl
Normal file
10
apache-shiro/src/main/resources/templates/index.ftl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Index</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Welcome Guest!</h1>
|
||||||
|
<br>
|
||||||
|
<a href="/login">Login</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
27
apache-shiro/src/main/resources/templates/login.ftl
Normal file
27
apache-shiro/src/main/resources/templates/login.ftl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Login</title>
|
||||||
|
</head>
|
||||||
|
<body style="margin-left: 30px;">
|
||||||
|
<h3>Login</h3>
|
||||||
|
<br>
|
||||||
|
<form action="/login" method="post">
|
||||||
|
<#if (error?length > 0)??>
|
||||||
|
<p style="color:darkred;">${error}</p>
|
||||||
|
<#else>
|
||||||
|
</#if>
|
||||||
|
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<br>
|
||||||
|
<input type="text" name="username">
|
||||||
|
<br><br>
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<br>
|
||||||
|
<input type="password" name="password">
|
||||||
|
<br><br>
|
||||||
|
<input type="checkbox" name="rememberMe"> Remember Me
|
||||||
|
<br><br>
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
apache-shiro/src/main/resources/templates/secure.ftl
Normal file
15
apache-shiro/src/main/resources/templates/secure.ftl
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Secure</title>
|
||||||
|
</head>
|
||||||
|
<body style="margin-left: 30px;">
|
||||||
|
<h1>Welcome ${username}!</h1>
|
||||||
|
<p><strong>Role</strong>: ${role}</p>
|
||||||
|
<p><strong>Permissions</strong></p>
|
||||||
|
<p>${permission}</p>
|
||||||
|
<br>
|
||||||
|
<form role="form" action="/logout" method="POST">
|
||||||
|
<input type="Submit" value="Logout" />
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
2
bootique/README.md
Normal file
2
bootique/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
### Relevant Articles:
|
||||||
|
- [Introduction to Bootique](http://www.baeldung.com/bootique)
|
26
core-java-8/.gitignore
vendored
Normal file
26
core-java-8/.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
*.class
|
||||||
|
|
||||||
|
0.*
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
.resourceCache
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
# Files generated by integration tests
|
||||||
|
*.txt
|
||||||
|
backup-pom.xml
|
||||||
|
/bin/
|
||||||
|
/temp
|
||||||
|
|
||||||
|
#IntelliJ specific
|
||||||
|
.idea/
|
||||||
|
*.iml
|
32
core-java-8/README.md
Normal file
32
core-java-8/README.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
=========
|
||||||
|
|
||||||
|
## Core Java 8 Cookbooks and Examples
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors)
|
||||||
|
- [Guide to Java 8’s Functional Interfaces](http://www.baeldung.com/java-8-functional-interfaces)
|
||||||
|
- [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda)
|
||||||
|
- [Java 8 New Features](http://www.baeldung.com/java-8-new-features)
|
||||||
|
- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips)
|
||||||
|
- [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator)
|
||||||
|
- [Java 8 Streams Advanced](http://www.baeldung.com/java-8-streams)
|
||||||
|
- [Introduction to Java 8 Streams](http://www.baeldung.com/java-8-streams-introduction)
|
||||||
|
- [Guide to Java 8 groupingBy Collector](http://www.baeldung.com/java-groupingby-collector)
|
||||||
|
- [Strategy Design Pattern in Java 8](http://www.baeldung.com/java-strategy-pattern)
|
||||||
|
- [Java 8 and Infinite Streams](http://www.baeldung.com/java-inifinite-streams)
|
||||||
|
- [String Operations with Java Streams](http://www.baeldung.com/java-stream-operations-on-strings)
|
||||||
|
- [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions)
|
||||||
|
- [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany)
|
||||||
|
- [Guide to Java 8 Comparator.comparing()](http://www.baeldung.com/java-8-comparator-comparing)
|
||||||
|
- [How to Get the Last Element of a Stream in Java?](http://www.baeldung.com/java-stream-last-element)
|
||||||
|
- [Introduction to the Java 8 Date/Time API](http://www.baeldung.com/java-8-date-time-intro)
|
||||||
|
- [Migrating to the New Java 8 Date Time API](http://www.baeldung.com/migrating-to-java-8-date-time-api)
|
||||||
|
- [Guide To Java 8 Optional](http://www.baeldung.com/java-optional)
|
||||||
|
- [Guide to the Java 8 forEach](http://www.baeldung.com/foreach-java)
|
||||||
|
- [Get the Current Date, Time and Timestamp in Java 8](http://www.baeldung.com/current-date-time-and-timestamp-in-java-8)
|
||||||
|
- [TemporalAdjuster in Java](http://www.baeldung.com/java-temporal-adjuster)
|
||||||
|
- [Finding Max/Min of a List or Collection](http://www.baeldung.com/java-collection-min-max)
|
||||||
|
- [Java Base64 Encoding and Decoding](http://www.baeldung.com/java-base64-encode-and-decode)
|
||||||
|
- [The Difference Between map() and flatMap()](http://www.baeldung.com/java-difference-map-and-flatmap)
|
||||||
|
|
||||||
|
- [Merging Streams in Java](http://www.baeldung.com/java-merge-streams)
|
258
core-java-8/pom.xml
Normal file
258
core-java-8/pom.xml
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>core-java-8</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>core-java-8</name>
|
||||||
|
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- utils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
<version>${commons-collections4.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons-io.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-math3</artifactId>
|
||||||
|
<version>${commons-math3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<version>1.2.17</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>${commons-codec.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test scoped -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.awaitility</groupId>
|
||||||
|
<artifactId>awaitility</artifactId>
|
||||||
|
<version>${avaitility.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>core-java-8</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-dependencies</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>libs/</classpathPrefix>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||||
|
<transformers>
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.jolira</groupId>
|
||||||
|
<artifactId>onejar-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
<attachToBuild>true</attachToBuild>
|
||||||
|
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>one-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<classifier>spring-boot</classifier>
|
||||||
|
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>integration</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*ManualTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<includes>
|
||||||
|
<include>**/*IntegrationTest.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<test.mime>json</test.mime>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
|
||||||
|
<!-- util -->
|
||||||
|
<guava.version>21.0</guava.version>
|
||||||
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
|
<commons-io.version>2.5</commons-io.version>
|
||||||
|
<commons-collections4.version>4.1</commons-collections4.version>
|
||||||
|
<collections-generic.version>4.01</collections-generic.version>
|
||||||
|
<commons-codec.version>1.10</commons-codec.version>
|
||||||
|
<lombok.version>1.16.12</lombok.version>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
<avaitility.version>1.7.0</avaitility.version>
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
</project>
|
@ -1,5 +1,6 @@
|
|||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface Bar {
|
public interface Bar {
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface Baz {
|
public interface Baz {
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface Foo {
|
public interface Foo {
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface FooExtended extends Baz, Bar {
|
public interface FooExtended extends Baz, Bar {
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class UseFoo {
|
public class UseFoo {
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.baeldung.datetime;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public class UseLocalDateTime {
|
||||||
|
|
||||||
|
public LocalDateTime getLocalDateTimeUsingParseMethod(String representation) {
|
||||||
|
return LocalDateTime.parse(representation);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,7 +15,9 @@ public class UseLocalDateTimeUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenString_whenUsingParse_thenLocalDateTime() {
|
public void givenString_whenUsingParse_thenLocalDateTime() {
|
||||||
assertEquals(LocalDate.of(2016, Month.MAY, 10), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30").toLocalDate());
|
assertEquals(LocalDate.of(2016, Month.MAY, 10), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30")
|
||||||
assertEquals(LocalTime.of(6, 30), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30").toLocalTime());
|
.toLocalDate());
|
||||||
|
assertEquals(LocalTime.of(6, 30), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30")
|
||||||
|
.toLocalTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,12 +15,14 @@ public class UseLocalDateUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenValues_whenUsingFactoryOf_thenLocalDate() {
|
public void givenValues_whenUsingFactoryOf_thenLocalDate() {
|
||||||
assertEquals("2016-05-10", useLocalDate.getLocalDateUsingFactoryOfMethod(2016, 5, 10).toString());
|
assertEquals("2016-05-10", useLocalDate.getLocalDateUsingFactoryOfMethod(2016, 5, 10)
|
||||||
|
.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenString_whenUsingParse_thenLocalDate() {
|
public void givenString_whenUsingParse_thenLocalDate() {
|
||||||
assertEquals("2016-05-10", useLocalDate.getLocalDateUsingParseMethod("2016-05-10").toString());
|
assertEquals("2016-05-10", useLocalDate.getLocalDateUsingParseMethod("2016-05-10")
|
||||||
|
.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -30,12 +32,14 @@ public class UseLocalDateUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenDate_whenUsingPlus_thenNextDay() {
|
public void givenDate_whenUsingPlus_thenNextDay() {
|
||||||
assertEquals(LocalDate.now().plusDays(1), useLocalDate.getNextDay(LocalDate.now()));
|
assertEquals(LocalDate.now()
|
||||||
|
.plusDays(1), useLocalDate.getNextDay(LocalDate.now()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenDate_whenUsingMinus_thenPreviousDay() {
|
public void givenDate_whenUsingMinus_thenPreviousDay() {
|
||||||
assertEquals(LocalDate.now().minusDays(1), useLocalDate.getPreviousDay(LocalDate.now()));
|
assertEquals(LocalDate.now()
|
||||||
|
.minusDays(1), useLocalDate.getPreviousDay(LocalDate.now()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -45,7 +49,8 @@ public class UseLocalDateUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenToday_whenUsingWithTemporalAdjuster_thenFirstDayOfMonth() {
|
public void givenToday_whenUsingWithTemporalAdjuster_thenFirstDayOfMonth() {
|
||||||
assertEquals(1, useLocalDate.getFirstDayOfMonth().getDayOfMonth());
|
assertEquals(1, useLocalDate.getFirstDayOfMonth()
|
||||||
|
.getDayOfMonth());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
@ -21,7 +21,6 @@ public class FunctionalInterfaceUnitTest {
|
|||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FunctionalInterfaceUnitTest.class);
|
private static final Logger LOG = LoggerFactory.getLogger(FunctionalInterfaceUnitTest.class);
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPassingLambdaToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() {
|
public void whenPassingLambdaToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() {
|
||||||
Map<String, Integer> nameMap = new HashMap<>();
|
Map<String, Integer> nameMap = new HashMap<>();
|
||||||
@ -83,7 +82,8 @@ public class FunctionalInterfaceUnitTest {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
List<Integer> fibonacci5 = fibonacci.limit(5).collect(Collectors.toList());
|
List<Integer> fibonacci5 = fibonacci.limit(5)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
assertEquals(new Integer(1), fibonacci5.get(0));
|
assertEquals(new Integer(1), fibonacci5.get(0));
|
||||||
assertEquals(new Integer(1), fibonacci5.get(1));
|
assertEquals(new Integer(1), fibonacci5.get(1));
|
||||||
@ -112,7 +112,9 @@ public class FunctionalInterfaceUnitTest {
|
|||||||
public void whenUsingPredicateInFilter_thenListValuesAreFilteredOut() {
|
public void whenUsingPredicateInFilter_thenListValuesAreFilteredOut() {
|
||||||
List<String> names = Arrays.asList("Angela", "Aaron", "Bob", "Claire", "David");
|
List<String> names = Arrays.asList("Angela", "Aaron", "Bob", "Claire", "David");
|
||||||
|
|
||||||
List<String> namesWithA = names.stream().filter(name -> name.startsWith("A")).collect(Collectors.toList());
|
List<String> namesWithA = names.stream()
|
||||||
|
.filter(name -> name.startsWith("A"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
assertEquals(2, namesWithA.size());
|
assertEquals(2, namesWithA.size());
|
||||||
assertTrue(namesWithA.contains("Angela"));
|
assertTrue(namesWithA.contains("Angela"));
|
||||||
@ -135,7 +137,8 @@ public class FunctionalInterfaceUnitTest {
|
|||||||
|
|
||||||
List<Integer> values = Arrays.asList(3, 5, 8, 9, 12);
|
List<Integer> values = Arrays.asList(3, 5, 8, 9, 12);
|
||||||
|
|
||||||
int sum = values.stream().reduce(0, (i1, i2) -> i1 + i2);
|
int sum = values.stream()
|
||||||
|
.reduce(0, (i1, i2) -> i1 + i2);
|
||||||
|
|
||||||
assertEquals(37, sum);
|
assertEquals(37, sum);
|
||||||
|
|
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