Merge branch 'master' of https://github.com/eugenp/tutorials
This commit is contained in:
commit
cb9e336bd6
|
@ -7,4 +7,6 @@
|
|||
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
|
||||
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
|
||||
- [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher)
|
||||
- [Implementing a 2048 Solver in Java](https://www.baeldung.com/2048-java-solver)
|
||||
- [Finding Top K Elements in an Array](https://www.baeldung.com/java-array-top-elements)
|
||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-5)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.algorithms.topkelements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BruteForceTopKElementsFinder implements TopKElementsFinder<Integer> {
|
||||
|
||||
public List<Integer> findTopK(List<Integer> input, int k) {
|
||||
List<Integer> array = new ArrayList<>(input);
|
||||
List<Integer> topKList = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < k; i++) {
|
||||
int maxIndex = 0;
|
||||
|
||||
for (int j = 1; j < array.size(); j++) {
|
||||
if (array.get(j) > array.get(maxIndex)) {
|
||||
maxIndex = j;
|
||||
}
|
||||
}
|
||||
|
||||
topKList.add(array.remove(maxIndex));
|
||||
}
|
||||
|
||||
return topKList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.algorithms.topkelements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
public class MaxHeapTopKElementsFinder implements TopKElementsFinder<Integer> {
|
||||
|
||||
public List<Integer> findTopK(List<Integer> input, int k) {
|
||||
PriorityQueue<Integer> maxHeap = new PriorityQueue<>();
|
||||
|
||||
input.forEach(number -> {
|
||||
maxHeap.add(number);
|
||||
|
||||
if (maxHeap.size() > k) {
|
||||
maxHeap.poll();
|
||||
}
|
||||
});
|
||||
|
||||
List<Integer> topKList = new ArrayList<>(maxHeap);
|
||||
Collections.reverse(topKList);
|
||||
|
||||
return topKList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.algorithms.topkelements;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TopKElementsFinder<T extends Comparable<T>> {
|
||||
List<T> findTopK(List<T> input, int k);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.algorithms.topkelements;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TreeSetTopKElementsFinder implements TopKElementsFinder<Integer> {
|
||||
|
||||
public List<Integer> findTopK(List<Integer> input, int k) {
|
||||
Set<Integer> sortedSet = new TreeSet<>(Comparator.reverseOrder());
|
||||
sortedSet.addAll(input);
|
||||
|
||||
return sortedSet.stream().limit(k).collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.algorithms.topkelements;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
|
||||
public class TopKElementsFinderUnitTest {
|
||||
private final TopKElementsFinder<Integer> bruteForceFinder = new BruteForceTopKElementsFinder();
|
||||
private final TopKElementsFinder<Integer> maxHeapFinder = new MaxHeapTopKElementsFinder();
|
||||
private final TopKElementsFinder<Integer> treeSetFinder = new TreeSetTopKElementsFinder();
|
||||
|
||||
private final int k = 4;
|
||||
private final List<Integer> distinctIntegers = Arrays.asList(1, 2, 3, 9, 7, 6, 12);
|
||||
private final List<Integer> distinctIntegersTopK = Arrays.asList(9, 7, 6, 12);
|
||||
private final List<Integer> nonDistinctIntegers = Arrays.asList(1, 2, 3, 3, 9, 9, 7, 6, 12);
|
||||
private final List<Integer> nonDistinctIntegersTopK = Arrays.asList(9, 9, 7, 12);
|
||||
|
||||
|
||||
@Test
|
||||
public void givenArrayDistinctIntegers_whenBruteForceFindTopK_thenReturnKLargest() {
|
||||
assertThat(bruteForceFinder.findTopK(distinctIntegers, k)).containsOnlyElementsOf(distinctIntegersTopK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenArrayDistinctIntegers_whenMaxHeapFindTopK_thenReturnKLargest() {
|
||||
assertThat(maxHeapFinder.findTopK(distinctIntegers, k)).containsOnlyElementsOf(distinctIntegersTopK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenArrayDistinctIntegers_whenTreeSetFindTopK_thenReturnKLargest() {
|
||||
assertThat(treeSetFinder.findTopK(distinctIntegers, k)).containsOnlyElementsOf(distinctIntegersTopK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenArrayNonDistinctIntegers_whenBruteForceFindTopK_thenReturnKLargest() {
|
||||
assertThat(bruteForceFinder.findTopK(nonDistinctIntegers, k)).containsOnlyElementsOf(nonDistinctIntegersTopK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenArrayNonDistinctIntegers_whenMaxHeapFindTopK_thenReturnKLargest() {
|
||||
assertThat(maxHeapFinder.findTopK(nonDistinctIntegers, k)).containsOnlyElementsOf(nonDistinctIntegersTopK);
|
||||
}
|
||||
}
|
|
@ -6,4 +6,4 @@ This module contains articles about Apache Shiro
|
|||
|
||||
- [Introduction to Apache Shiro](https://www.baeldung.com/apache-shiro)
|
||||
- [Permissions-Based Access Control with Apache Shiro](https://www.baeldung.com/apache-shiro-access-control)
|
||||
|
||||
- [Spring Security vs Apache Shiro](https://www.baeldung.com/spring-security-vs-apache-shiro)
|
||||
|
|
|
@ -13,4 +13,5 @@ This module contains articles about core Groovy concepts
|
|||
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
|
||||
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)
|
||||
- [Convert String to Integer in Groovy](https://www.baeldung.com/groovy-convert-string-to-integer)
|
||||
- [Groovy Variable Scope](https://www.baeldung.com/groovy/variable-scope)
|
||||
- [[More -->]](/core-groovy-2)
|
||||
|
|
|
@ -8,7 +8,7 @@ This module contains articles about Java 11 core features
|
|||
- [Java 11 Local Variable Syntax for Lambda Parameters](https://www.baeldung.com/java-var-lambda-params)
|
||||
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
|
||||
- [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control)
|
||||
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
|
||||
- [Exploring the New HTTP Client in Java](https://www.baeldung.com/java-9-http-client)
|
||||
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)
|
||||
- [Guide to jlink](https://www.baeldung.com/jlink)
|
||||
- [Negate a Predicate Method Reference with Java 11](https://www.baeldung.com/java-negate-predicate-method-reference)
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package com.baeldung.modules.main;
|
||||
|
||||
import com.baeldung.modules.hello.HelloInterface;
|
||||
import com.baeldung.modules.hello.HelloModules;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
public class MainApp {
|
||||
public static void main(String[] args) {
|
||||
HelloModules.doSomething();
|
||||
|
||||
HelloModules module = new HelloModules();
|
||||
module.sayHello();
|
||||
|
||||
Iterable<HelloInterface> services = ServiceLoader.load(HelloInterface.class);
|
||||
HelloInterface service = services.iterator().next();
|
||||
service.sayHello();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,3 +13,4 @@ This module contains articles about core Java features that have been introduced
|
|||
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
||||
- [Java 9 Reactive Streams](https://www.baeldung.com/java-9-reactive-streams)
|
||||
- [Multi-Release JAR Files with Maven](https://www.baeldung.com/maven-multi-release-jars)
|
||||
- [The Difference between RxJava API and the Java 9 Flow API](https://www.baeldung.com/rxjava-vs-java-flow-api)
|
||||
|
|
|
@ -9,3 +9,4 @@ This module contains articles about Java 9 core features
|
|||
- [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range)
|
||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||
- [Immutable ArrayList in Java](https://www.baeldung.com/java-immutable-list)
|
||||
- [Easy Ways to Write a Java InputStream to an OutputStream](https://www.baeldung.com/java-inputstream-to-outputstream)
|
||||
|
|
|
@ -5,4 +5,4 @@ This module contains complete guides about arrays in Java
|
|||
### Relevant Articles:
|
||||
- [Arrays in Java: A Reference Guide](https://www.baeldung.com/java-arrays-guide)
|
||||
- [Guide to the java.util.Arrays Class](https://www.baeldung.com/java-util-arrays)
|
||||
- [What is [Ljava.lang.Object;?]](https://www.baeldung.com/java-tostring-array)
|
||||
- [What is \[Ljava.lang.Object;?](https://www.baeldung.com/java-tostring-array)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
## Core Java Collections Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Time Comparison of Arrays.sort(Object[]) and Arrays.sort(int[])](https://www.baeldung.com/arrays-sortobject-vs-sortint)
|
||||
- [Java ArrayList vs Vector](https://www.baeldung.com/java-arraylist-vs-vector)
|
||||
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
|
||||
|
@ -10,3 +11,4 @@
|
|||
- [Performance of contains() in a HashSet vs ArrayList](https://www.baeldung.com/java-hashset-arraylist-contains-performance)
|
||||
- [Fail-Safe Iterator vs Fail-Fast Iterator](https://www.baeldung.com/java-fail-safe-vs-fail-fast-iterator)
|
||||
- [Quick Guide to the Java Stack](https://www.baeldung.com/java-stack)
|
||||
- [Convert an Array of Primitives to a List](https://www.baeldung.com/java-primitive-array-to-list)
|
||||
|
|
|
@ -15,4 +15,5 @@ This module contains articles about advanced topics about multithreading with co
|
|||
- [The ABA Problem in Concurrency](https://www.baeldung.com/cs/aba-concurrency)
|
||||
- [Introduction to Lock-Free Data Structures](https://www.baeldung.com/lock-free-programming)
|
||||
- [Introduction to Exchanger in Java](https://www.baeldung.com/java-exchanger)
|
||||
- [Why Not To Start A Thread In The Constructor?](https://www.baeldung.com/java-thread-constructor)
|
||||
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
This module contains articles about basic Java concurrency
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution)
|
||||
- [wait and notify() Methods in Java](https://www.baeldung.com/java-wait-notify)
|
||||
- [Difference Between Wait and Sleep in Java](https://www.baeldung.com/java-wait-and-sleep)
|
||||
- [Guide to the Synchronized Keyword in Java](https://www.baeldung.com/java-synchronized)
|
||||
- [Life Cycle of a Thread in Java](https://www.baeldung.com/java-thread-lifecycle)
|
||||
- [Guide to AtomicMarkableReference](https://www.baeldung.com/java-atomicmarkablereference)
|
||||
- [Why are Local Variables Thread-Safe in Java](https://www.baeldung.com/java-local-variables-thread-safe)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-concurrency-basic)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Introduction to Lock Striping](https://www.baeldung.com/java-lock-stripping)
|
||||
- [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-concurrency-collections)
|
||||
|
|
|
@ -3,9 +3,16 @@
|
|||
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.concurrent.lock</groupId>
|
||||
<artifactId>core-java-concurrency-collections-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-concurrency-collections-2</name>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
@ -30,19 +37,6 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jmh.version>1.21</jmh.version>
|
||||
|
|
|
@ -19,7 +19,7 @@ import org.junit.FixMethodOrder;
|
|||
import org.junit.Test;
|
||||
|
||||
@FixMethodOrder
|
||||
public class TestConcurrentLinkedQueue {
|
||||
public class ConcurrentLinkedQueueUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenThereIsExistingCollection_WhenAddedIntoQueue_ThenShouldContainElements() {
|
|
@ -18,7 +18,7 @@ import org.junit.FixMethodOrder;
|
|||
import org.junit.Test;
|
||||
|
||||
@FixMethodOrder
|
||||
public class TestLinkedBlockingQueue {
|
||||
public class LinkedBlockingQueueUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenThereIsExistingCollection_WhenAddedIntoQueue_ThenShouldContainElements() {
|
|
@ -4,7 +4,11 @@ import org.junit.FixMethodOrder;
|
|||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedTransferQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TransferQueue;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
|
@ -10,7 +10,7 @@ This module contains articles about concurrent Java collections
|
|||
- [Custom Thread Pools In Java 8 Parallel Streams](http://www.baeldung.com/java-8-parallel-streams-custom-threadpool)
|
||||
- [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue)
|
||||
- [A Guide to Java SynchronousQueue](http://www.baeldung.com/java-synchronous-queue)
|
||||
- [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue)
|
||||
- [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map)
|
||||
- [Guide to CopyOnWriteArrayList](http://www.baeldung.com/java-copy-on-write-arraylist)
|
||||
- [LinkedBlockingQueue vs ConcurrentLinkedQueue](https://www.baeldung.com/java-queue-linkedblocking-concurrentlinked)
|
||||
- [[Next -->]](/core-java-modules/core-java-concurrency-collections-2)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.consoleout;
|
||||
|
||||
import java.io.Console;
|
||||
|
||||
public class ConsoleAndOut {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
printConsoleObject();
|
||||
readPasswordFromConsole();
|
||||
} catch (Exception ex) {
|
||||
// Eating NullPointerExcpetion which will occur when this
|
||||
// program will be run from mediums other than console
|
||||
}
|
||||
printSysOut();
|
||||
}
|
||||
|
||||
static void printConsoleObject() {
|
||||
Console console = System.console();
|
||||
console.writer().print(console);
|
||||
}
|
||||
|
||||
static void readPasswordFromConsole() {
|
||||
Console console = System.console();
|
||||
char[] password = console.readPassword("Enter password: ");
|
||||
console.printf(String.valueOf(password));
|
||||
}
|
||||
|
||||
static void printSysOut() {
|
||||
System.out.println(System.out);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.consoleout;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ConsoleAndOutUnitTest {
|
||||
|
||||
@Test
|
||||
void whenRetreivingConsole_thenPrintConsoleObject() {
|
||||
assertThrows(NullPointerException.class, () -> {
|
||||
ConsoleAndOut.printConsoleObject();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenReadingPassword_thenReadPassword() {
|
||||
assertThrows(NullPointerException.class, () -> {
|
||||
ConsoleAndOut.readPasswordFromConsole();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenRetrievingSysOut_thenPrintSysOutObject() {
|
||||
ConsoleAndOut.printSysOut();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
This module contains articles about date operations in Java.
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Get the Current Date Prior to Java 8](https://www.baeldung.com/java-get-the-current-date-legacy)
|
||||
- [Skipping Weekends While Adding Days to LocalDate in Java 8](https://www.baeldung.com/java-localdate-add-days-skip-weekends)
|
||||
- [Checking If Two Java Dates Are on the Same Day](https://www.baeldung.com/java-check-two-dates-on-same-day)
|
||||
|
@ -9,4 +10,5 @@ This module contains articles about date operations in Java.
|
|||
- [How to Set the JVM Time Zone](https://www.baeldung.com/java-jvm-time-zone)
|
||||
- [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week)
|
||||
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
||||
- [Getting the Week Number From Any Date](https://www.baeldung.com/java-get-week-number)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)
|
||||
|
|
|
@ -12,3 +12,5 @@ This module contains articles about core java exceptions
|
|||
- [Java – Try with Resources](https://www.baeldung.com/java-try-with-resources)
|
||||
- [Java Global Exception Handler](https://www.baeldung.com/java-global-exception-handler)
|
||||
- [How to Find an Exception’s Root Cause in Java](https://www.baeldung.com/java-exception-root-cause)
|
||||
- [Java IOException “Too many open files”](https://www.baeldung.com/java-too-many-open-files)
|
||||
- [When Does Java Throw the ExceptionInInitializerError?](https://www.baeldung.com/java-exceptionininitializererror)
|
||||
|
|
|
@ -13,4 +13,4 @@ This module contains articles about core Java input and output (IO)
|
|||
- [How to Copy a File with Java](https://www.baeldung.com/java-copy-file)
|
||||
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
||||
- [Java IO vs NIO](https://www.baeldung.com/java-io-vs-nio)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io)[[More -->]](/core-java-modules/core-java-io-3)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
## Core Java IO
|
||||
|
||||
This module contains articles about core Java input and output (IO)
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Java – Create a File](https://www.baeldung.com/java-how-to-create-a-file)
|
||||
- [Check If a Directory Is Empty in Java](https://www.baeldung.com/java-check-empty-directory)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io-2)
|
|
@ -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>core-java-io-3</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-io-3</name>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<!-- logging -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
</dependency>
|
||||
<!-- test scoped -->
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.createfile;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class CreateFileUnitTest {
|
||||
|
||||
private final String FILE_NAME = "src/test/resources/fileToCreate.txt";
|
||||
|
||||
@AfterEach
|
||||
@BeforeEach
|
||||
public void cleanUpFiles() {
|
||||
File targetFile = new File(FILE_NAME);
|
||||
targetFile.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingNio_whenCreatingFile_thenCorrect() throws IOException {
|
||||
Path newFilePath = Paths.get(FILE_NAME);
|
||||
Files.createFile(newFilePath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingFile_whenCreatingFile_thenCorrect() throws IOException {
|
||||
File newFile = new File(FILE_NAME);
|
||||
boolean success = newFile.createNewFile();
|
||||
assertTrue(success);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingGuava_whenCreatingFile_thenCorrect() throws IOException {
|
||||
com.google.common.io.Files.touch(new File(FILE_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingCommonsIo_whenCreatingFile_thenCorrect() throws IOException {
|
||||
FileUtils.touch(new File(FILE_NAME));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.baeldung.emptiness;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class DirectoryEmptinessUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenPath_whenInvalid_thenReturnsFalse() throws IOException {
|
||||
assertThat(isEmpty(Paths.get("invalid-addr"))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPath_whenNotDirectory_thenReturnsFalse() throws IOException {
|
||||
Path aFile = Paths.get(getClass().getResource("/notDir.txt").getPath());
|
||||
assertThat(isEmpty(aFile)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPath_whenNotEmptyDir_thenReturnsFalse() throws IOException {
|
||||
Path currentDir = new File("").toPath().toAbsolutePath();
|
||||
assertThat(isEmpty(currentDir)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPath_whenIsEmpty_thenReturnsTrue() throws Exception {
|
||||
Path path = Files.createTempDirectory("baeldung-empty");
|
||||
assertThat(isEmpty(path)).isTrue();
|
||||
}
|
||||
|
||||
private static boolean isEmpty(Path path) throws IOException {
|
||||
if (Files.isDirectory(path)) {
|
||||
try (DirectoryStream<Path> directory = Files.newDirectoryStream(path)) {
|
||||
return !directory.iterator().hasNext();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isEmpty2(Path path) throws IOException {
|
||||
if (Files.isDirectory(path)) {
|
||||
try (Stream<Path> entries = Files.list(path)) {
|
||||
return !entries.findFirst().isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isEmptyInefficient(Path path) {
|
||||
return path.toFile().listFiles().length == 0;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@ This module contains articles about core Java input/output(IO) APIs.
|
|||
- [A Guide to the Java FileReader Class](https://www.baeldung.com/java-filereader)
|
||||
- [The Java File Class](https://www.baeldung.com/java-io-file)
|
||||
- [Java FileWriter](https://www.baeldung.com/java-filewriter)
|
||||
- [Differences Between the Java WatchService API and the Apache Commons IO Monitor Library](https://www.baeldung.com/java-watchservice-vs-apache-commons-io-monitor-library)
|
||||
- [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](https://www.baeldung.com/java-path)
|
||||
- [Quick Use of FilenameFilter](https://www.baeldung.com/java-filename-filter)
|
||||
- [Guide to BufferedReader](https://www.baeldung.com/java-buffered-reader)
|
||||
|
|
|
@ -6,4 +6,6 @@ This module contains articles about core Java input/output(IO) conversions.
|
|||
- [Java InputStream to String](https://www.baeldung.com/convert-input-stream-to-string)
|
||||
- [Java – Write an InputStream to a File](https://www.baeldung.com/convert-input-stream-to-a-file)
|
||||
- [Converting a BufferedReader to a JSONObject](https://www.baeldung.com/java-bufferedreader-to-jsonobject)
|
||||
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
||||
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions)
|
||||
|
|
|
@ -26,6 +26,12 @@
|
|||
<artifactId>json</artifactId>
|
||||
<version>${json.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.opencsv</groupId>
|
||||
<artifactId>opencsv</artifactId>
|
||||
<version>${opencsv.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -40,6 +46,7 @@
|
|||
|
||||
<properties>
|
||||
<json.version>20200518</json.version>
|
||||
<opencsv.version>4.1</opencsv.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,20 +1,11 @@
|
|||
package com.baeldung.csv;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import com.opencsv.CSVReader;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.opencsv.CSVReader;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ReadCSVInArrayUnitTest {
|
||||
public static final String COMMA_DELIMITER = ",";
|
|
@ -1,7 +1,9 @@
|
|||
package com.baeldung.csv;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -10,10 +12,8 @@ import java.io.PrintWriter;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class WriteCsvFileExampleUnitTest {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WriteCsvFileExampleUnitTest.class);
|
|
@ -8,10 +8,9 @@ This module contains articles about core Java input and output (IO)
|
|||
- [Java – Directory Size](https://www.baeldung.com/java-folder-size)
|
||||
- [File Size in Java](https://www.baeldung.com/java-file-size)
|
||||
- [Zipping and Unzipping in Java](https://www.baeldung.com/java-compress-and-uncompress)
|
||||
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
||||
- [How to Get the File Extension of a File in Java](https://www.baeldung.com/java-file-extension)
|
||||
- [Getting a File’s Mime Type in Java](https://www.baeldung.com/java-file-mime-type)
|
||||
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
|
||||
- [How to Avoid the Java FileNotFoundException When Loading Resources](https://www.baeldung.com/java-classpath-resource-cannot-be-opened)
|
||||
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
||||
- [Java – Rename or Move a File](https://www.baeldung.com/java-how-to-rename-or-move-a-file)
|
||||
- [[More -->]](/core-java-modules/core-java-io-2)
|
||||
|
|
|
@ -29,12 +29,6 @@
|
|||
<version>${hsqldb.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.opencsv</groupId>
|
||||
<artifactId>opencsv</artifactId>
|
||||
<version>${opencsv.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Mime Type Resolution Libraries -->
|
||||
<dependency>
|
||||
<groupId>org.apache.tika</groupId>
|
||||
|
@ -142,8 +136,6 @@
|
|||
</profiles>
|
||||
|
||||
<properties>
|
||||
<!-- util -->
|
||||
<opencsv.version>4.1</opencsv.version>
|
||||
<!-- testing -->
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<!-- maven plugins -->
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package com.baeldung.rename;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class RenameFileUnitTest {
|
||||
|
||||
private final String FILE_TO_MOVE = "src/test/resources/originalFileToMove.txt";
|
||||
private final String TARGET_FILE = "src/test/resources/targetFileToMove.txt";
|
||||
|
||||
@BeforeEach
|
||||
public void createFileToMove() throws IOException {
|
||||
File fileToMove = new File(FILE_TO_MOVE);
|
||||
fileToMove.createNewFile();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void cleanUpFiles() {
|
||||
File targetFile = new File(TARGET_FILE);
|
||||
targetFile.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingNio_whenMovingFile_thenCorrect() throws IOException {
|
||||
Path fileToMovePath = Paths.get(FILE_TO_MOVE);
|
||||
Path targetPath = Paths.get(TARGET_FILE);
|
||||
Files.move(fileToMovePath, targetPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingFileClass_whenMovingFile_thenCorrect() throws IOException {
|
||||
File fileToMove = new File(FILE_TO_MOVE);
|
||||
boolean isMoved = fileToMove.renameTo(new File(TARGET_FILE));
|
||||
if (!isMoved) {
|
||||
throw new FileSystemException(TARGET_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingGuava_whenMovingFile_thenCorrect()
|
||||
throws IOException {
|
||||
File fileToMove = new File(FILE_TO_MOVE);
|
||||
File targetFile = new File(TARGET_FILE);
|
||||
|
||||
com.google.common.io.Files.move(fileToMove, targetFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingApache_whenMovingFile_thenCorrect() throws IOException {
|
||||
FileUtils.moveFile(
|
||||
FileUtils.getFile(FILE_TO_MOVE),
|
||||
FileUtils.getFile(TARGET_FILE));
|
||||
}
|
||||
|
||||
}
|
|
@ -8,4 +8,6 @@ This module contains articles about working with the Java Virtual Machine (JVM).
|
|||
- [Measuring Object Sizes in the JVM](https://www.baeldung.com/jvm-measuring-object-sizes)
|
||||
- [Adding Shutdown Hooks for JVM Applications](https://www.baeldung.com/jvm-shutdown-hooks)
|
||||
- [boolean and boolean[] Memory Layout in the JVM](https://www.baeldung.com/jvm-boolean-memory-layout)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-jvm)
|
||||
- [Where Is the Array Length Stored in JVM?](https://www.baeldung.com/java-jvm-array-length)
|
||||
- [Memory Address of Objects in Java](https://www.baeldung.com/java-object-memory-address)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-jvm)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.memaddress;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.openjdk.jol.vm.VM;
|
||||
|
||||
public class MemoryAddressUnitTest {
|
||||
|
||||
@Test
|
||||
public void printTheMemoryAddress() {
|
||||
String answer = "42";
|
||||
|
||||
System.out.println("The memory address is " + VM.current().addressOf(answer));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void identityHashCodeAndMemoryAddress() {
|
||||
Object obj = new Object();
|
||||
|
||||
System.out.println("Memory address: " + VM.current().addressOf(obj));
|
||||
System.out.println("hashCode: " + obj.hashCode());
|
||||
System.out.println("hashCode: " + System.identityHashCode(obj));
|
||||
System.out.println("toString: " + obj);
|
||||
}
|
||||
}
|
|
@ -2,4 +2,6 @@
|
|||
|
||||
This module contains articles about core features in the Java language
|
||||
|
||||
- [Class.isInstance vs Class.isAssignableFrom](https://www.baeldung.com/java-isinstance-isassignablefrom)
|
||||
- [Converting a Java String Into a Boolean](https://www.baeldung.com/java-string-to-boolean)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-lang-2)
|
||||
|
|
|
@ -39,4 +39,4 @@
|
|||
<assertj.version>3.12.2</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.staticvariables;
|
||||
|
||||
public class StaticVariableDemo {
|
||||
public static int i;
|
||||
public static int j = 20;
|
||||
public static int z;
|
||||
|
||||
static {
|
||||
z = 30;
|
||||
a = 40;
|
||||
}
|
||||
|
||||
public static int a = 50;
|
||||
|
||||
public static final int b = 100;
|
||||
|
||||
public StaticVariableDemo() {
|
||||
}
|
||||
|
||||
static class Nested {
|
||||
public static String nestedClassStaticVariable = "test";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package com.baeldung.staticvariables;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class StaticVariableUnitTest {
|
||||
|
||||
@Test
|
||||
public void initializeStaticVariable_checkAssignedValues() {
|
||||
|
||||
try {
|
||||
Class<?> staticVariableDemo = this.getClass()
|
||||
.getClassLoader()
|
||||
.loadClass("com.baeldung.staticvariables.StaticVariableDemo");
|
||||
|
||||
Field field1 = staticVariableDemo.getField("i");
|
||||
|
||||
assertThat(field1.getInt(staticVariableDemo)).isEqualTo(0);
|
||||
|
||||
Field field2 = staticVariableDemo.getField("j");
|
||||
|
||||
assertThat(field2.getInt(staticVariableDemo)).isEqualTo(20);
|
||||
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializeStaticVariable_checkStaticBlock() {
|
||||
|
||||
try {
|
||||
Class<?> staticVariableDemo = this.getClass()
|
||||
.getClassLoader()
|
||||
.loadClass("com.baeldung.staticvariables.StaticVariableDemo");
|
||||
|
||||
Field field1 = staticVariableDemo.getField("z");
|
||||
|
||||
assertThat(field1.getInt(staticVariableDemo)).isEqualTo(30);
|
||||
|
||||
Field field2 = staticVariableDemo.getField("a");
|
||||
|
||||
assertThat(field2.getInt(staticVariableDemo)).isEqualTo(50);
|
||||
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializeStaticVariable_checkFinalValues() {
|
||||
|
||||
try {
|
||||
Class<?> staticVariableDemo = this.getClass()
|
||||
.getClassLoader()
|
||||
.loadClass("com.baeldung.staticvariables.StaticVariableDemo");
|
||||
|
||||
Field field1 = staticVariableDemo.getField("b");
|
||||
|
||||
assertThat(field1.getInt(staticVariableDemo)).isEqualTo(100);
|
||||
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializeStaticVariable_checkInnerClassValues() {
|
||||
|
||||
try {
|
||||
Class<?> staticVariableDemo = this.getClass()
|
||||
.getClassLoader()
|
||||
.loadClass("com.baeldung.staticvariables.StaticVariableDemo");
|
||||
|
||||
Class<?>[] nestedClasses = staticVariableDemo.getClasses();
|
||||
|
||||
for (Class<?> nestedClass : nestedClasses) {
|
||||
if (nestedClass.getName()
|
||||
.equals("Nested")) {
|
||||
|
||||
Field field1 = nestedClass.getField("nestedClassStaticVariable");
|
||||
assertThat(field1.get(nestedClass)).isEqualTo("test");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -3,7 +3,9 @@
|
|||
This module contains articles about methods in Java
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Methods in Java](https://www.baeldung.com/java-methods)
|
||||
- [Method Overloading and Overriding in Java](https://www.baeldung.com/java-method-overload-override)
|
||||
- [Java equals() and hashCode() Contracts](https://www.baeldung.com/java-equals-hashcode-contracts)
|
||||
- [Guide to hashCode() in Java](https://www.baeldung.com/java-hashcode)
|
||||
- [The Covariant Return Type in Java](https://www.baeldung.com/java-covariant-return-type)
|
||||
|
|
|
@ -12,4 +12,5 @@ This module contains articles about networking in Java
|
|||
- [Authentication with HttpUrlConnection](https://www.baeldung.com/java-http-url-connection)
|
||||
- [Download a File from an URL in Java](https://www.baeldung.com/java-download-file)
|
||||
- [Handling java.net.ConnectException](https://www.baeldung.com/java-net-connectexception)
|
||||
- [Getting MAC addresses in Java](https://www.baeldung.com/java-mac-address)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-networking)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Reading the Value of ‘private’ Fields from a Different Class in Java](https://www.baeldung.com/java-reflection-read-private-field-value)
|
|
@ -8,5 +8,4 @@
|
|||
- [Changing Annotation Parameters At Runtime](http://www.baeldung.com/java-reflection-change-annotation-params)
|
||||
- [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies)
|
||||
- [What Causes java.lang.reflect.InvocationTargetException?](https://www.baeldung.com/java-lang-reflect-invocationtargetexception)
|
||||
- [How to Find all Getters Returning Null](http://www.baeldung.com/java-getters-returning-null)
|
||||
- [How to Get a Name of a Method Being Executed?](http://www.baeldung.com/java-name-of-executing-method)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
## Core Java 8 Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [An Overview of Regular Expressions Performance in Java](https://www.baeldung.com/java-regex-performance)
|
||||
- [A Guide To Java Regular Expressions API](http://www.baeldung.com/regular-expressions-java)
|
||||
- [Guide to Escaping Characters in Java RegExps](http://www.baeldung.com/java-regexp-escape-char)
|
||||
|
@ -11,3 +12,4 @@
|
|||
- [How to Use Regular Expressions to Replace Tokens in Strings](https://www.baeldung.com/java-regex-token-replacement)
|
||||
- [Regular Expressions \s and \s+ in Java](https://www.baeldung.com/java-regex-s-splus)
|
||||
- [Validate Phone Numbers With Java Regex](https://www.baeldung.com/java-regex-validate-phone-numbers)
|
||||
- [How to Count the Number of Matches for a Regex?](https://www.baeldung.com/java-count-regex-matches)
|
||||
|
|
|
@ -9,4 +9,5 @@ This module contains articles about core Java Security
|
|||
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
|
||||
- [SHA-256 and SHA3-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java)
|
||||
- [Checksums in Java](https://www.baeldung.com/java-checksums)
|
||||
- [How to Read PEM File to Get Public and Private Keys](https://www.baeldung.com/java-read-pem-file-keys)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-security)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Version Comparison in Java](https://www.baeldung.com/java-comparing-versions)
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-string-operations-3</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-string-operations-3</name>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-artifact</artifactId>
|
||||
<version>${maven-artifact.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gradle</groupId>
|
||||
<artifactId>gradle-core</artifactId>
|
||||
<version>${gradle-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.vdurmont</groupId>
|
||||
<artifactId>semver4j</artifactId>
|
||||
<version>${semver4j.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<maven-artifact.version>3.6.3</maven-artifact.version>
|
||||
<gradle-core.version>6.1.1</gradle-core.version>
|
||||
<jackson-core.version>2.11.1</jackson-core.version>
|
||||
<semver4j.version>3.1.0</semver4j.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gradle-repo</id>
|
||||
<url>https://repo.gradle.org/gradle/libs-releases-local/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.versioncomparison;
|
||||
|
||||
public class VersionCompare {
|
||||
|
||||
public static int compareVersions(String version1, String version2) {
|
||||
int comparisonResult = 0;
|
||||
|
||||
String[] version1Splits = version1.split("\\.");
|
||||
String[] version2Splits = version2.split("\\.");
|
||||
|
||||
int maxLengthOfVersionSplits = Math.max(version1Splits.length, version2Splits.length);
|
||||
for (int i = 0; i < maxLengthOfVersionSplits; i++){
|
||||
Integer v1 = i < version1Splits.length ? Integer.parseInt(version1Splits[i]) : 0;
|
||||
Integer v2 = i < version2Splits.length ? Integer.parseInt(version2Splits[i]) : 0;
|
||||
int compare = v1.compareTo(v2);
|
||||
if (compare != 0) {
|
||||
comparisonResult = compare;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return comparisonResult;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
package com.baeldung.versioncomparison;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.fasterxml.jackson.core.Version;
|
||||
import com.vdurmont.semver4j.Semver;
|
||||
import com.vdurmont.semver4j.Semver.VersionDiff;
|
||||
|
||||
import org.apache.maven.artifact.versioning.ComparableVersion;
|
||||
import org.gradle.util.VersionNumber;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class VersionComparisonUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenVersionStrings_whenUsingMavenArtifact_thenCompareVersions() {
|
||||
ComparableVersion version1_1 = new ComparableVersion("1.1");
|
||||
ComparableVersion version1_2 = new ComparableVersion("1.2");
|
||||
ComparableVersion version1_3 = new ComparableVersion("1.3");
|
||||
|
||||
assertTrue(version1_1.compareTo(version1_2) < 0);
|
||||
assertTrue(version1_3.compareTo(version1_2) > 0);
|
||||
|
||||
ComparableVersion version1_1_0 = new ComparableVersion("1.1.0");
|
||||
assertEquals(0, version1_1.compareTo(version1_1_0));
|
||||
|
||||
ComparableVersion version1_1_alpha = new ComparableVersion("1.1-alpha");
|
||||
assertTrue(version1_1.compareTo(version1_1_alpha) > 0);
|
||||
|
||||
ComparableVersion version1_1_beta = new ComparableVersion("1.1-beta");
|
||||
ComparableVersion version1_1_milestone = new ComparableVersion("1.1-milestone");
|
||||
ComparableVersion version1_1_rc = new ComparableVersion("1.1-rc");
|
||||
ComparableVersion version1_1_snapshot = new ComparableVersion("1.1-snapshot");
|
||||
|
||||
assertTrue(version1_1_alpha.compareTo(version1_1_beta) < 0);
|
||||
assertTrue(version1_1_beta.compareTo(version1_1_milestone) < 0);
|
||||
assertTrue(version1_1_rc.compareTo(version1_1_snapshot) < 0);
|
||||
assertTrue(version1_1_snapshot.compareTo(version1_1) < 0);
|
||||
|
||||
ComparableVersion version1_1_c = new ComparableVersion("1.1-c");
|
||||
ComparableVersion version1_1_z = new ComparableVersion("1.1-z");
|
||||
ComparableVersion version1_1_1 = new ComparableVersion("1.1.1");
|
||||
|
||||
assertTrue(version1_1_c.compareTo(version1_1_z) < 0);
|
||||
assertTrue(version1_1_z.compareTo(version1_1_1) < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVersionStrings_whenUsingGradle_thenCompareVersions() {
|
||||
VersionNumber version1_1 = VersionNumber.parse("1.1");
|
||||
VersionNumber version1_2 = VersionNumber.parse("1.2");
|
||||
VersionNumber version1_3 = VersionNumber.parse("1.3");
|
||||
|
||||
assertTrue(version1_1.compareTo(version1_2) < 0);
|
||||
assertTrue(version1_3.compareTo(version1_2) > 0);
|
||||
|
||||
VersionNumber version1_1_0 = VersionNumber.parse("1.1.0");
|
||||
assertEquals(0, version1_1.compareTo(version1_1_0));
|
||||
|
||||
VersionNumber version1_1_1_1_alpha = VersionNumber.parse("1.1.1.1-alpha");
|
||||
assertTrue(version1_1.compareTo(version1_1_1_1_alpha) < 0);
|
||||
|
||||
VersionNumber version1_1_beta = VersionNumber.parse("1.1.0.0-beta");
|
||||
assertTrue(version1_1_beta.compareTo(version1_1_1_1_alpha) < 0);
|
||||
|
||||
VersionNumber version1_1_1_snapshot = VersionNumber.parse("1.1.1-snapshot");
|
||||
assertTrue(version1_1_1_1_alpha.compareTo(version1_1_1_snapshot) < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVersionStrings_whenUsingJackson_thenCompareVersions() {
|
||||
Version version1_1 = new Version(1, 1, 0, null, null, null);
|
||||
Version version1_2 = new Version(1, 2, 0, null, null, null);
|
||||
Version version1_3 = new Version(1, 3, 0, null, null, null);
|
||||
|
||||
assertTrue(version1_1.compareTo(version1_2) < 0);
|
||||
assertTrue(version1_3.compareTo(version1_2) > 0);
|
||||
|
||||
Version version1_1_1 = new Version(1, 1, 1, null, null, null);
|
||||
assertTrue(version1_1.compareTo(version1_1_1) < 0);
|
||||
|
||||
Version version1_1_maven = new Version(1, 1, 0, null, "org.apache.maven", null);
|
||||
Version version1_1_gradle = new Version(1, 1, 0, null, "org.gradle", null);
|
||||
assertTrue(version1_1_maven.compareTo(version1_1_gradle) < 0);
|
||||
|
||||
Version version1_1_snapshot = new Version(1, 1, 0, "snapshot", null, null);
|
||||
assertEquals(0, version1_1.compareTo(version1_1_snapshot));
|
||||
|
||||
assertTrue(version1_1_snapshot.isSnapshot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVersionStrings_whenUsingSemver_thenCompareVersions() {
|
||||
Semver version1_1 = new Semver("1.1.0");
|
||||
Semver version1_2 = new Semver("1.2.0");
|
||||
Semver version1_3 = new Semver("1.3.0");
|
||||
|
||||
assertTrue(version1_1.compareTo(version1_2) < 0);
|
||||
assertTrue(version1_3.compareTo(version1_2) > 0);
|
||||
|
||||
Semver version1_1_alpha = new Semver("1.1.0-alpha");
|
||||
assertTrue(version1_1.isGreaterThan(version1_1_alpha));
|
||||
|
||||
Semver version1_1_beta = new Semver("1.1.0-beta");
|
||||
Semver version1_1_milestone = new Semver("1.1.0-milestone");
|
||||
Semver version1_1_rc = new Semver("1.1.0-rc");
|
||||
Semver version1_1_snapshot = new Semver("1.1.0-snapshot");
|
||||
|
||||
assertTrue(version1_1_alpha.isLowerThan(version1_1_beta));
|
||||
assertTrue(version1_1_beta.compareTo(version1_1_milestone) < 0);
|
||||
assertTrue(version1_1_rc.compareTo(version1_1_snapshot) < 0);
|
||||
assertTrue(version1_1_snapshot.compareTo(version1_1) < 0);
|
||||
|
||||
assertTrue(version1_1.isEqualTo("1.1.0"));
|
||||
|
||||
assertEquals(VersionDiff.MAJOR, version1_1.diff("2.1.0"));
|
||||
assertEquals(VersionDiff.MINOR, version1_1.diff("1.2.3"));
|
||||
assertEquals(VersionDiff.PATCH, version1_1.diff("1.1.1"));
|
||||
|
||||
assertTrue(version1_1.isStable());
|
||||
assertFalse(version1_1_alpha.isStable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVersionStrings_whenUsingCustomVersionCompare_thenCompareVersions() {
|
||||
assertTrue(VersionCompare.compareVersions("1.0.1", "1.1.2") < 0);
|
||||
assertTrue(VersionCompare.compareVersions("1.0.1", "1.10") < 0);
|
||||
assertTrue(VersionCompare.compareVersions("1.1.2", "1.0.1") > 0);
|
||||
assertTrue(VersionCompare.compareVersions("1.1.2", "1.2") < 0);
|
||||
assertEquals(0, VersionCompare.compareVersions("1.3.0", "1.3"));
|
||||
}
|
||||
|
||||
}
|
|
@ -72,6 +72,7 @@
|
|||
|
||||
<module>core-java-io</module>
|
||||
<module>core-java-io-2</module>
|
||||
<module>core-java-io-3</module>
|
||||
<module>core-java-io-apis</module>
|
||||
<module>core-java-io-conversions</module>
|
||||
<module>core-java-io-conversions-2</module>
|
||||
|
@ -126,6 +127,7 @@
|
|||
<module>core-java-string-conversions-2</module>
|
||||
<module>core-java-string-operations</module>
|
||||
<module>core-java-string-operations-2</module>
|
||||
<module>core-java-string-operations-3</module>
|
||||
<module>core-java-strings</module>
|
||||
<module>core-java-sun</module>
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
This module contains articles about core Kotlin collections.
|
||||
|
||||
### Relevant articles:
|
||||
|
||||
- [Split a List Into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
|
||||
- [Finding an Element in a List Using Kotlin](https://www.baeldung.com/kotlin-finding-element-in-list)
|
||||
- [Overview of Kotlin Collections API](https://www.baeldung.com/kotlin-collections-api)
|
||||
|
@ -12,3 +13,4 @@ This module contains articles about core Kotlin collections.
|
|||
- [Difference between fold and reduce in Kotlin](https://www.baeldung.com/kotlin/fold-vs-reduce)
|
||||
- [Guide to Sorting in Kotlin](https://www.baeldung.com/kotlin-sort)
|
||||
- [Working With Lists in Kotlin](https://www.baeldung.com/kotlin/lists)
|
||||
- [Iterating Collections by Index in Kotlin](https://www.baeldung.com/kotlin/iterating-collections-by-index)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.baeldung.index
|
||||
|
||||
fun main() {
|
||||
|
||||
// Index only
|
||||
val colors = listOf("Red", "Green", "Blue")
|
||||
for (i in colors.indices) {
|
||||
println(colors[i])
|
||||
}
|
||||
|
||||
val colorArray = arrayOf("Red", "Green", "Blue")
|
||||
for (i in colorArray.indices) {
|
||||
println(colorArray[i])
|
||||
}
|
||||
|
||||
(0 until colors.size).forEach { println(colors[it]) }
|
||||
for (i in 0 until colors.size) {
|
||||
println(colors[i])
|
||||
}
|
||||
|
||||
// Index and Value
|
||||
colors.forEachIndexed { i, v -> println("The value for index $i is $v") }
|
||||
for (indexedValue in colors.withIndex()) {
|
||||
println("The value for index ${indexedValue.index} is ${indexedValue.value}")
|
||||
}
|
||||
|
||||
for ((i, v) in colors.withIndex()) {
|
||||
println("The value for index $i is $v")
|
||||
}
|
||||
|
||||
colors.filterIndexed { i, _ -> i % 2 == 0 }
|
||||
colors.filterIndexed { _, v -> v == "RED" }
|
||||
}
|
|
@ -7,7 +7,6 @@ This module contains articles about core features in the Kotlin language.
|
|||
- [Infix Functions in Kotlin](https://www.baeldung.com/kotlin-infix-functions)
|
||||
- [Lambda Expressions in Kotlin](https://www.baeldung.com/kotlin-lambda-expressions)
|
||||
- [Creating Java static final Equivalents in Kotlin](https://www.baeldung.com/kotlin-java-static-final)
|
||||
- [Initializing Arrays in Kotlin](https://www.baeldung.com/kotlin-initialize-array)
|
||||
- [Lazy Initialization in Kotlin](https://www.baeldung.com/kotlin-lazy-initialization)
|
||||
- [Comprehensive Guide to Null Safety in Kotlin](https://www.baeldung.com/kotlin-null-safety)
|
||||
- [Kotlin Scope Functions](https://www.baeldung.com/kotlin-scope-functions)
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
package com.baeldung.arrayinitialization
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ArrayInitializationTest {
|
||||
|
||||
@Test
|
||||
fun givenArrayOfStrings_thenValuesPopulated() {
|
||||
val strings = arrayOf("January", "February", "March")
|
||||
|
||||
assertEquals(3, strings.size)
|
||||
assertEquals("March", strings[2])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenArrayOfIntegers_thenValuesPopulated() {
|
||||
val integers = intArrayOf(1, 2, 3, 4)
|
||||
|
||||
assertEquals(4, integers.size)
|
||||
assertEquals(1, integers[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenArrayOfNulls_whenPopulated_thenValuesPresent() {
|
||||
val array = arrayOfNulls<Number>(5)
|
||||
|
||||
for (i in array.indices) {
|
||||
array[i] = i * i
|
||||
}
|
||||
|
||||
assertEquals(16, array[4])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGeneratorUsed_thenValuesPresent() {
|
||||
val generatedArray = IntArray(10) { i -> i * i }
|
||||
|
||||
assertEquals(81, generatedArray[9])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenStringGenerated_thenValuesPresent() {
|
||||
val generatedStringArray = Array(10) { i -> "Number of index: $i" }
|
||||
|
||||
assertEquals("Number of index: 0", generatedStringArray[0])
|
||||
}
|
||||
|
||||
}
|
|
@ -7,4 +7,5 @@ This module contains articles about Object-Oriented Programming in Kotlin
|
|||
- [Generics in Kotlin](https://www.baeldung.com/kotlin-generics)
|
||||
- [Delegated Properties in Kotlin](https://www.baeldung.com/kotlin-delegated-properties)
|
||||
- [Delegation Pattern in Kotlin](https://www.baeldung.com/kotlin-delegation-pattern)
|
||||
- [Anonymous Inner Classes in Kotlin](https://www.baeldung.com/kotlin/anonymous-inner-classes)
|
||||
- [[<-- Prev]](/core-kotlin-modules/core-kotlin-lang-oop)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.anonymous
|
||||
|
||||
import java.io.Serializable
|
||||
import java.nio.channels.Channel
|
||||
|
||||
fun main() {
|
||||
val channel = object : Channel {
|
||||
override fun isOpen() = false
|
||||
|
||||
override fun close() {
|
||||
}
|
||||
}
|
||||
|
||||
val maxEntries = 10
|
||||
val lruCache = object : LinkedHashMap<String, Int>(10, 0.75f) {
|
||||
|
||||
override fun removeEldestEntry(eldest: MutableMap.MutableEntry<String, Int>?): Boolean {
|
||||
return size > maxEntries
|
||||
}
|
||||
}
|
||||
|
||||
val map = object : LinkedHashMap<String, Int>() {
|
||||
// omitted
|
||||
}
|
||||
|
||||
val serializableChannel = object : Channel, Serializable {
|
||||
override fun isOpen(): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
val obj = object {
|
||||
val question = "answer"
|
||||
val answer = 42
|
||||
}
|
||||
println("The ${obj.question} is ${obj.answer}")
|
||||
}
|
|
@ -11,3 +11,4 @@ This module contains articles about data structures in Java
|
|||
- [Introduction to Big Queue](https://www.baeldung.com/java-big-queue)
|
||||
- [Guide to AVL Trees in Java](https://www.baeldung.com/java-avl-trees)
|
||||
- [Graphs in Java](https://www.baeldung.com/java-graphs)
|
||||
- [Implementing a Ring Buffer in Java](https://www.baeldung.com/java-ring-buffer)
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.ddd.order.config;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
|
||||
@Configuration
|
||||
public class CustomMongoConfiguration {
|
||||
|
||||
@Bean
|
||||
public MongoCustomConversions customConversions() {
|
||||
return new MongoCustomConversions(Collections.singletonList(DocumentToMoneyConverter.INSTANCE));
|
||||
}
|
||||
|
||||
@ReadingConverter
|
||||
enum DocumentToMoneyConverter implements Converter<Document, Money> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Money convert(Document source) {
|
||||
Document money = source.get("money", Document.class);
|
||||
|
||||
return Money.of(getCurrency(money), getAmount(money));
|
||||
}
|
||||
|
||||
private CurrencyUnit getCurrency(Document money) {
|
||||
Document currency = money.get("currency", Document.class);
|
||||
String currencyCode = currency.getString("code");
|
||||
return CurrencyUnit.of(currencyCode);
|
||||
}
|
||||
|
||||
private BigDecimal getAmount(Document money) {
|
||||
String amount = money.getString("amount");
|
||||
return BigDecimal.valueOf(Double.parseDouble(amount));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,24 @@
|
|||
package com.baeldung.ddd.order.jpa;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/*
|
||||
To run this test we need to run the databases first.
|
||||
A dedicated docker-compose.yml file is located under the resources directory.
|
||||
We can run it by simple executing `docker-compose up`.
|
||||
*/
|
||||
@SpringJUnitConfig
|
||||
@SpringBootTest
|
||||
public class PersistOrderIntegrationTest {
|
||||
public class PersistOrderLiveTest {
|
||||
@Autowired
|
||||
private JpaOrderRepository repository;
|
||||
|
|
@ -17,9 +17,14 @@ import com.baeldung.ddd.order.Order;
|
|||
import com.baeldung.ddd.order.OrderLine;
|
||||
import com.baeldung.ddd.order.Product;
|
||||
|
||||
/*
|
||||
To run this test we need to run the databases first.
|
||||
A dedicated docker-compose.yml file is located under the resources directory.
|
||||
We can run it by simple executing `docker-compose up`.
|
||||
*/
|
||||
@SpringJUnitConfig
|
||||
@SpringBootTest
|
||||
public class OrderMongoIntegrationTest {
|
||||
public class OrderMongoLiveTest {
|
||||
@Autowired
|
||||
private OrderMongoRepository repo;
|
||||
|
|
@ -18,10 +18,15 @@ import com.baeldung.dddhexagonalspring.domain.Product;
|
|||
import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository;
|
||||
import com.baeldung.dddhexagonalspring.infrastracture.repository.cassandra.SpringDataCassandraOrderRepository;
|
||||
|
||||
/*
|
||||
To run this test we need to run the databases first.
|
||||
A dedicated docker-compose.yml file is located under the resources directory.
|
||||
We can run it by simple executing `docker-compose up`.
|
||||
*/
|
||||
@SpringJUnitConfig
|
||||
@SpringBootTest
|
||||
@TestPropertySource("classpath:ddd-layers-test.properties")
|
||||
class CassandraDbOrderRepositoryIntegrationTest {
|
||||
class CassandraDbOrderRepositoryLiveTest {
|
||||
|
||||
@Autowired
|
||||
private SpringDataCassandraOrderRepository cassandraOrderRepository;
|
|
@ -18,10 +18,15 @@ import com.baeldung.dddhexagonalspring.domain.Product;
|
|||
import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository;
|
||||
import com.baeldung.dddhexagonalspring.infrastracture.repository.mongo.SpringDataMongoOrderRepository;
|
||||
|
||||
/*
|
||||
To run this test we need to run the databases first.
|
||||
A dedicated docker-compose.yml file is located under the resources directory.
|
||||
We can run it by simple executing `docker-compose up`.
|
||||
*/
|
||||
@SpringJUnitConfig
|
||||
@SpringBootTest
|
||||
@TestPropertySource("classpath:ddd-layers-test.properties")
|
||||
class MongoDbOrderRepositoryIntegrationTest {
|
||||
class MongoDbOrderRepositoryLiveTest {
|
||||
|
||||
@Autowired
|
||||
private SpringDataMongoOrderRepository mongoOrderRepository;
|
|
@ -0,0 +1,310 @@
|
|||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=`cygpath --path --windows "$javaClass"`
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
@ -0,0 +1,182 @@
|
|||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
|
||||
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
|
@ -0,0 +1,54 @@
|
|||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.3.1.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.baeldung.docker</groupId>
|
||||
<artifactId>spring-boot-docker</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-boot-docker</name>
|
||||
<description>Demo project showing Spring Boot and Docker</description>
|
||||
|
||||
<properties>
|
||||
<java.version>8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<layers>
|
||||
<enabled>true</enabled>
|
||||
</layers>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,15 @@
|
|||
# To build, run the following command from the top level project directory:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile .
|
||||
|
||||
FROM adoptopenjdk:11-jre-hotspot as builder
|
||||
ARG JAR_FILE=target/*.jar
|
||||
COPY ${JAR_FILE} application.jar
|
||||
RUN java -Djarmode=layertools -jar application.jar extract
|
||||
|
||||
FROM adoptopenjdk:11-jre-hotspot
|
||||
COPY --from=builder dependencies/ ./
|
||||
COPY --from=builder snapshot-dependencies/ ./
|
||||
COPY --from=builder spring-boot-loader/ ./
|
||||
COPY --from=builder application/ ./
|
||||
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.docker;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.docker;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class HelloController {
|
||||
|
||||
@GetMapping("/hello")
|
||||
public ResponseEntity<String> hello()
|
||||
{
|
||||
return ResponseEntity.ok("hello2 ");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Run a Java main Method Using Gradle](https://www.baeldung.com/gradle-run-java-main)
|
||||
- [Finding Unused Gradle Dependencies](https://www.baeldung.com/gradle-finding-unused-dependencies)
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
This module contains articles a Google Guava
|
||||
|
||||
### Relevant Articles:
|
||||
- [Introduction to Guava Throwables](https://www.baeldung.com/guava-throwables)
|
||||
|
||||
- [Guava CharMatcher](https://www.baeldung.com/guava-string-charmatcher)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
This module contains articles a Google Guava
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Guava Functional Cookbook](https://www.baeldung.com/guava-functions-predicates)
|
||||
- [Guide to Guava’s PreConditions](https://www.baeldung.com/guava-preconditions)
|
||||
- [Introduction to Guava CacheLoader](https://www.baeldung.com/guava-cacheloader)
|
||||
|
@ -13,3 +14,4 @@ This module contains articles a Google Guava
|
|||
- [Bloom Filter in Java using Guava](https://www.baeldung.com/guava-bloom-filter)
|
||||
- [Quick Guide to the Guava RateLimiter](https://www.baeldung.com/guava-rate-limiter)
|
||||
- [Guava Cache](https://www.baeldung.com/guava-cache)
|
||||
- [Introduction to Guava Throwables](https://www.baeldung.com/guava-throwables)
|
||||
|
|
|
@ -6,3 +6,5 @@ This module contains articles about image processing.
|
|||
- [Working with Images in Java](https://www.baeldung.com/java-images)
|
||||
- [Intro to OpenCV with Java](https://www.baeldung.com/java-opencv)
|
||||
- [Optical Character Recognition with Tesseract](https://www.baeldung.com/java-ocr-tesseract)
|
||||
- [How Can I Resize an Image Using Java?](https://www.baeldung.com/java-resize-image)
|
||||
- [Adding Text to an Image in Java](https://www.baeldung.com/java-add-text-to-image)
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.convertlisttomap;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Convert a string list to a map whose key is the string's length and value is the collection with same length.
|
||||
* Give a list {"Baeldung", "is", "very", "cool"}.
|
||||
* After conversion we'll get a map like:
|
||||
* {8 : ["Baeldung"], 2 : ["is"], 4 : ["very", "cool"]}.
|
||||
*
|
||||
* @author leasy.zhang
|
||||
*
|
||||
*/
|
||||
public class ListToMapConverter {
|
||||
|
||||
public Map<Integer, List<String>> groupingByStringLength(List<String> source,
|
||||
Supplier<Map<Integer, List<String>>> mapSupplier,
|
||||
Supplier<List<String>> listSupplier) {
|
||||
|
||||
return source.stream()
|
||||
.collect(Collectors.groupingBy(String::length, mapSupplier, Collectors.toCollection(listSupplier)));
|
||||
}
|
||||
|
||||
public Map<Integer, List<String>> streamCollectByStringLength(List<String> source,
|
||||
Supplier<Map<Integer, List<String>>> mapSupplier,
|
||||
Supplier<List<String>> listSupplier) {
|
||||
|
||||
BiConsumer<Map<Integer, List<String>>, String> accumulator = (response, element) -> {
|
||||
Integer key = element.length();
|
||||
List<String> values = response.getOrDefault(key, listSupplier.get());
|
||||
values.add(element);
|
||||
response.put(key, values);
|
||||
};
|
||||
|
||||
BiConsumer<Map<Integer, List<String>>, Map<Integer, List<String>>> combiner = (res1, res2) -> {
|
||||
res1.putAll(res2);
|
||||
};
|
||||
|
||||
return source.stream()
|
||||
.collect(mapSupplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public Map<Integer, List<String>> collectorToMapByStringLength(List<String> source,
|
||||
Supplier<Map<Integer, List<String>>> mapSupplier,
|
||||
Supplier<List<String>> listSupplier) {
|
||||
|
||||
Function<String, Integer> keyMapper = String::length;
|
||||
|
||||
Function<String, List<String>> valueMapper = (element) -> {
|
||||
List<String> collection = listSupplier.get();
|
||||
collection.add(element);
|
||||
return collection;
|
||||
};
|
||||
|
||||
BinaryOperator<List<String>> mergeFunction = (existing, replacement) -> {
|
||||
existing.addAll(replacement);
|
||||
return existing;
|
||||
};
|
||||
|
||||
return source.stream()
|
||||
.collect(Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapSupplier));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.convertlisttomap;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ListToMapUnitTest {
|
||||
|
||||
private ListToMapConverter converter;
|
||||
private List<String> source;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
converter = new ListToMapConverter();
|
||||
source = Arrays.asList("List", "Map", "Set", "Tree");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAList_whenConvertWithJava8GroupBy_thenReturnMap() {
|
||||
Map<Integer, List<String>> convertedMap = converter.groupingByStringLength(source, HashMap::new, ArrayList::new);
|
||||
assertTrue(convertedMap.get(3)
|
||||
.contains("Map"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAList_whenConvertWithJava8Collect_thenReturnMap() {
|
||||
Map<Integer, List<String>> convertedMap = converter.streamCollectByStringLength(source, HashMap::new, ArrayList::new);
|
||||
assertTrue(convertedMap.get(3)
|
||||
.contains("Map"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAList_whenConvertWithCollectorToMap_thenReturnMap() {
|
||||
Map<Integer, List<String>> convertedMap = converter.collectorToMapByStringLength(source, HashMap::new, ArrayList::new);
|
||||
assertTrue(convertedMap.get(3)
|
||||
.contains("Map"));
|
||||
}
|
||||
|
||||
}
|
|
@ -11,4 +11,7 @@ This module contains articles about numbers in Java.
|
|||
- [Listing Numbers Within a Range in Java](https://www.baeldung.com/java-listing-numbers-within-a-range)
|
||||
- [Fibonacci Series in Java](https://www.baeldung.com/java-fibonacci)
|
||||
- [Guide to the Number Class in Java](https://www.baeldung.com/java-number-class)
|
||||
- [Print an Integer in Binary Format in Java](https://www.baeldung.com/java-print-integer-binary)
|
||||
- [Number Formatting in Java](https://www.baeldung.com/java-number-formatting)
|
||||
- [Division by Zero in Java: Exception, Infinity, or Not a Number](https://www.baeldung.com/java-division-by-zero)
|
||||
- More articles: [[<-- prev]](/java-numbers-2)
|
||||
|
|
|
@ -5,4 +5,4 @@ This module contains articles about the Java Microbenchmark Harness (JMH).
|
|||
### Relevant articles:
|
||||
|
||||
- [Microbenchmarking with Java](https://www.baeldung.com/java-microbenchmark-harness)
|
||||
|
||||
- [A Guide to False Sharing and @Contended](https://www.baeldung.com/java-false-sharing-contended)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.falsesharing;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public class FalseSharing {
|
||||
|
||||
private java.util.concurrent.atomic.LongAdder builtin = new java.util.concurrent.atomic.LongAdder();
|
||||
private LongAdder custom = new LongAdder();
|
||||
|
||||
@Benchmark
|
||||
public void builtin() {
|
||||
builtin.increment();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void custom() {
|
||||
custom.increment();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
package com.baeldung.falsesharing;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Copy-pasted from {@link java.util.concurrent.atomic.LongAdder}
|
||||
*
|
||||
* One or more variables that together maintain an initially zero
|
||||
* {@code long} sum. When updates (method {@link #add}) are contended
|
||||
* across threads, the set of variables may grow dynamically to reduce
|
||||
* contention. Method {@link #sum} (or, equivalently, {@link
|
||||
* #longValue}) returns the current total combined across the
|
||||
* variables maintaining the sum.
|
||||
*
|
||||
* <p>This class is usually preferable to {@link AtomicLong} when
|
||||
* multiple threads update a common sum that is used for purposes such
|
||||
* as collecting statistics, not for fine-grained synchronization
|
||||
* control. Under low update contention, the two classes have similar
|
||||
* characteristics. But under high contention, expected throughput of
|
||||
* this class is significantly higher, at the expense of higher space
|
||||
* consumption.
|
||||
*
|
||||
* <p>LongAdders can be used with a {@link
|
||||
* java.util.concurrent.ConcurrentHashMap} to maintain a scalable
|
||||
* frequency map (a form of histogram or multiset). For example, to
|
||||
* add a count to a {@code ConcurrentHashMap<String,LongAdder> freqs},
|
||||
* initializing if not already present, you can use {@code
|
||||
* freqs.computeIfAbsent(k -> new LongAdder()).increment();}
|
||||
*
|
||||
* <p>This class extends {@link Number}, but does <em>not</em> define
|
||||
* methods such as {@code equals}, {@code hashCode} and {@code
|
||||
* compareTo} because instances are expected to be mutated, and so are
|
||||
* not useful as collection keys.
|
||||
*
|
||||
* @since 1.8
|
||||
* @author Doug Lea
|
||||
*/
|
||||
public class LongAdder extends Striped64 implements Serializable {
|
||||
private static final long serialVersionUID = 7249069246863182397L;
|
||||
|
||||
/**
|
||||
* Creates a new adder with initial sum of zero.
|
||||
*/
|
||||
public LongAdder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given value.
|
||||
*
|
||||
* @param x the value to add
|
||||
*/
|
||||
public void add(long x) {
|
||||
Cell[] as; long b, v; int m; Cell a;
|
||||
if ((as = cells) != null || !casBase(b = base, b + x)) {
|
||||
boolean uncontended = true;
|
||||
if (as == null || (m = as.length - 1) < 0 ||
|
||||
(a = as[getProbe() & m]) == null ||
|
||||
!(uncontended = a.cas(v = a.value, v + x)))
|
||||
longAccumulate(x, null, uncontended);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@code add(1)}.
|
||||
*/
|
||||
public void increment() {
|
||||
add(1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@code add(-1)}.
|
||||
*/
|
||||
public void decrement() {
|
||||
add(-1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current sum. The returned value is <em>NOT</em> an
|
||||
* atomic snapshot; invocation in the absence of concurrent
|
||||
* updates returns an accurate result, but concurrent updates that
|
||||
* occur while the sum is being calculated might not be
|
||||
* incorporated.
|
||||
*
|
||||
* @return the sum
|
||||
*/
|
||||
public long sum() {
|
||||
Cell[] as = cells; Cell a;
|
||||
long sum = base;
|
||||
if (as != null) {
|
||||
for (int i = 0; i < as.length; ++i) {
|
||||
if ((a = as[i]) != null)
|
||||
sum += a.value;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets variables maintaining the sum to zero. This method may
|
||||
* be a useful alternative to creating a new adder, but is only
|
||||
* effective if there are no concurrent updates. Because this
|
||||
* method is intrinsically racy, it should only be used when it is
|
||||
* known that no threads are concurrently updating.
|
||||
*/
|
||||
public void reset() {
|
||||
Cell[] as = cells; Cell a;
|
||||
base = 0L;
|
||||
if (as != null) {
|
||||
for (int i = 0; i < as.length; ++i) {
|
||||
if ((a = as[i]) != null)
|
||||
a.value = 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent in effect to {@link #sum} followed by {@link
|
||||
* #reset}. This method may apply for example during quiescent
|
||||
* points between multithreaded computations. If there are
|
||||
* updates concurrent with this method, the returned value is
|
||||
* <em>not</em> guaranteed to be the final value occurring before
|
||||
* the reset.
|
||||
*
|
||||
* @return the sum
|
||||
*/
|
||||
public long sumThenReset() {
|
||||
Cell[] as = cells; Cell a;
|
||||
long sum = base;
|
||||
base = 0L;
|
||||
if (as != null) {
|
||||
for (int i = 0; i < as.length; ++i) {
|
||||
if ((a = as[i]) != null) {
|
||||
sum += a.value;
|
||||
a.value = 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the {@link #sum}.
|
||||
* @return the String representation of the {@link #sum}
|
||||
*/
|
||||
public String toString() {
|
||||
return Long.toString(sum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@link #sum}.
|
||||
*
|
||||
* @return the sum
|
||||
*/
|
||||
public long longValue() {
|
||||
return sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link #sum} as an {@code int} after a narrowing
|
||||
* primitive conversion.
|
||||
*/
|
||||
public int intValue() {
|
||||
return (int)sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link #sum} as a {@code float}
|
||||
* after a widening primitive conversion.
|
||||
*/
|
||||
public float floatValue() {
|
||||
return (float)sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link #sum} as a {@code double} after a widening
|
||||
* primitive conversion.
|
||||
*/
|
||||
public double doubleValue() {
|
||||
return (double)sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization proxy, used to avoid reference to the non-public
|
||||
* Striped64 superclass in serialized forms.
|
||||
* @serial include
|
||||
*/
|
||||
private static class SerializationProxy implements Serializable {
|
||||
private static final long serialVersionUID = 7249069246863182397L;
|
||||
|
||||
/**
|
||||
* The current value returned by sum().
|
||||
* @serial
|
||||
*/
|
||||
private final long value;
|
||||
|
||||
SerializationProxy(LongAdder a) {
|
||||
value = a.sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code LongAdder} object with initial state
|
||||
* held by this proxy.
|
||||
*
|
||||
* @return a {@code LongAdder} object with initial state
|
||||
* held by this proxy.
|
||||
*/
|
||||
private Object readResolve() {
|
||||
LongAdder a = new LongAdder();
|
||||
a.base = value;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a
|
||||
* <a href="../../../../serialized-form.html#java.util.concurrent.atomic.LongAdder.SerializationProxy">
|
||||
* SerializationProxy</a>
|
||||
* representing the state of this instance.
|
||||
*
|
||||
* @return a {@link SerializationProxy}
|
||||
* representing the state of this instance
|
||||
*/
|
||||
private Object writeReplace() {
|
||||
return new SerializationProxy(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s the stream
|
||||
* @throws java.io.InvalidObjectException always
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws java.io.InvalidObjectException {
|
||||
throw new java.io.InvalidObjectException("Proxy required");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,395 @@
|
|||
package com.baeldung.falsesharing;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* Copy-pasted from {@code java.util.concurrent.atomic.Striped64} class.
|
||||
*
|
||||
* A package-local class holding common representation and mechanics
|
||||
* for classes supporting dynamic striping on 64bit values. The class
|
||||
* extends Number so that concrete subclasses must publicly do so.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
abstract class Striped64 extends Number {
|
||||
/*
|
||||
* This class maintains a lazily-initialized table of atomically
|
||||
* updated variables, plus an extra "base" field. The table size
|
||||
* is a power of two. Indexing uses masked per-thread hash codes.
|
||||
* Nearly all declarations in this class are package-private,
|
||||
* accessed directly by subclasses.
|
||||
*
|
||||
* Table entries are of class Cell; a variant of AtomicLong padded
|
||||
* (via @sun.misc.Contended) to reduce cache contention. Padding
|
||||
* is overkill for most Atomics because they are usually
|
||||
* irregularly scattered in memory and thus don't interfere much
|
||||
* with each other. But Atomic objects residing in arrays will
|
||||
* tend to be placed adjacent to each other, and so will most
|
||||
* often share cache lines (with a huge negative performance
|
||||
* impact) without this precaution.
|
||||
*
|
||||
* In part because Cells are relatively large, we avoid creating
|
||||
* them until they are needed. When there is no contention, all
|
||||
* updates are made to the base field. Upon first contention (a
|
||||
* failed CAS on base update), the table is initialized to size 2.
|
||||
* The table size is doubled upon further contention until
|
||||
* reaching the nearest power of two greater than or equal to the
|
||||
* number of CPUS. Table slots remain empty (null) until they are
|
||||
* needed.
|
||||
*
|
||||
* A single spinlock ("cellsBusy") is used for initializing and
|
||||
* resizing the table, as well as populating slots with new Cells.
|
||||
* There is no need for a blocking lock; when the lock is not
|
||||
* available, threads try other slots (or the base). During these
|
||||
* retries, there is increased contention and reduced locality,
|
||||
* which is still better than alternatives.
|
||||
*
|
||||
* The Thread probe fields maintained via ThreadLocalRandom serve
|
||||
* as per-thread hash codes. We let them remain uninitialized as
|
||||
* zero (if they come in this way) until they contend at slot
|
||||
* 0. They are then initialized to values that typically do not
|
||||
* often conflict with others. Contention and/or table collisions
|
||||
* are indicated by failed CASes when performing an update
|
||||
* operation. Upon a collision, if the table size is less than
|
||||
* the capacity, it is doubled in size unless some other thread
|
||||
* holds the lock. If a hashed slot is empty, and lock is
|
||||
* available, a new Cell is created. Otherwise, if the slot
|
||||
* exists, a CAS is tried. Retries proceed by "double hashing",
|
||||
* using a secondary hash (Marsaglia XorShift) to try to find a
|
||||
* free slot.
|
||||
*
|
||||
* The table size is capped because, when there are more threads
|
||||
* than CPUs, supposing that each thread were bound to a CPU,
|
||||
* there would exist a perfect hash function mapping threads to
|
||||
* slots that eliminates collisions. When we reach capacity, we
|
||||
* search for this mapping by randomly varying the hash codes of
|
||||
* colliding threads. Because search is random, and collisions
|
||||
* only become known via CAS failures, convergence can be slow,
|
||||
* and because threads are typically not bound to CPUS forever,
|
||||
* may not occur at all. However, despite these limitations,
|
||||
* observed contention rates are typically low in these cases.
|
||||
*
|
||||
* It is possible for a Cell to become unused when threads that
|
||||
* once hashed to it terminate, as well as in the case where
|
||||
* doubling the table causes no thread to hash to it under
|
||||
* expanded mask. We do not try to detect or remove such cells,
|
||||
* under the assumption that for long-running instances, observed
|
||||
* contention levels will recur, so the cells will eventually be
|
||||
* needed again; and for short-lived ones, it does not matter.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Padded variant of AtomicLong supporting only raw accesses plus CAS.
|
||||
*
|
||||
* JVM intrinsics note: It would be possible to use a release-only
|
||||
* form of CAS here, if it were provided.
|
||||
*/
|
||||
@sun.misc.Contended static final class Cell {
|
||||
volatile long value;
|
||||
Cell(long x) { value = x; }
|
||||
final boolean cas(long cmp, long val) {
|
||||
return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
|
||||
}
|
||||
|
||||
// Unsafe mechanics
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
private static final long valueOffset;
|
||||
static {
|
||||
try {
|
||||
UNSAFE = getUnsafe();
|
||||
Class<?> ak = Striped64.Cell.class;
|
||||
valueOffset = UNSAFE.objectFieldOffset
|
||||
(ak.getDeclaredField("value"));
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Number of CPUS, to place bound on table size */
|
||||
static final int NCPU = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
/**
|
||||
* Table of cells. When non-null, size is a power of 2.
|
||||
*/
|
||||
transient volatile Striped64.Cell[] cells;
|
||||
|
||||
/**
|
||||
* Base value, used mainly when there is no contention, but also as
|
||||
* a fallback during table initialization races. Updated via CAS.
|
||||
*/
|
||||
transient volatile long base;
|
||||
|
||||
/**
|
||||
* Spinlock (locked via CAS) used when resizing and/or creating Cells.
|
||||
*/
|
||||
transient volatile int cellsBusy;
|
||||
|
||||
/**
|
||||
* Package-private default constructor
|
||||
*/
|
||||
Striped64() {
|
||||
}
|
||||
|
||||
/**
|
||||
* CASes the base field.
|
||||
*/
|
||||
final boolean casBase(long cmp, long val) {
|
||||
return UNSAFE.compareAndSwapLong(this, BASE, cmp, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* CASes the cellsBusy field from 0 to 1 to acquire lock.
|
||||
*/
|
||||
final boolean casCellsBusy() {
|
||||
return UNSAFE.compareAndSwapInt(this, CELLSBUSY, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the probe value for the current thread.
|
||||
* Duplicated from ThreadLocalRandom because of packaging restrictions.
|
||||
*/
|
||||
static final int getProbe() {
|
||||
return UNSAFE.getInt(Thread.currentThread(), PROBE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pseudo-randomly advances and records the given probe value for the
|
||||
* given thread.
|
||||
* Duplicated from ThreadLocalRandom because of packaging restrictions.
|
||||
*/
|
||||
static final int advanceProbe(int probe) {
|
||||
probe ^= probe << 13; // xorshift
|
||||
probe ^= probe >>> 17;
|
||||
probe ^= probe << 5;
|
||||
UNSAFE.putInt(Thread.currentThread(), PROBE, probe);
|
||||
return probe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles cases of updates involving initialization, resizing,
|
||||
* creating new Cells, and/or contention. See above for
|
||||
* explanation. This method suffers the usual non-modularity
|
||||
* problems of optimistic retry code, relying on rechecked sets of
|
||||
* reads.
|
||||
*
|
||||
* @param x the value
|
||||
* @param fn the update function, or null for add (this convention
|
||||
* avoids the need for an extra field or function in LongAdder).
|
||||
* @param wasUncontended false if CAS failed before call
|
||||
*/
|
||||
final void longAccumulate(long x, LongBinaryOperator fn,
|
||||
boolean wasUncontended) {
|
||||
int h;
|
||||
if ((h = getProbe()) == 0) {
|
||||
ThreadLocalRandom.current(); // force initialization
|
||||
h = getProbe();
|
||||
wasUncontended = true;
|
||||
}
|
||||
boolean collide = false; // True if last slot nonempty
|
||||
for (;;) {
|
||||
Striped64.Cell[] as; Striped64.Cell a; int n; long v;
|
||||
if ((as = cells) != null && (n = as.length) > 0) {
|
||||
if ((a = as[(n - 1) & h]) == null) {
|
||||
if (cellsBusy == 0) { // Try to attach new Cell
|
||||
Striped64.Cell r = new Striped64.Cell(x); // Optimistically create
|
||||
if (cellsBusy == 0 && casCellsBusy()) {
|
||||
boolean created = false;
|
||||
try { // Recheck under lock
|
||||
Striped64.Cell[] rs; int m, j;
|
||||
if ((rs = cells) != null &&
|
||||
(m = rs.length) > 0 &&
|
||||
rs[j = (m - 1) & h] == null) {
|
||||
rs[j] = r;
|
||||
created = true;
|
||||
}
|
||||
} finally {
|
||||
cellsBusy = 0;
|
||||
}
|
||||
if (created)
|
||||
break;
|
||||
continue; // Slot is now non-empty
|
||||
}
|
||||
}
|
||||
collide = false;
|
||||
}
|
||||
else if (!wasUncontended) // CAS already known to fail
|
||||
wasUncontended = true; // Continue after rehash
|
||||
else if (a.cas(v = a.value, ((fn == null) ? v + x :
|
||||
fn.applyAsLong(v, x))))
|
||||
break;
|
||||
else if (n >= NCPU || cells != as)
|
||||
collide = false; // At max size or stale
|
||||
else if (!collide)
|
||||
collide = true;
|
||||
else if (cellsBusy == 0 && casCellsBusy()) {
|
||||
try {
|
||||
if (cells == as) { // Expand table unless stale
|
||||
Striped64.Cell[] rs = new Striped64.Cell[n << 1];
|
||||
for (int i = 0; i < n; ++i)
|
||||
rs[i] = as[i];
|
||||
cells = rs;
|
||||
}
|
||||
} finally {
|
||||
cellsBusy = 0;
|
||||
}
|
||||
collide = false;
|
||||
continue; // Retry with expanded table
|
||||
}
|
||||
h = advanceProbe(h);
|
||||
}
|
||||
else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
|
||||
boolean init = false;
|
||||
try { // Initialize table
|
||||
if (cells == as) {
|
||||
Striped64.Cell[] rs = new Striped64.Cell[2];
|
||||
rs[h & 1] = new Striped64.Cell(x);
|
||||
cells = rs;
|
||||
init = true;
|
||||
}
|
||||
} finally {
|
||||
cellsBusy = 0;
|
||||
}
|
||||
if (init)
|
||||
break;
|
||||
}
|
||||
else if (casBase(v = base, ((fn == null) ? v + x :
|
||||
fn.applyAsLong(v, x))))
|
||||
break; // Fall back on using base
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as longAccumulate, but injecting long/double conversions
|
||||
* in too many places to sensibly merge with long version, given
|
||||
* the low-overhead requirements of this class. So must instead be
|
||||
* maintained by copy/paste/adapt.
|
||||
*/
|
||||
final void doubleAccumulate(double x, DoubleBinaryOperator fn,
|
||||
boolean wasUncontended) {
|
||||
int h;
|
||||
if ((h = getProbe()) == 0) {
|
||||
ThreadLocalRandom.current(); // force initialization
|
||||
h = getProbe();
|
||||
wasUncontended = true;
|
||||
}
|
||||
boolean collide = false; // True if last slot nonempty
|
||||
for (;;) {
|
||||
Striped64.Cell[] as; Striped64.Cell a; int n; long v;
|
||||
if ((as = cells) != null && (n = as.length) > 0) {
|
||||
if ((a = as[(n - 1) & h]) == null) {
|
||||
if (cellsBusy == 0) { // Try to attach new Cell
|
||||
Striped64.Cell r = new Striped64.Cell(Double.doubleToRawLongBits(x));
|
||||
if (cellsBusy == 0 && casCellsBusy()) {
|
||||
boolean created = false;
|
||||
try { // Recheck under lock
|
||||
Striped64.Cell[] rs; int m, j;
|
||||
if ((rs = cells) != null &&
|
||||
(m = rs.length) > 0 &&
|
||||
rs[j = (m - 1) & h] == null) {
|
||||
rs[j] = r;
|
||||
created = true;
|
||||
}
|
||||
} finally {
|
||||
cellsBusy = 0;
|
||||
}
|
||||
if (created)
|
||||
break;
|
||||
continue; // Slot is now non-empty
|
||||
}
|
||||
}
|
||||
collide = false;
|
||||
}
|
||||
else if (!wasUncontended) // CAS already known to fail
|
||||
wasUncontended = true; // Continue after rehash
|
||||
else if (a.cas(v = a.value,
|
||||
((fn == null) ?
|
||||
Double.doubleToRawLongBits
|
||||
(Double.longBitsToDouble(v) + x) :
|
||||
Double.doubleToRawLongBits
|
||||
(fn.applyAsDouble
|
||||
(Double.longBitsToDouble(v), x)))))
|
||||
break;
|
||||
else if (n >= NCPU || cells != as)
|
||||
collide = false; // At max size or stale
|
||||
else if (!collide)
|
||||
collide = true;
|
||||
else if (cellsBusy == 0 && casCellsBusy()) {
|
||||
try {
|
||||
if (cells == as) { // Expand table unless stale
|
||||
Striped64.Cell[] rs = new Striped64.Cell[n << 1];
|
||||
for (int i = 0; i < n; ++i)
|
||||
rs[i] = as[i];
|
||||
cells = rs;
|
||||
}
|
||||
} finally {
|
||||
cellsBusy = 0;
|
||||
}
|
||||
collide = false;
|
||||
continue; // Retry with expanded table
|
||||
}
|
||||
h = advanceProbe(h);
|
||||
}
|
||||
else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
|
||||
boolean init = false;
|
||||
try { // Initialize table
|
||||
if (cells == as) {
|
||||
Striped64.Cell[] rs = new Striped64.Cell[2];
|
||||
rs[h & 1] = new Striped64.Cell(Double.doubleToRawLongBits(x));
|
||||
cells = rs;
|
||||
init = true;
|
||||
}
|
||||
} finally {
|
||||
cellsBusy = 0;
|
||||
}
|
||||
if (init)
|
||||
break;
|
||||
}
|
||||
else if (casBase(v = base,
|
||||
((fn == null) ?
|
||||
Double.doubleToRawLongBits
|
||||
(Double.longBitsToDouble(v) + x) :
|
||||
Double.doubleToRawLongBits
|
||||
(fn.applyAsDouble
|
||||
(Double.longBitsToDouble(v), x)))))
|
||||
break; // Fall back on using base
|
||||
}
|
||||
}
|
||||
|
||||
// Unsafe mechanics
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
private static final long BASE;
|
||||
private static final long CELLSBUSY;
|
||||
private static final long PROBE;
|
||||
static {
|
||||
try {
|
||||
UNSAFE = getUnsafe();
|
||||
Class<?> sk = Striped64.class;
|
||||
BASE = UNSAFE.objectFieldOffset
|
||||
(sk.getDeclaredField("base"));
|
||||
CELLSBUSY = UNSAFE.objectFieldOffset
|
||||
(sk.getDeclaredField("cellsBusy"));
|
||||
Class<?> tk = Thread.class;
|
||||
PROBE = UNSAFE.objectFieldOffset
|
||||
(tk.getDeclaredField("threadLocalRandomProbe"));
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Unsafe getUnsafe() {
|
||||
try {
|
||||
Field field = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
field.setAccessible(true);
|
||||
|
||||
return (Unsafe) field.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,4 +15,5 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m
|
|||
- [A Guide to the Reflections Library](https://www.baeldung.com/reflections-library)
|
||||
- [Exactly Once Processing in Kafka](https://www.baeldung.com/kafka-exactly-once)
|
||||
- [Introduction to Protonpack](https://www.baeldung.com/java-protonpack)
|
||||
- [Java-R Integration](https://www.baeldung.com/java-r-integration)
|
||||
- More articles [[<-- prev]](/libraries-5)
|
||||
|
|
|
@ -92,8 +92,50 @@
|
|||
<version>${commonsio.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.rosuda.REngine</groupId>
|
||||
<artifactId>Rserve</artifactId>
|
||||
<version>${rserve.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.jbytecode</groupId>
|
||||
<artifactId>RCaller</artifactId>
|
||||
<version>${rcaller.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.renjin</groupId>
|
||||
<artifactId>renjin-script-engine</artifactId>
|
||||
<version>${renjin.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<!-- Needed for Renjin -->
|
||||
<repository>
|
||||
<id>bedatadriven</id>
|
||||
<name>bedatadriven public repo</name>
|
||||
<url>https://nexus.bedatadriven.com/content/groups/public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- Excludes FastR classes from compilations since they require GraalVM -->
|
||||
<excludes>
|
||||
<exclude>com/baeldung/r/FastRMean.java</exclude>
|
||||
</excludes>
|
||||
<testExcludes>
|
||||
<exclude>com/baeldung/r/FastRMeanUnitTest.java</exclude>
|
||||
</testExcludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<kafka.version>2.0.0</kafka.version>
|
||||
<javapoet.version>1.10.0</javapoet.version>
|
||||
|
@ -105,6 +147,9 @@
|
|||
<commons-net.version>3.6</commons-net.version>
|
||||
<assertj.version>3.6.2</assertj.version>
|
||||
<commonsio.version>2.6</commonsio.version>
|
||||
<renjin.version>RELEASE</renjin.version>
|
||||
<rcaller.version>3.0</rcaller.version>
|
||||
<rserve.version>1.8.1</rserve.version>
|
||||
</properties>
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package com.baeldung.r;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* FastR showcase.
|
||||
*
|
|
@ -1,12 +1,12 @@
|
|||
package com.baeldung.r;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import com.github.rcaller.rstuff.RCaller;
|
||||
import com.github.rcaller.rstuff.RCallerOptions;
|
||||
import com.github.rcaller.rstuff.RCode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* RCaller showcase.
|
||||
*
|
|
@ -1,13 +1,12 @@
|
|||
package com.baeldung.r;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.renjin.script.RenjinScriptEngine;
|
||||
import org.renjin.sexp.DoubleArrayVector;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* Renjin showcase.
|
||||
*
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue