Merge branch 'master' of https://github.com/eugenp/tutorials into task/BAEL-20665
# Conflicts: # core-groovy-2/src/test/groovy/com/baeldung/metaprogramming/MetaprogrammingUnitTest.groovy # core-java-modules/pom.xml # pom.xml
This commit is contained in:
52
core-java-modules/core-java-14/pom.xml
Normal file
52
core-java-modules/core-java-14/pom.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?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>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>core-java-14</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>core-java-14</name>
|
||||
<packaging>jar</packaging>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source.version}</source>
|
||||
<target>${maven.compiler.target.version}</target>
|
||||
<compilerArgs>
|
||||
<compilerArg>
|
||||
--enable-preview
|
||||
</compilerArg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M3</version>
|
||||
<configuration>
|
||||
<argLine>--enable-preview</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source.version>14</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>14</maven.compiler.target.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.baeldung.serial;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Class showcasing the usage of the Java 14 @Serial annotation.
|
||||
*
|
||||
* @author Donato Rimenti
|
||||
*/
|
||||
public class MySerialClass implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final ObjectStreamField[] serialPersistentFields = null;
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
@Serial
|
||||
private void writeObject(ObjectOutputStream stream) throws IOException {
|
||||
// ...
|
||||
}
|
||||
|
||||
@Serial
|
||||
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
|
||||
// ...
|
||||
}
|
||||
|
||||
@Serial
|
||||
private void readObjectNoData() throws ObjectStreamException {
|
||||
// ...
|
||||
}
|
||||
|
||||
@Serial
|
||||
private Object writeReplace() throws ObjectStreamException {
|
||||
// ...
|
||||
return null;
|
||||
}
|
||||
|
||||
@Serial
|
||||
private Object readResolve() throws ObjectStreamException {
|
||||
// ...
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,16 @@
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>${jmh.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>${jmh.version}</version>
|
||||
</dependency>
|
||||
<!-- test scoped -->
|
||||
<dependency>
|
||||
@@ -37,9 +47,34 @@
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<finalName>benchmarks</finalName>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.openjdk.jmh.Main</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jmh.version>1.19</jmh.version>
|
||||
<!-- util -->
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
<!-- testing -->
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.baeldung.arraysort;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Warmup(iterations = 5)
|
||||
@Measurement(iterations = 10)
|
||||
@Fork(2)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
public class ArraySortingBenchmark {
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class ArrayContainer {
|
||||
|
||||
@Param({ "1000", "10000", "100000", "1000000" })
|
||||
int arraySize;
|
||||
|
||||
// initial unsorted array
|
||||
int[] unsortedArray;
|
||||
|
||||
//cloned array to sort
|
||||
int[] arrayToSort;
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void createUnSortedArray() {
|
||||
unsortedArray = new int[arraySize];
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
unsortedArray[i] = new Random().nextInt(1000);
|
||||
}
|
||||
}
|
||||
|
||||
@Setup(Level.Invocation)
|
||||
public void createUnSortedArrayCopy() {
|
||||
arrayToSort = unsortedArray.clone();
|
||||
}
|
||||
|
||||
int[] getArrayToSort() {
|
||||
return arrayToSort;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchmark_arrays_parallel_sort(ArrayContainer d, Blackhole b) {
|
||||
int[] arr = d.getArrayToSort();
|
||||
Arrays.parallelSort(arr);
|
||||
b.consume(arr);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void benchmark_arrays_sort(ArrayContainer d, Blackhole b) {
|
||||
int[] arr = d.getArrayToSort();
|
||||
Arrays.sort(arr);
|
||||
b.consume(arr);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,11 +24,21 @@ public class DuplicatesCounter {
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
public static <T> Map<T, Long> countByClassicalLoopWithMapCompute(List<T> inputList) {
|
||||
public static <T> Map<T, Long> countByForEachLoopWithGetOrDefault(List<T> inputList) {
|
||||
Map<T, Long> resultMap = new HashMap<>();
|
||||
for (T element : inputList) {
|
||||
resultMap.compute(element, (k, v) -> v == null ? 1 : v + 1);
|
||||
}
|
||||
inputList.forEach(e -> resultMap.put(e, resultMap.getOrDefault(e, 0L) + 1L));
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
public static <T> Map<T, Long> countByForEachLoopWithMapCompute(List<T> inputList) {
|
||||
Map<T, Long> resultMap = new HashMap<>();
|
||||
inputList.forEach(e -> resultMap.compute(e, (k, v) -> v == null ? 1L : v + 1L));
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
public static <T> Map<T, Long> countByForEachLoopWithMapMerge(List<T> inputList) {
|
||||
Map<T, Long> resultMap = new HashMap<>();
|
||||
inputList.forEach(e -> resultMap.merge(e, 1L, Long::sum));
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import static org.assertj.core.data.MapEntry.entry;
|
||||
|
||||
class DuplicatesCounterUnitTest {
|
||||
|
||||
|
||||
private static List<String> INPUT_LIST = Lists.list(
|
||||
"expect1",
|
||||
"expect2", "expect2",
|
||||
@@ -24,10 +23,21 @@ class DuplicatesCounterUnitTest {
|
||||
verifyResult(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInput_whenCountByForEachLoopWithGetOrDefault_thenGetResultMap() {
|
||||
Map<String, Long> result = DuplicatesCounter.countByForEachLoopWithGetOrDefault(INPUT_LIST);
|
||||
verifyResult(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInput_whenCountByClassicalLoopWithMapCompute_thenGetResultMap() {
|
||||
Map<String, Long> result = DuplicatesCounter.countByClassicalLoopWithMapCompute(INPUT_LIST);
|
||||
void givenInput_whenCountByForEachLoopWithMapCompute_thenGetResultMap() {
|
||||
Map<String, Long> result = DuplicatesCounter.countByForEachLoopWithMapCompute(INPUT_LIST);
|
||||
verifyResult(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInput_whenCountByForEachLoopWithMapMerge_thenGetResultMap() {
|
||||
Map<String, Long> result = DuplicatesCounter.countByForEachLoopWithMapMerge(INPUT_LIST);
|
||||
verifyResult(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,37 @@
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jcabi</groupId>
|
||||
<artifactId>jcabi-aspects</artifactId>
|
||||
<version>${jcabi-aspects.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectjrt.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.cactoos</groupId>
|
||||
<artifactId>cactoos</artifactId>
|
||||
<version>${cactoos.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.ea.async</groupId>
|
||||
<artifactId>ea-async</artifactId>
|
||||
<version>${ea-async.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -36,6 +67,30 @@
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.jcabi</groupId>
|
||||
<artifactId>jcabi-maven-plugin</artifactId>
|
||||
<version>${jcabi-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>ajc</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>${aspectjtools.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>${aspectjweaver.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
@@ -49,6 +104,14 @@
|
||||
<assertj.version>3.14.0</assertj.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<jcabi-aspects.version>0.22.6</jcabi-aspects.version>
|
||||
<aspectjrt.version>1.9.5</aspectjrt.version>
|
||||
<guava.version>28.2-jre</guava.version>
|
||||
<cactoos.version>0.43</cactoos.version>
|
||||
<ea-async.version>1.2.3</ea-async.version>
|
||||
<jcabi-maven-plugin.version>0.14.1</jcabi-maven-plugin.version>
|
||||
<aspectjtools.version>1.9.1</aspectjtools.version>
|
||||
<aspectjweaver.version>1.9.1</aspectjweaver.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.baeldung.async;
|
||||
|
||||
import static com.ea.async.Async.await;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import com.ea.async.Async;
|
||||
|
||||
public class EAAsyncExample {
|
||||
|
||||
static {
|
||||
Async.init();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
usingCompletableFuture();
|
||||
usingAsyncAwait();
|
||||
}
|
||||
|
||||
public static void usingCompletableFuture() throws InterruptedException, ExecutionException, Exception {
|
||||
CompletableFuture<Void> completableFuture = hello()
|
||||
.thenComposeAsync(hello -> mergeWorld(hello))
|
||||
.thenAcceptAsync(helloWorld -> print(helloWorld))
|
||||
.exceptionally( throwable -> {
|
||||
System.out.println(throwable.getCause());
|
||||
return null;
|
||||
});
|
||||
completableFuture.get();
|
||||
}
|
||||
|
||||
public static CompletableFuture<String> hello() {
|
||||
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
public static CompletableFuture<String> mergeWorld(String s) {
|
||||
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
|
||||
return s + " World!";
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
public static void print(String str) {
|
||||
CompletableFuture.runAsync(() -> System.out.println(str));
|
||||
}
|
||||
|
||||
private static void usingAsyncAwait() {
|
||||
try {
|
||||
String hello = await(hello());
|
||||
String helloWorld = await(mergeWorld(hello));
|
||||
await(CompletableFuture.runAsync(() -> print(helloWorld)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.baeldung.async;
|
||||
|
||||
import static com.ea.async.Async.await;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.google.common.util.concurrent.AsyncCallable;
|
||||
import com.google.common.util.concurrent.Callables;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.jcabi.aspects.Async;
|
||||
import com.jcabi.aspects.Loggable;
|
||||
|
||||
public class JavaAsync {
|
||||
|
||||
static {
|
||||
com.ea.async.Async.init();
|
||||
}
|
||||
|
||||
private static final ExecutorService threadpool = Executors.newCachedThreadPool();
|
||||
|
||||
public static void main (String[] args) throws InterruptedException, ExecutionException {
|
||||
int number = 20;
|
||||
|
||||
//Thread Example
|
||||
factorialUsingThread(number).start();
|
||||
|
||||
//FutureTask Example
|
||||
Future<Long> futureTask = factorialUsingFutureTask(number);
|
||||
System.out.println("Factorial of " + number + " is: " + futureTask.get());
|
||||
|
||||
// CompletableFuture Example
|
||||
Future<Long> completableFuture = factorialUsingCompletableFuture(number);
|
||||
System.out.println("Factorial of " + number + " is: " + completableFuture.get());
|
||||
|
||||
// EA Async example
|
||||
System.out.println("Factorial of " + number + " is: " + factorialUsingEAAsync(number));
|
||||
|
||||
// cactoos async example
|
||||
Future<Long> asyncFuture = factorialUsingCactoos(number);
|
||||
System.out.println("Factorial of " + number + " is: " + asyncFuture.get());
|
||||
|
||||
// Guava example
|
||||
ListenableFuture<Long> guavaFuture = factorialUsingGuavaServiceSubmit(number);
|
||||
System.out.println("Factorial of " + number + " is: " + guavaFuture.get());
|
||||
|
||||
ListenableFuture<Long> guavaFutures = factorialUsingGuavaFutures(number);
|
||||
System.out.println("Factorial of " + number + " is: " + guavaFutures.get());
|
||||
|
||||
// @async jcabi-aspect example
|
||||
Future<Long> aspectFuture = factorialUsingJcabiAspect(number);
|
||||
System.out.println("Factorial of " + number + " is: " + aspectFuture.get());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
public static long factorial(int number) {
|
||||
long result = 1;
|
||||
for(int i=number;i>0;i--) {
|
||||
result *= i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number using Thread
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
@Loggable
|
||||
public static Thread factorialUsingThread(int number) {
|
||||
Thread newThread = new Thread(() -> {
|
||||
System.out.println("Factorial of " + number + " is: " + factorial(number));
|
||||
});
|
||||
|
||||
return newThread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number using FutureTask
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
@Loggable
|
||||
public static Future<Long> factorialUsingFutureTask(int number) {
|
||||
Future<Long> futureTask = threadpool.submit(() -> factorial(number));
|
||||
|
||||
while (!futureTask.isDone()) {
|
||||
System.out.println("FutureTask is not finished yet...");
|
||||
}
|
||||
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number using CompletableFuture
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
@Loggable
|
||||
public static Future<Long> factorialUsingCompletableFuture(int number) {
|
||||
CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> factorial(number));
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number using EA Async
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
@Loggable
|
||||
public static long factorialUsingEAAsync(int number) {
|
||||
CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> factorial(number));
|
||||
long result = await(completableFuture);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number using Async of Cactoos
|
||||
* @param number
|
||||
* @return
|
||||
* @throws InterruptedException
|
||||
* @throws ExecutionException
|
||||
*/
|
||||
@Loggable
|
||||
public static Future<Long> factorialUsingCactoos(int number) throws InterruptedException, ExecutionException {
|
||||
org.cactoos.func.Async<Integer, Long> asyncFunction = new org.cactoos.func.Async<Integer, Long>(input -> factorial(input));
|
||||
Future<Long> asyncFuture = asyncFunction.apply(number);
|
||||
return asyncFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number using Guava's ListeningExecutorService.submit()
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
@Loggable
|
||||
public static ListenableFuture<Long> factorialUsingGuavaServiceSubmit(int number) {
|
||||
ListeningExecutorService service = MoreExecutors.listeningDecorator(threadpool);
|
||||
ListenableFuture<Long> factorialFuture = (ListenableFuture<Long>) service.submit(()-> factorial(number));
|
||||
return factorialFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number using Guava's Futures.submitAsync()
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
@Loggable
|
||||
public static ListenableFuture<Long> factorialUsingGuavaFutures(int number) {
|
||||
ListeningExecutorService service = MoreExecutors.listeningDecorator(threadpool);
|
||||
AsyncCallable<Long> asyncCallable = Callables.asAsyncCallable(new Callable<Long>() {
|
||||
public Long call() {
|
||||
return factorial(number);
|
||||
}
|
||||
}, service);
|
||||
return Futures.submitAsync(asyncCallable, service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds factorial of a number using @Async of jcabi-aspects
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
@Async
|
||||
@Loggable
|
||||
public static Future<Long> factorialUsingJcabiAspect(int number) {
|
||||
Future<Long> factorialFuture = CompletableFuture.supplyAsync(() -> factorial(number));
|
||||
return factorialFuture;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
## Java Date/time computations Cookbooks and Examples
|
||||
|
||||
This module contains articles about date and time computations in Java.
|
||||
## Core Date Operations (Part 1)
|
||||
This module contains articles about date operations in Java.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Difference Between Two Dates in Java](http://www.baeldung.com/java-date-difference)
|
||||
@@ -13,3 +12,4 @@ This module contains articles about date and time computations in Java.
|
||||
- [Increment Date in Java](http://www.baeldung.com/java-increment-date)
|
||||
- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date)
|
||||
- [Introduction to Joda-Time](http://www.baeldung.com/joda-time)
|
||||
- [[Next -->]](/core-java-modules/core-java-date-operations-2)
|
||||
@@ -2,9 +2,9 @@
|
||||
<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-datetime-computations</artifactId>
|
||||
<artifactId>core-java-date-operations-1</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<name>core-java-datetime-computations</name>
|
||||
<name>core-java-date-operations-1</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
@@ -41,7 +41,7 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-datetime-computations</finalName>
|
||||
<finalName>core-java-date-operations-1</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
@@ -1,4 +1,4 @@
|
||||
## Core Date Operations
|
||||
## Core Date Operations (Part 2)
|
||||
This module contains articles about date operations in Java.
|
||||
|
||||
### Relevant Articles:
|
||||
@@ -6,3 +6,4 @@ This module contains articles about date operations in Java.
|
||||
- [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)
|
||||
- [Converting Java Date to OffsetDateTime](https://www.baeldung.com/java-convert-date-to-offsetdatetime)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)
|
||||
@@ -3,9 +3,9 @@
|
||||
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-date-operations</artifactId>
|
||||
<artifactId>core-java-date-operations-2</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<name>core-java-date-operations</name>
|
||||
<name>core-java-date-operations-2</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
@@ -31,11 +31,18 @@
|
||||
<artifactId>hirondelle-date4j</artifactId>
|
||||
<version>${hirondelle-date4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<joda-time.version>2.10</joda-time.version>
|
||||
<hirondelle-date4j.version>1.5.1</hirondelle-date4j.version>
|
||||
<assertj.version>3.14.0</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -1,55 +1,65 @@
|
||||
package com.baeldung.date.comparison;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import hirondelle.date4j.DateTime;
|
||||
|
||||
public class DateComparisonUtils {
|
||||
|
||||
public static boolean isSameDayUsingLocalDate(Date date1, Date date2) {
|
||||
LocalDate localDate1 = date1.toInstant()
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalDate();
|
||||
LocalDate localDate2 = date2.toInstant()
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalDate();
|
||||
return localDate1.isEqual(localDate2);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingSimpleDateFormat(Date date1, Date date2) {
|
||||
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
|
||||
return fmt.format(date1)
|
||||
.equals(fmt.format(date2));
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingCalendar(Date date1, Date date2) {
|
||||
Calendar calendar1 = Calendar.getInstance();
|
||||
calendar1.setTime(date1);
|
||||
Calendar calendar2 = Calendar.getInstance();
|
||||
calendar2.setTime(date2);
|
||||
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR) && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH) && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingApacheCommons(Date date1, Date date2) {
|
||||
return DateUtils.isSameDay(date1, date2);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingJoda(Date date1, Date date2) {
|
||||
org.joda.time.LocalDate localDate1 = new org.joda.time.LocalDate(date1);
|
||||
org.joda.time.LocalDate localDate2 = new org.joda.time.LocalDate(date2);
|
||||
return localDate1.equals(localDate2);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingDate4j(Date date1, Date date2) {
|
||||
DateTime dateObject1 = DateTime.forInstant(date1.getTime(), TimeZone.getDefault());
|
||||
DateTime dateObject2 = DateTime.forInstant(date2.getTime(), TimeZone.getDefault());
|
||||
return dateObject1.isSameDayAs(dateObject2);
|
||||
}
|
||||
}
|
||||
package com.baeldung.date.comparison;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import hirondelle.date4j.DateTime;
|
||||
|
||||
public class DateComparisonUtils {
|
||||
|
||||
public static boolean isSameDayUsingLocalDate(Date date1, Date date2) {
|
||||
LocalDate localDate1 = date1.toInstant()
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalDate();
|
||||
LocalDate localDate2 = date2.toInstant()
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalDate();
|
||||
return localDate1.isEqual(localDate2);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingInstant(Date date1, Date date2) {
|
||||
Instant instant1 = date1.toInstant()
|
||||
.truncatedTo(ChronoUnit.DAYS);
|
||||
Instant instant2 = date2.toInstant()
|
||||
.truncatedTo(ChronoUnit.DAYS);
|
||||
return instant1.equals(instant2);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingSimpleDateFormat(Date date1, Date date2) {
|
||||
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
|
||||
return fmt.format(date1)
|
||||
.equals(fmt.format(date2));
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingCalendar(Date date1, Date date2) {
|
||||
Calendar calendar1 = Calendar.getInstance();
|
||||
calendar1.setTime(date1);
|
||||
Calendar calendar2 = Calendar.getInstance();
|
||||
calendar2.setTime(date2);
|
||||
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR) && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH) && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingApacheCommons(Date date1, Date date2) {
|
||||
return DateUtils.isSameDay(date1, date2);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingJoda(Date date1, Date date2) {
|
||||
org.joda.time.LocalDate localDate1 = new org.joda.time.LocalDate(date1);
|
||||
org.joda.time.LocalDate localDate2 = new org.joda.time.LocalDate(date2);
|
||||
return localDate1.equals(localDate2);
|
||||
}
|
||||
|
||||
public static boolean isSameDayUsingDate4j(Date date1, Date date2) {
|
||||
DateTime dateObject1 = DateTime.forInstant(date1.getTime(), TimeZone.getDefault());
|
||||
DateTime dateObject2 = DateTime.forInstant(date2.getTime(), TimeZone.getDefault());
|
||||
return dateObject1.isSameDayAs(dateObject2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.timer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class DatabaseMigrationTask extends TimerTask {
|
||||
private List<String> oldDatabase;
|
||||
private List<String> newDatabase;
|
||||
|
||||
public DatabaseMigrationTask(List<String> oldDatabase, List<String> newDatabase) {
|
||||
this.oldDatabase = oldDatabase;
|
||||
this.newDatabase = newDatabase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
newDatabase.addAll(oldDatabase);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.timer;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class NewsletterTask extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Email sent at: "
|
||||
+ LocalDateTime.ofInstant(Instant.ofEpochMilli(scheduledExecutionTime()), ZoneId.systemDefault()));
|
||||
}
|
||||
}
|
||||
@@ -1,53 +1,57 @@
|
||||
package com.baeldung.date.comparison;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class DateComparisonUtilsUnitTest {
|
||||
|
||||
private Date day1Morning = toDate(LocalDateTime.of(2019, 10, 19, 6, 30, 40));
|
||||
private Date day1Evening = toDate(LocalDateTime.of(2019, 10, 19, 18, 30, 50));
|
||||
private Date day2Morning = toDate(LocalDateTime.of(2019, 10, 20, 6, 30, 50));
|
||||
|
||||
private Date toDate(LocalDateTime localDateTime) {
|
||||
return Date.from(localDateTime.atZone(ZoneId.systemDefault())
|
||||
.toInstant());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDatesWithDifferentTime_whenIsSameDay_thenReturnsTrue() {
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingLocalDate(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingSimpleDateFormat(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingCalendar(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingApacheCommons(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingJoda(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingDate4j(day1Morning, day1Evening));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDates_whenIsDifferentDay_thenReturnsFalse() {
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingLocalDate(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingLocalDate(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingSimpleDateFormat(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingSimpleDateFormat(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingCalendar(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingCalendar(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingApacheCommons(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingApacheCommons(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingJoda(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingJoda(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingDate4j(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingDate4j(day1Evening, day2Morning));
|
||||
}
|
||||
}
|
||||
package com.baeldung.date.comparison;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class DateComparisonUtilsUnitTest {
|
||||
|
||||
private Date day1Morning = toDate(LocalDateTime.of(2019, 10, 19, 6, 30, 40));
|
||||
private Date day1Evening = toDate(LocalDateTime.of(2019, 10, 19, 18, 30, 50));
|
||||
private Date day2Morning = toDate(LocalDateTime.of(2019, 10, 20, 6, 30, 50));
|
||||
|
||||
private Date toDate(LocalDateTime localDateTime) {
|
||||
return Date.from(localDateTime.atZone(ZoneId.systemDefault())
|
||||
.toInstant());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDatesWithDifferentTime_whenIsSameDay_thenReturnsTrue() {
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingLocalDate(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingInstant(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingSimpleDateFormat(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingCalendar(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingApacheCommons(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingJoda(day1Morning, day1Evening));
|
||||
assertTrue(DateComparisonUtils.isSameDayUsingDate4j(day1Morning, day1Evening));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDates_whenIsDifferentDay_thenReturnsFalse() {
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingLocalDate(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingLocalDate(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingInstant(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingInstant(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingSimpleDateFormat(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingSimpleDateFormat(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingCalendar(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingCalendar(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingApacheCommons(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingApacheCommons(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingJoda(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingJoda(day1Evening, day2Morning));
|
||||
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingDate4j(day1Morning, day2Morning));
|
||||
assertFalse(DateComparisonUtils.isSameDayUsingDate4j(day1Evening, day2Morning));
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,6 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class DateUtilsUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenTimeMillis_thenDateIsReturned() {
|
||||
Date now = DateUtils.getNow();
|
||||
assertEquals(DateUtils.getDate(now.getTime()), now);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateAndPattern_thenDateIsCorrectlyReturned() throws ParseException {
|
||||
long milliseconds = new Date(2020 - 1900, 0, 1).getTime();
|
||||
@@ -9,11 +9,6 @@ import org.junit.Test;
|
||||
|
||||
public class DateUtilsUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenCurrentDate_thenTodayIsReturned() {
|
||||
assertEquals(DateUtils.getNow().toLocalDate(), LocalDate.now());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void givenDateAsString_whenPatternIsNotRespected_thenExceptionIsThrown() {
|
||||
DateUtils.getDate("2020 01 01");
|
||||
@@ -1,22 +1,13 @@
|
||||
package com.baeldung.datetime.sql;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.datetime.sql.TimestampUtils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TimestampUtilsUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenCurrentTimestamp_thenNowIsReturned() {
|
||||
assertEquals(TimestampUtils.getNow()
|
||||
.getTime(), new Date().getTime());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void givenTimestampAsString_whenPatternIsNotRespected_thenExceptionIsThrown() {
|
||||
TimestampUtils.getTimestamp("2020/01/01 10:11-12");
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.timer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class DatabaseMigrationTaskUnitTest {
|
||||
@Test
|
||||
void givenDatabaseMigrationTask_whenTimerScheduledForNowPlusTwoSeconds_thenDataMigratedAfterTwoSeconds() throws Exception {
|
||||
List<String> oldDatabase = Arrays.asList("Harrison Ford", "Carrie Fisher", "Mark Hamill");
|
||||
List<String> newDatabase = new ArrayList<>();
|
||||
|
||||
LocalDateTime twoSecondsLater = LocalDateTime.now().plusSeconds(2);
|
||||
Date twoSecondsLaterAsDate = Date.from(twoSecondsLater.atZone(ZoneId.systemDefault()).toInstant());
|
||||
|
||||
new Timer().schedule(new DatabaseMigrationTask(oldDatabase, newDatabase), twoSecondsLaterAsDate);
|
||||
|
||||
while (LocalDateTime.now().isBefore(twoSecondsLater)) {
|
||||
assertThat(newDatabase).isEmpty();
|
||||
Thread.sleep(500);
|
||||
}
|
||||
assertThat(newDatabase).containsExactlyElementsOf(oldDatabase);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenDatabaseMigrationTask_whenTimerScheduledInTwoSeconds_thenDataMigratedAfterTwoSeconds() throws Exception {
|
||||
List<String> oldDatabase = Arrays.asList("Harrison Ford", "Carrie Fisher", "Mark Hamill");
|
||||
List<String> newDatabase = new ArrayList<>();
|
||||
|
||||
new Timer().schedule(new DatabaseMigrationTask(oldDatabase, newDatabase), 2000);
|
||||
|
||||
LocalDateTime twoSecondsLater = LocalDateTime.now().plusSeconds(2);
|
||||
|
||||
while (LocalDateTime.now().isBefore(twoSecondsLater)) {
|
||||
assertThat(newDatabase).isEmpty();
|
||||
Thread.sleep(500);
|
||||
}
|
||||
assertThat(newDatabase).containsExactlyElementsOf(oldDatabase);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.timer;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Timer;
|
||||
|
||||
class NewsletterTaskUnitTest {
|
||||
private final Timer timer = new Timer();
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
timer.cancel();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNewsletterTask_whenTimerScheduledEachSecondFixedDelay_thenNewsletterSentEachSecond() throws Exception {
|
||||
timer.schedule(new NewsletterTask(), 0, 1000);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNewsletterTask_whenTimerScheduledEachSecondFixedRate_thenNewsletterSentEachSecond() throws Exception {
|
||||
timer.scheduleAtFixedRate(new NewsletterTask(), 0, 1000);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.baeldung.datebasics;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class CreateDate {
|
||||
public LocalDate getTodaysDate() {
|
||||
return LocalDate.now();
|
||||
}
|
||||
|
||||
public LocalDate getTodaysDateFromClock() {
|
||||
return LocalDate.now(Clock.systemDefaultZone());
|
||||
}
|
||||
|
||||
public LocalDate getTodaysDateFromZone(String zone) {
|
||||
return LocalDate.now(ZoneId.of(zone));
|
||||
}
|
||||
|
||||
public LocalDate getCustomDateOne(int year, int month, int dayOfMonth) {
|
||||
return LocalDate.of(year, month, dayOfMonth);
|
||||
}
|
||||
|
||||
public LocalDate getCustomDateTwo(int year, Month month, int dayOfMonth) {
|
||||
return LocalDate.of(year, month, dayOfMonth);
|
||||
}
|
||||
|
||||
public LocalDate getDateFromEpochDay(long epochDay) {
|
||||
return LocalDate.ofEpochDay(epochDay);
|
||||
}
|
||||
|
||||
public LocalDate getDateFromYearAndDayOfYear(int year, int dayOfYear) {
|
||||
return LocalDate.ofYearDay(year, dayOfYear);
|
||||
}
|
||||
|
||||
public LocalDate getDateFromString(String date) {
|
||||
return LocalDate.parse(date);
|
||||
}
|
||||
|
||||
public LocalDate getDateFromStringAndFormatter(String date, String pattern) {
|
||||
return LocalDate.parse(date, DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.baeldung.datebasics;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.time.Month;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class CreateDateUnitTest {
|
||||
private CreateDate date = new CreateDate();
|
||||
|
||||
@Test
|
||||
public void whenUsingNowMethod_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getTodaysDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingClock_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getTodaysDateFromClock());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingZone_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getTodaysDateFromZone("Asia/Kolkata"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingOfMethod_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getCustomDateOne(2020, 1, 8));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValuesWithMonthEnum_whenUsingOfMethod_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getCustomDateTwo(2020, Month.JANUARY, 8));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingEpochDay_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getDateFromEpochDay(18269));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingYearDay_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getDateFromYearAndDayOfYear(2020, 8));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValues_whenUsingParse_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getDateFromString("2020-01-08"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValuesWithFormatter_whenUsingParse_thenLocalDate() {
|
||||
assertEquals("2020-01-08", date.getDateFromStringAndFormatter("8-Jan-2020", "d-MMM-yyyy"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.finallykeyword;
|
||||
|
||||
public class FinallyExample {
|
||||
|
||||
public void printCount(String count) {
|
||||
try {
|
||||
System.out.println("The count is " + Integer.parseInt(count));
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println("No count");
|
||||
} finally {
|
||||
System.out.println("In finally");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.baeldung.finallykeyword;
|
||||
|
||||
public class FinallyExecutedCases {
|
||||
|
||||
public void noExceptionFinally() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
}
|
||||
}
|
||||
|
||||
public void unhandledException() throws Exception {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
throw new Exception();
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
}
|
||||
}
|
||||
|
||||
public void handledException() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
throw new Exception();
|
||||
} catch (Exception e) {
|
||||
System.out.println("Inside catch");
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
}
|
||||
}
|
||||
|
||||
public String returnFromTry() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
return "from try";
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
}
|
||||
}
|
||||
|
||||
public String returnFromCatch() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
throw new Exception();
|
||||
} catch (Exception e) {
|
||||
System.out.println("Inside catch");
|
||||
return "from catch";
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.baeldung.finallykeyword;
|
||||
|
||||
public class FinallyNotExecutedCases {
|
||||
|
||||
public void callingSystemExit() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
System.exit(1);
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
}
|
||||
}
|
||||
|
||||
public void callingRuntimeHalt() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
Runtime.getRuntime()
|
||||
.halt(1);
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
}
|
||||
}
|
||||
|
||||
public void infiniteLoop() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
while (true) {
|
||||
}
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
}
|
||||
}
|
||||
|
||||
public void daemonThread() throws InterruptedException {
|
||||
Runnable runnable = () -> {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
} finally {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
System.out.println("Inside finally");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread regular = new Thread(runnable);
|
||||
Thread daemon = new Thread(runnable);
|
||||
daemon.setDaemon(true);
|
||||
regular.start();
|
||||
Thread.sleep(300);
|
||||
daemon.start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.finallykeyword;
|
||||
|
||||
public class PitfallsWhenUsingFinally {
|
||||
|
||||
public String disregardsUnCaughtException() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
throw new RuntimeException();
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
return "from finally";
|
||||
}
|
||||
}
|
||||
|
||||
public String ignoringOtherReturns() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
return "from try";
|
||||
} finally {
|
||||
System.out.println("Inside finally");
|
||||
return "from finally";
|
||||
}
|
||||
}
|
||||
|
||||
public String throwsException() {
|
||||
try {
|
||||
System.out.println("Inside try");
|
||||
return "from try";
|
||||
} finally {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
public class Coordinates {
|
||||
|
||||
private double longitude;
|
||||
private double latitude;
|
||||
private String placeName;
|
||||
|
||||
public Coordinates() {}
|
||||
|
||||
public Coordinates(double longitude, double latitude, String placeName) {
|
||||
this.longitude = longitude;
|
||||
this.latitude = latitude;
|
||||
this.placeName = placeName;
|
||||
}
|
||||
|
||||
public double calculateDistance(Coordinates c) {
|
||||
|
||||
double s1 = Math.abs(this.longitude - c.longitude);
|
||||
double s2 = Math.abs(this.latitude - c.latitude);
|
||||
|
||||
return Math.hypot(s1, s2);
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
|
||||
public String getPlaceName() {
|
||||
return placeName;
|
||||
}
|
||||
|
||||
public void setPlaceName(String placeName) {
|
||||
this.placeName = placeName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
class MultipleReturnValuesUsingArrays {
|
||||
|
||||
|
||||
static double[] getCoordinatesDoubleArray() {
|
||||
|
||||
double[] coordinates = new double[2];
|
||||
|
||||
coordinates[0] = 10;
|
||||
coordinates[1] = 12.5;
|
||||
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
|
||||
static Number[] getCoordinatesNumberArray() {
|
||||
|
||||
Number[] coordinates = new Number[2];
|
||||
|
||||
coordinates[0] = 10; //Integer
|
||||
coordinates[1] = 12.5; //Double
|
||||
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
class MultipleReturnValuesUsingCollections {
|
||||
|
||||
static List<Number> getCoordinatesList() {
|
||||
|
||||
List<Number> coordinates = new ArrayList<>();
|
||||
|
||||
coordinates.add(10);
|
||||
coordinates.add(12.5);
|
||||
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
static Map<String, Number> getCoordinatesMap() {
|
||||
|
||||
Map<String, Number> coordinates = new HashMap<>();
|
||||
|
||||
coordinates.put("longitude", 10);
|
||||
coordinates.put("latitude", 12.5);
|
||||
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
class MultipleReturnValuesUsingContainer {
|
||||
|
||||
static Coordinates getCoordinates() {
|
||||
|
||||
double longitude = 10;
|
||||
double latitude = 12.5;
|
||||
String placeName = "home";
|
||||
|
||||
return new Coordinates(longitude, latitude, placeName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class MultipleReturnValuesUsingTuples {
|
||||
|
||||
static Tuple2<Coordinates, Double> getMostDistantPoint(List<Coordinates> coordinatesList,
|
||||
Coordinates target) {
|
||||
|
||||
return coordinatesList.stream()
|
||||
.map(coor -> new Tuple2<>(coor, coor.calculateDistance(target)))
|
||||
.max((d1, d2) -> Double.compare(d1.getSecond(), d2.getSecond()))
|
||||
.get();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
public class Tuple2 <K, V> {
|
||||
|
||||
private K first;
|
||||
private V second;
|
||||
|
||||
public Tuple2() {}
|
||||
|
||||
public Tuple2(K first, V second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public K getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public V getSecond() {
|
||||
return second;
|
||||
}
|
||||
|
||||
public void setFirst(K first) {
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
public void setSecond(V second) {
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.finallykeyword;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PitfallsWhenUsingFinallyUnitTest {
|
||||
|
||||
PitfallsWhenUsingFinally instance = new PitfallsWhenUsingFinally();
|
||||
|
||||
@Test
|
||||
public void testIgnoresException() {
|
||||
String result = instance.disregardsUnCaughtException();
|
||||
assertEquals("from finally", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoresOtherReturns() {
|
||||
String result = instance.ignoringOtherReturns();
|
||||
assertEquals("from finally", result);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testThrowsException() {
|
||||
instance.throwsException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MultipleReturnValuesUsingArraysUnitTest {
|
||||
|
||||
@Test
|
||||
void whenUsingArrayOfDoubles_thenMultipleDoubleFieldsAreReturned() {
|
||||
|
||||
double[] coordinates = MultipleReturnValuesUsingArrays.getCoordinatesDoubleArray();
|
||||
assertEquals(10, coordinates[0]);
|
||||
assertEquals(12.5, coordinates[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingArrayOfNumbers_thenMultipleNumberFieldsAreReturned() {
|
||||
|
||||
Number[] coordinates = MultipleReturnValuesUsingArrays.getCoordinatesNumberArray();
|
||||
assertEquals(10, coordinates[0]);
|
||||
assertEquals(12.5, coordinates[1]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MultipleReturnValuesUsingCollectionsUnitTest {
|
||||
|
||||
@Test
|
||||
void whenUsingList_thenMultipleFieldsAreReturned() {
|
||||
|
||||
List<Number> coordinates = MultipleReturnValuesUsingCollections.getCoordinatesList();
|
||||
assertEquals(Integer.valueOf(10), coordinates.get(0));
|
||||
assertEquals(Double.valueOf(12.5), coordinates.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingMap_thenMultipleFieldsAreReturned() {
|
||||
|
||||
Map<String, Number> coordinates = MultipleReturnValuesUsingCollections.getCoordinatesMap();
|
||||
assertEquals(Integer.valueOf(10), coordinates.get("longitude"));
|
||||
assertEquals(Double.valueOf(12.5), coordinates.get("latitude"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MultipleReturnValuesUsingContainerUnitTest {
|
||||
|
||||
@Test
|
||||
void whenUsingContainerClass_thenMultipleFieldsAreReturned() {
|
||||
|
||||
Coordinates coordinates = MultipleReturnValuesUsingContainer.getCoordinates();
|
||||
|
||||
assertEquals(10, coordinates.getLongitude());
|
||||
assertEquals(12.5, coordinates.getLatitude());
|
||||
assertEquals("home", coordinates.getPlaceName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.methodmultiplereturnvalues;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class MultipleReturnValuesUsingTuplesUnitTest {
|
||||
|
||||
@Test
|
||||
void whenUsingTuple_thenMultipleFieldsAreReturned() {
|
||||
|
||||
List<Coordinates> coordinatesList = new ArrayList<>();
|
||||
coordinatesList.add(new Coordinates(1, 1, "home"));
|
||||
coordinatesList.add(new Coordinates(2, 2, "school"));
|
||||
coordinatesList.add(new Coordinates(3, 3, "hotel"));
|
||||
|
||||
Coordinates target = new Coordinates(5, 5, "gym");
|
||||
|
||||
Tuple2<Coordinates, Double> mostDistantPoint = MultipleReturnValuesUsingTuples.getMostDistantPoint(coordinatesList, target);
|
||||
|
||||
assertEquals(1, mostDistantPoint.getFirst().getLongitude());
|
||||
assertEquals(1, mostDistantPoint.getFirst().getLatitude());
|
||||
assertEquals("home", mostDistantPoint.getFirst().getPlaceName());
|
||||
assertEquals(5.66, BigDecimal.valueOf(mostDistantPoint.getSecond()).setScale(2, RoundingMode.HALF_UP).doubleValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
package com.baeldung.powerset;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
public class PowerSetUtility<T> {
|
||||
|
||||
private Map<T, Integer> map = new HashMap<>();
|
||||
private List<T> reverseMap = new ArrayList<>();
|
||||
|
||||
//Lazy Load PowerSet class
|
||||
private static class PowerSet<E> extends AbstractSet<Set<E>> {
|
||||
private Map<E, Integer> map = new HashMap<>();
|
||||
private List<E> reverseMap = new ArrayList<>();
|
||||
private Set<E> set;
|
||||
|
||||
public PowerSet(Set<E> set) {
|
||||
this.set = set;
|
||||
initializeMap();
|
||||
}
|
||||
|
||||
abstract class ListIterator<K> implements Iterator<K> {
|
||||
|
||||
protected int position = 0;
|
||||
private int size;
|
||||
|
||||
public ListIterator(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return position < size;
|
||||
}
|
||||
}
|
||||
|
||||
static class Subset<E> extends AbstractSet<E> {
|
||||
private Map<E, Integer> map;
|
||||
private List<E> reverseMap;
|
||||
private int mask;
|
||||
|
||||
public Subset(Map<E, Integer> map, List<E> reverseMap, int mask) {
|
||||
this.map = map;
|
||||
this.reverseMap = reverseMap;
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new Iterator<E>() {
|
||||
int remainingSetBits = mask;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return remainingSetBits != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
int index = Integer.numberOfTrailingZeros(remainingSetBits);
|
||||
if (index == 32) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
remainingSetBits &= ~(1 << index);
|
||||
return reverseMap.get(index);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return Integer.bitCount(mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@Nullable Object o) {
|
||||
Integer index = map.get(o);
|
||||
return index != null && (mask & (1 << index)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Set<E>> iterator() {
|
||||
return new ListIterator<Set<E>>(this.size()) {
|
||||
@Override
|
||||
public Set<E> next() {
|
||||
return new Subset<>(map, reverseMap, position++);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return (1 << this.set.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(@Nullable Object obj) {
|
||||
if (obj instanceof Set) {
|
||||
Set<?> set = (Set<?>) obj;
|
||||
return reverseMap.containsAll(set);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof PowerSet) {
|
||||
PowerSet<?> that = (PowerSet<?>) obj;
|
||||
return set.equals(that.set);//Set equals check to have the same element regardless of the order of the items
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
|
||||
private void initializeMap() {
|
||||
int mapId = 0;
|
||||
for (E c : this.set) {
|
||||
map.put(c, mapId++);
|
||||
reverseMap.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Set<T>> lazyLoadPowerSet(Set<T> set) {
|
||||
return new PowerSet<>(set);
|
||||
}
|
||||
|
||||
public Set<Set<T>> recursivePowerSet(Set<T> set) {
|
||||
if (set.isEmpty()) {
|
||||
Set<Set<T>> ret = new HashSet<>();
|
||||
ret.add(set);
|
||||
return ret;
|
||||
}
|
||||
|
||||
T element = set.iterator().next();
|
||||
Set<T> subSetWithoutElement = getSubSetWithoutElement(set, element);
|
||||
Set<Set<T>> powerSetSubSetWithoutElement = recursivePowerSet(subSetWithoutElement);
|
||||
|
||||
Set<Set<T>> powerSetSubSetWithElement = addElementToAll(powerSetSubSetWithoutElement, element);
|
||||
|
||||
Set<Set<T>> powerSet = new HashSet<>();
|
||||
powerSet.addAll(powerSetSubSetWithoutElement);
|
||||
powerSet.addAll(powerSetSubSetWithElement);
|
||||
return powerSet;
|
||||
}
|
||||
|
||||
public Set<Set<T>> recursivePowerSetIndexRepresentation(Collection<T> set) {
|
||||
initializeMap(set);
|
||||
Set<Set<Integer>> powerSetIndices = recursivePowerSetIndexRepresentation(0, set.size());
|
||||
return unMapIndex(powerSetIndices);
|
||||
}
|
||||
|
||||
private List<List<Boolean>> iterativePowerSetByLoopOverNumbers(int n) {
|
||||
List<List<Boolean>> powerSet = new ArrayList<>();
|
||||
for (int i = 0; i < (1 << n); i++) {
|
||||
List<Boolean> subset = new ArrayList<>(n);
|
||||
for (int j = 0; j < n; j++)
|
||||
subset.add(((1 << j) & i) > 0);
|
||||
powerSet.add(subset);
|
||||
}
|
||||
return powerSet;
|
||||
}
|
||||
|
||||
private List<List<Boolean>> iterativePowerSetByLoopOverNumbersWithMinimalChange(int n) {
|
||||
List<List<Boolean>> powerSet = new ArrayList<>();
|
||||
for (int i = 0; i < (1 << n); i++) {
|
||||
List<Boolean> subset = new ArrayList<>(n);
|
||||
for (int j = 0; j < n; j++) {
|
||||
int grayEquivalent = i ^ (i >> 1);
|
||||
subset.add(((1 << j) & grayEquivalent) > 0);
|
||||
}
|
||||
powerSet.add(subset);
|
||||
}
|
||||
return powerSet;
|
||||
}
|
||||
|
||||
public Set<Set<T>> recursivePowerSetBinaryRepresentation(Collection<T> set) {
|
||||
initializeMap(set);
|
||||
Set<List<Boolean>> powerSetBoolean = recursivePowerSetBinaryRepresentation(0, set.size());
|
||||
return unMapBinary(powerSetBoolean);
|
||||
}
|
||||
|
||||
public List<List<T>> iterativePowerSetByLoopOverNumbers(Set<T> set) {
|
||||
initializeMap(set);
|
||||
List<List<Boolean>> sets = iterativePowerSetByLoopOverNumbers(set.size());
|
||||
return unMapListBinary(sets);
|
||||
}
|
||||
|
||||
public List<List<T>> iterativePowerSetByLoopOverNumbersMinimalChange(Set<T> set) {
|
||||
initializeMap(set);
|
||||
List<List<Boolean>> sets = iterativePowerSetByLoopOverNumbersWithMinimalChange(set.size());
|
||||
return unMapListBinary(sets);
|
||||
}
|
||||
|
||||
private Set<Set<Integer>> recursivePowerSetIndexRepresentation(int idx, int n) {
|
||||
if (idx == n) {
|
||||
Set<Set<Integer>> empty = new HashSet<>();
|
||||
empty.add(new HashSet<>());
|
||||
return empty;
|
||||
}
|
||||
Set<Set<Integer>> powerSetSubset = recursivePowerSetIndexRepresentation(idx + 1, n);
|
||||
Set<Set<Integer>> powerSet = new HashSet<>(powerSetSubset);
|
||||
for (Set<Integer> s : powerSetSubset) {
|
||||
HashSet<Integer> subSetIdxInclusive = new HashSet<>(s);
|
||||
subSetIdxInclusive.add(idx);
|
||||
powerSet.add(subSetIdxInclusive);
|
||||
}
|
||||
return powerSet;
|
||||
}
|
||||
|
||||
private Set<List<Boolean>> recursivePowerSetBinaryRepresentation(int idx, int n) {
|
||||
if (idx == n) {
|
||||
Set<List<Boolean>> powerSetOfEmptySet = new HashSet<>();
|
||||
powerSetOfEmptySet.add(Arrays.asList(new Boolean[n]));
|
||||
return powerSetOfEmptySet;
|
||||
}
|
||||
Set<List<Boolean>> powerSetSubset = recursivePowerSetBinaryRepresentation(idx + 1, n);
|
||||
Set<List<Boolean>> powerSet = new HashSet<>();
|
||||
for (List<Boolean> s : powerSetSubset) {
|
||||
List<Boolean> subSetIdxExclusive = new ArrayList<>(s);
|
||||
subSetIdxExclusive.set(idx, false);
|
||||
powerSet.add(subSetIdxExclusive);
|
||||
List<Boolean> subSetIdxInclusive = new ArrayList<>(s);
|
||||
subSetIdxInclusive.set(idx, true);
|
||||
powerSet.add(subSetIdxInclusive);
|
||||
}
|
||||
return powerSet;
|
||||
}
|
||||
|
||||
private void initializeMap(Collection<T> collection) {
|
||||
int mapId = 0;
|
||||
for (T c : collection) {
|
||||
map.put(c, mapId++);
|
||||
reverseMap.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Set<T>> unMapIndex(Set<Set<Integer>> sets) {
|
||||
Set<Set<T>> ret = new HashSet<>();
|
||||
for (Set<Integer> s : sets) {
|
||||
HashSet<T> subset = new HashSet<>();
|
||||
for (Integer i : s)
|
||||
subset.add(reverseMap.get(i));
|
||||
ret.add(subset);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Set<Set<T>> unMapBinary(Collection<List<Boolean>> sets) {
|
||||
Set<Set<T>> ret = new HashSet<>();
|
||||
for (List<Boolean> s : sets) {
|
||||
HashSet<T> subset = new HashSet<>();
|
||||
for (int i = 0; i < s.size(); i++)
|
||||
if (s.get(i))
|
||||
subset.add(reverseMap.get(i));
|
||||
ret.add(subset);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<List<T>> unMapListBinary(Collection<List<Boolean>> sets) {
|
||||
List<List<T>> ret = new ArrayList<>();
|
||||
for (List<Boolean> s : sets) {
|
||||
List<T> subset = new ArrayList<>();
|
||||
for (int i = 0; i < s.size(); i++)
|
||||
if (s.get(i))
|
||||
subset.add(reverseMap.get(i));
|
||||
ret.add(subset);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Set<Set<T>> addElementToAll(Set<Set<T>> powerSetSubSetWithoutElement, T element) {
|
||||
Set<Set<T>> powerSetSubSetWithElement = new HashSet<>();
|
||||
for (Set<T> subsetWithoutElement : powerSetSubSetWithoutElement) {
|
||||
Set<T> subsetWithElement = new HashSet<>(subsetWithoutElement);
|
||||
subsetWithElement.add(element);
|
||||
powerSetSubSetWithElement.add(subsetWithElement);
|
||||
}
|
||||
return powerSetSubSetWithElement;
|
||||
}
|
||||
|
||||
private Set<T> getSubSetWithoutElement(Set<T> set, T element) {
|
||||
Set<T> subsetWithoutElement = new HashSet<>();
|
||||
for (T s : set) {
|
||||
if (!s.equals(element))
|
||||
subsetWithoutElement.add(s);
|
||||
}
|
||||
return subsetWithoutElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
package com.baeldung.powerset;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hamcrest.collection.IsCollectionWithSize;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class PowerSetUtilityUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenSet_WhenGuavaLibraryGeneratePowerSet_ThenItContainsAllSubsets() {
|
||||
ImmutableSet<String> set = ImmutableSet.of("APPLE", "ORANGE", "MANGO");
|
||||
Set<Set<String>> powerSet = Sets.powerSet(set);
|
||||
Assertions.assertEquals((1 << set.size()), powerSet.size());
|
||||
MatcherAssert.assertThat(powerSet, Matchers.containsInAnyOrder(
|
||||
ImmutableSet.of(),
|
||||
ImmutableSet.of("APPLE"),
|
||||
ImmutableSet.of("ORANGE"),
|
||||
ImmutableSet.of("APPLE", "ORANGE"),
|
||||
ImmutableSet.of("MANGO"),
|
||||
ImmutableSet.of("APPLE", "MANGO"),
|
||||
ImmutableSet.of("ORANGE", "MANGO"),
|
||||
ImmutableSet.of("APPLE", "ORANGE", "MANGO")
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSet_WhenPowerSetIsLazyLoadGenerated_ThenItContainsAllSubsets() {
|
||||
Set<String> set = RandomSetOfStringGenerator.generateRandomSet();
|
||||
Set<Set<String>> powerSet = new PowerSetUtility<String>().lazyLoadPowerSet(set);
|
||||
|
||||
//To make sure that the size of power set is (2 power n)
|
||||
MatcherAssert.assertThat(powerSet, IsCollectionWithSize.hasSize((1 << set.size())));
|
||||
//To make sure that number of occurrence of each element is (2 power n-1)
|
||||
Map<String, Integer> counter = new HashMap<>();
|
||||
for (Set<String> subset : powerSet) {
|
||||
for (String name : subset) {
|
||||
int num = counter.getOrDefault(name, 0);
|
||||
counter.put(name, num + 1);
|
||||
}
|
||||
}
|
||||
counter.forEach((k, v) -> Assertions.assertEquals((1 << (set.size() - 1)), v.intValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSet_WhenPowerSetIsCalculated_ThenItContainsAllSubsets() {
|
||||
Set<String> set = RandomSetOfStringGenerator.generateRandomSet();
|
||||
|
||||
Set<Set<String>> powerSet = new PowerSetUtility<String>().recursivePowerSet(set);
|
||||
|
||||
//To make sure that the size of power set is (2 power n)
|
||||
MatcherAssert.assertThat(powerSet, IsCollectionWithSize.hasSize((1 << set.size())));
|
||||
//To make sure that number of occurrence of each element is (2 power n-1)
|
||||
Map<String, Integer> counter = new HashMap<>();
|
||||
for (Set<String> subset : powerSet) {
|
||||
for (String name : subset) {
|
||||
int num = counter.getOrDefault(name, 0);
|
||||
counter.put(name, num + 1);
|
||||
}
|
||||
}
|
||||
counter.forEach((k, v) -> Assertions.assertEquals((1 << (set.size() - 1)), v.intValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSet_WhenPowerSetIsCalculatedRecursiveByIndexRepresentation_ThenItContainsAllSubsets() {
|
||||
Set<String> set = RandomSetOfStringGenerator.generateRandomSet();
|
||||
|
||||
Set<Set<String>> powerSet = new PowerSetUtility<String>().recursivePowerSetIndexRepresentation(set);
|
||||
|
||||
//To make sure that the size of power set is (2 power n)
|
||||
MatcherAssert.assertThat(powerSet, IsCollectionWithSize.hasSize((1 << set.size())));
|
||||
//To make sure that number of occurrence of each element is (2 power n-1)
|
||||
Map<String, Integer> counter = new HashMap<>();
|
||||
for (Set<String> subset : powerSet) {
|
||||
for (String name : subset) {
|
||||
int num = counter.getOrDefault(name, 0);
|
||||
counter.put(name, num + 1);
|
||||
}
|
||||
}
|
||||
counter.forEach((k, v) -> Assertions.assertEquals((1 << (set.size() - 1)), v.intValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSet_WhenPowerSetIsCalculatedRecursiveByBinaryRepresentation_ThenItContainsAllSubsets() {
|
||||
Set<String> set = RandomSetOfStringGenerator.generateRandomSet();
|
||||
|
||||
Set<Set<String>> powerSet = new PowerSetUtility<String>().recursivePowerSetBinaryRepresentation(set);
|
||||
|
||||
//To make sure that the size of power set is (2 power n)
|
||||
MatcherAssert.assertThat(powerSet, IsCollectionWithSize.hasSize((1 << set.size())));
|
||||
//To make sure that number of occurrence of each element is (2 power n-1)
|
||||
Map<String, Integer> counter = new HashMap<>();
|
||||
for (Set<String> subset : powerSet) {
|
||||
for (String name : subset) {
|
||||
int num = counter.getOrDefault(name, 0);
|
||||
counter.put(name, num + 1);
|
||||
}
|
||||
}
|
||||
counter.forEach((k, v) -> Assertions.assertEquals((1 << (set.size() - 1)), v.intValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSet_WhenPowerSetIsCalculatedIterativePowerSetByLoopOverNumbers_ThenItContainsAllSubsets() {
|
||||
Set<String> set = RandomSetOfStringGenerator.generateRandomSet();
|
||||
|
||||
List<List<String>> powerSet = new PowerSetUtility<String>().iterativePowerSetByLoopOverNumbers(set);
|
||||
|
||||
//To make sure that the size of power set is (2 power n)
|
||||
MatcherAssert.assertThat(powerSet, IsCollectionWithSize.hasSize((1 << set.size())));
|
||||
//To make sure that number of occurrence of each element is (2 power n-1)
|
||||
Map<String, Integer> counter = new HashMap<>();
|
||||
for (List<String> subset : powerSet) {
|
||||
for (String name : subset) {
|
||||
int num = counter.getOrDefault(name, 0);
|
||||
counter.put(name, num + 1);
|
||||
}
|
||||
}
|
||||
counter.forEach((k, v) -> Assertions.assertEquals((1 << (set.size() - 1)), v.intValue()));
|
||||
//To make sure that one subset is not generated twice
|
||||
Assertions.assertEquals(powerSet.size(), new HashSet<>(powerSet).size());
|
||||
//To make sure that each element in each subset is occurred once
|
||||
for (List<String> subset : powerSet) {
|
||||
Assertions.assertEquals(subset.size(), new HashSet<>(subset).size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSet_WhenPowerSetIsCalculatedIterativePowerSetByLoopOverNumbersWithMinimalChange_ThenItContainsAllSubsets() {
|
||||
|
||||
Set<String> set = RandomSetOfStringGenerator.generateRandomSet();
|
||||
List<List<String>> powerSet = new PowerSetUtility<String>().iterativePowerSetByLoopOverNumbersMinimalChange(set);
|
||||
|
||||
//To make sure that the size of power set is (2 power n)
|
||||
MatcherAssert.assertThat(powerSet, IsCollectionWithSize.hasSize((1 << set.size())));
|
||||
//To make sure that number of occurrence of each element is (2 power n-1)
|
||||
Map<String, Integer> counter = new HashMap<>();
|
||||
for (List<String> subset : powerSet) {
|
||||
for (String name : subset) {
|
||||
int num = counter.getOrDefault(name, 0);
|
||||
counter.put(name, num + 1);
|
||||
}
|
||||
}
|
||||
counter.forEach((k, v) -> Assertions.assertEquals((1 << (set.size() - 1)), v.intValue()));
|
||||
//To make sure that one subset is not generated twice
|
||||
Assertions.assertEquals(powerSet.size(), new HashSet<>(powerSet).size());
|
||||
//To make sure that each element in each subset is occurred once
|
||||
for (List<String> subset : powerSet) {
|
||||
Assertions.assertEquals(subset.size(), new HashSet<>(subset).size());
|
||||
}
|
||||
//To make sure that difference of consecutive subsets is exactly 1
|
||||
for(int i=1; i<powerSet.size(); i++) {
|
||||
int diff = 0;
|
||||
for (String s : powerSet.get(i - 1))
|
||||
if (!powerSet.get(i).contains(s))
|
||||
diff++;
|
||||
for (String s : powerSet.get(i))
|
||||
if (!powerSet.get(i - 1).contains(s))
|
||||
diff++;
|
||||
Assertions.assertEquals(1, diff);
|
||||
}
|
||||
}
|
||||
|
||||
static class RandomSetOfStringGenerator {
|
||||
private static List<String> fruits = Arrays.asList("Apples", "Avocados", "Banana", "Blueberry", "Cherry", "Clementine", "Cucumber", "Date", "Fig",
|
||||
"Grapefruit"/*, "Grape", "Kiwi", "Lemon", "Mango", "Mulberry", "Melon", "Nectarine", "Olive", "Orange"*/);
|
||||
|
||||
static Set<String> generateRandomSet() {
|
||||
Set<String> set = new HashSet<>();
|
||||
Random random = new Random();
|
||||
int size = random.nextInt(fruits.size());
|
||||
while (set.size() != size) {
|
||||
set.add(fruits.get(random.nextInt(fruits.size())));
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import org.junit.Test;
|
||||
public class TernaryOperatorUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenACondition_whenUsingTernaryOperator_thenItEvaluatesConditionAndReturnsAValue() {
|
||||
public void whenUsingTernaryOperator_thenConditionIsEvaluatedAndValueReturned() {
|
||||
int number = 10;
|
||||
String msg = number > 10 ? "Number is greater than 10" : "Number is less than or equal to 10";
|
||||
|
||||
@@ -14,7 +14,7 @@ public class TernaryOperatorUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenATrueCondition_whenUsingTernaryOperator_thenOnlyExpression1IsEvaluated() {
|
||||
public void whenConditionIsTrue_thenOnlyFirstExpressionIsEvaluated() {
|
||||
int exp1 = 0, exp2 = 0;
|
||||
int result = 12 > 10 ? ++exp1 : ++exp2;
|
||||
|
||||
@@ -24,7 +24,7 @@ public class TernaryOperatorUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAFalseCondition_whenUsingTernaryOperator_thenOnlyExpression2IsEvaluated() {
|
||||
public void whenConditionIsFalse_thenOnlySecondExpressionIsEvaluated() {
|
||||
int exp1 = 0, exp2 = 0;
|
||||
int result = 8 > 10 ? ++exp1 : ++exp2;
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.baeldung.branchprediction;
|
||||
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CombiningUnitTest {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CombiningUnitTest.class);
|
||||
|
||||
public static final int TOP = 10000000;
|
||||
public static final double FRACTION = 0.1;
|
||||
|
||||
@Test
|
||||
public void combined() {
|
||||
long[] first = LongStream.range(0, TOP)
|
||||
.map(n -> Math.random() < FRACTION ? 0 : n)
|
||||
.toArray();
|
||||
long[] second = LongStream.range(0, TOP)
|
||||
.map(n -> Math.random() < FRACTION ? 0 : n)
|
||||
.toArray();
|
||||
|
||||
long count = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < TOP; i++) {
|
||||
if (first[i] * second[i] != 0) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
LOG.info("Counted {}/{} numbers using combined mode in {}ms", count, TOP, end - start);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void separate() {
|
||||
long[] first = LongStream.range(0, TOP)
|
||||
.map(n -> Math.random() < FRACTION ? 0 : n)
|
||||
.toArray();
|
||||
long[] second = LongStream.range(0, TOP)
|
||||
.map(n -> Math.random() < FRACTION ? 0 : n)
|
||||
.toArray();
|
||||
|
||||
long count = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < TOP; i++) {
|
||||
if (first[i] != 0 && second[i] != 0) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
LOG.info("Counted {}/{} numbers using separate mode in {}ms", count, TOP, end - start);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.baeldung.branchprediction;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class IfUnitTest {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(IfUnitTest.class);
|
||||
|
||||
public static final int TOP = 10000000;
|
||||
|
||||
@Test
|
||||
public void majorBranchSorted() {
|
||||
test(TOP, 0.9, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minorBranchSorted() {
|
||||
test(TOP, 0.1, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalBranchSorted() {
|
||||
test(TOP, 0.5, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allBranchSorted() {
|
||||
test(TOP, 1, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noneBranchSorted() {
|
||||
test(TOP, 0, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void majorBranchShuffled() {
|
||||
test(TOP, 0.9, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minorBranchShuffled() {
|
||||
test(TOP, 0.1, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalBranchShuffled() {
|
||||
test(TOP, 0.5, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allBranchShuffled() {
|
||||
test(TOP, 1, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noneBranchShuffled() {
|
||||
test(TOP, 0, true);
|
||||
}
|
||||
|
||||
private void test(long top, double cutoffPercentage, boolean shuffle) {
|
||||
List<Long> numbers = LongStream.range(0, top)
|
||||
.boxed()
|
||||
.collect(Collectors.toList());
|
||||
if (shuffle) {
|
||||
Collections.shuffle(numbers);
|
||||
}
|
||||
|
||||
long cutoff = (long)(top * cutoffPercentage);
|
||||
long low = 0;
|
||||
long high = 0;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
for (Long number : numbers) {
|
||||
if (number < cutoff) {
|
||||
++low;
|
||||
} else {
|
||||
++high;
|
||||
}
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
LOG.info("Counted {}/{} {} numbers in {}ms", low, high, shuffle ? "shuffled" : "sorted", end - start);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.baeldung.branchprediction;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SortingUnitTest {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SortingUnitTest.class);
|
||||
public static final int BIG = 10000000;
|
||||
public static final int SMALL = 100000;
|
||||
|
||||
@Test
|
||||
public void sortedBig() {
|
||||
test(BIG, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shuffledBig() {
|
||||
test(BIG, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sortedSmall() {
|
||||
test(SMALL, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shuffledSmall() {
|
||||
test(SMALL, true);
|
||||
}
|
||||
|
||||
private void test(long top, boolean shuffle) {
|
||||
List<Long> numbers = LongStream.range(0, top)
|
||||
.boxed()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (shuffle) {
|
||||
Collections.shuffle(numbers);
|
||||
}
|
||||
|
||||
long cutoff = top / 2;
|
||||
long count = 0;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
for (Long number : numbers) {
|
||||
if (number < cutoff) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
LOG.info("Counted {}/{} {} numbers in {}ms",
|
||||
count, top, shuffle ? "shuffled" : "sorted", end - start);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Intro to the Java SecurityManager](https://www.baeldung.com/java-security-manager)
|
||||
@@ -1,16 +0,0 @@
|
||||
<?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-security-manager</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-security-manager</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
</project>
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.baeldung.security.manager;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URL;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class SecurityManagerUnitTest {
|
||||
|
||||
@Test(expected = AccessControlException.class)
|
||||
public void whenSecurityManagerIsActive_thenNetworkIsNotAccessibleByDefault() throws Exception {
|
||||
doTest(() -> {
|
||||
new URL("http://www.google.com").openConnection().connect();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = AccessControlException.class)
|
||||
public void whenUnauthorizedClassTriesToAccessProtectedOperation_thenAnExceptionIsThrown() throws Exception {
|
||||
doTest(() -> {
|
||||
new Service().operation();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void doTest(Callable<Void> action) throws Exception {
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
try {
|
||||
action.call();
|
||||
} finally {
|
||||
System.setSecurityManager(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,5 @@ This module contains articles about core Java Security
|
||||
- [The Java SecureRandom Class](https://www.baeldung.com/java-secure-random)
|
||||
- [An Introduction to Java SASL](https://www.baeldung.com/java-sasl)
|
||||
- [A Guide to Java GSS API](https://www.baeldung.com/java-gss)
|
||||
- [Intro to the Java SecurityManager](https://www.baeldung.com/java-security-manager)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.baeldung.security.manager;
|
||||
package com.baeldung.securitymanager;
|
||||
|
||||
import java.security.BasicPermission;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.baeldung.security.manager;
|
||||
package com.baeldung.securitymanager;
|
||||
|
||||
public class Service {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.baeldung.java.md5;
|
||||
package com.baeldung.java.md5;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.securitymanager;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.security.AccessControlException;
|
||||
|
||||
public class SecurityManagerUnitTest {
|
||||
|
||||
private static final String TESTING_SECURITY_POLICY = "file:src/test/resources/testing.policy";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
System.setProperty("java.security.policy", TESTING_SECURITY_POLICY);
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
System.setSecurityManager(null);
|
||||
}
|
||||
|
||||
@Test(expected = AccessControlException.class)
|
||||
public void whenSecurityManagerIsActive_thenNetworkIsNotAccessibleByDefault() throws IOException {
|
||||
new URL("http://www.google.com").openConnection().connect();
|
||||
}
|
||||
|
||||
@Test(expected = AccessControlException.class)
|
||||
public void whenUnauthorizedClassTriesToAccessProtectedOperation_thenAnExceptionIsThrown() {
|
||||
new Service().operation();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
grant {
|
||||
// This is for testing purposes only.
|
||||
// It allows us to properly reset the security manager after the unit test completes.
|
||||
permission java.lang.RuntimePermission "setSecurityManager";
|
||||
};
|
||||
@@ -49,7 +49,8 @@
|
||||
<module>core-java-concurrency-basic-2</module>
|
||||
<module>core-java-concurrency-collections</module>
|
||||
|
||||
<module>core-java-date-operations</module>
|
||||
<module>core-java-date-operations-1</module>
|
||||
<module>core-java-date-operations-2</module>
|
||||
<!-- We haven't upgraded to java 9.-->
|
||||
<!--
|
||||
<module>core-java-datetime-computations</module>
|
||||
@@ -98,7 +99,6 @@
|
||||
<module>core-java-reflection</module>
|
||||
|
||||
<module>core-java-security</module>
|
||||
<module>core-java-security-manager</module>
|
||||
<module>core-java-streams</module>
|
||||
<module>core-java-streams-2</module>
|
||||
<module>core-java-streams-3</module>
|
||||
|
||||
Reference in New Issue
Block a user