Merge remote-tracking branch 'origin/PR-6865' into PR-6865
This commit is contained in:
@@ -20,6 +20,17 @@
|
||||
<version>${junit-platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>7.7.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>32.1.1-jre</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.baeldung.cartesianproduct;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public class CartesianProduct {
|
||||
public List<List<Object>> getCartesianProductIterative(List<List<Object>> sets) {
|
||||
List<List<Object>> result = new ArrayList<>();
|
||||
if(sets == null || sets.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
int totalSets = sets.size();
|
||||
int totalCombinations = 1 << totalSets;
|
||||
for(int i = 0; i < totalCombinations; i++) {
|
||||
List<Object> combination = new ArrayList<>();
|
||||
for(int j = 0; j < totalSets; j++) {
|
||||
if (((i >> j) & 1) == 1) {
|
||||
combination.add(sets.get(j).get(0));
|
||||
} else {
|
||||
combination.add(sets.get(j).get(1));
|
||||
}
|
||||
}
|
||||
result.add(combination);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<List<Object>> getCartesianProductRecursive(List<List<Object>> sets) {
|
||||
List<List<Object>> result = new ArrayList<>();
|
||||
getCartesianProductRecursiveHelper(sets, 0, new ArrayList<>(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getCartesianProductRecursiveHelper(List<List<Object>> sets, int index, List<Object> current, List<List<Object>> result) {
|
||||
if(index == sets.size()) {
|
||||
result.add(new ArrayList<>(current));
|
||||
return;
|
||||
}
|
||||
List<Object> currentSet = sets.get(index);
|
||||
for(Object element: currentSet) {
|
||||
current.add(element);
|
||||
getCartesianProductRecursiveHelper(sets, index+1, current, result);
|
||||
current.remove(current.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public List<List<Object>> getCartesianProductUsingStreams(List<List<Object>> sets) {
|
||||
return cartesianProduct(sets,0).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Stream<List<Object>> cartesianProduct(List<List<Object>> sets, int index) {
|
||||
if(index == sets.size()) {
|
||||
List<Object> emptyList = new ArrayList<>();
|
||||
return Stream.of(emptyList);
|
||||
}
|
||||
List<Object> currentSet = sets.get(index);
|
||||
return currentSet.stream().flatMap(element -> cartesianProduct(sets, index+1)
|
||||
.map(list -> {
|
||||
List<Object> newList = new ArrayList<>(list);
|
||||
newList.add(0, element); return newList;
|
||||
}));
|
||||
}
|
||||
|
||||
public List<List<Object>> getCartesianProductUsingGuava(List<Set<Object>> sets) {
|
||||
Set<List<Object>> cartesianProduct = Sets.cartesianProduct(sets);
|
||||
List<List<Object>> cartesianList = new ArrayList<>(cartesianProduct);
|
||||
return cartesianList;
|
||||
}
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package com.baeldung.cartesianproduct;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class CartesianProductUnitTest {
|
||||
private CartesianProduct cp = new CartesianProduct();
|
||||
List<List<Object>> sets = Arrays.asList(
|
||||
Arrays.asList(10, 20),
|
||||
Arrays.asList("John", "Jack"),
|
||||
Arrays.asList('I', 'J')
|
||||
);
|
||||
|
||||
@Test
|
||||
public void whenUsingStreams_thenCalculateCartesianProduct() {
|
||||
List<List<Object>> expected = Arrays.asList(
|
||||
Arrays.asList(10, "John", 'I'),
|
||||
Arrays.asList(10, "John", 'J'),
|
||||
Arrays.asList(10, "Jack", 'I'),
|
||||
Arrays.asList(10, "Jack", 'J'),
|
||||
Arrays.asList(20, "John", 'I'),
|
||||
Arrays.asList(20, "John", 'J'),
|
||||
Arrays.asList(20, "Jack", 'I'),
|
||||
Arrays.asList(20, "Jack", 'J')
|
||||
);
|
||||
List<List<Object>> cartesianProduct = cp.getCartesianProductUsingStreams(sets);
|
||||
|
||||
assertEquals(expected, cartesianProduct);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingRecursion_thenCalculateCartesianProduct() {
|
||||
List<List<Object>> expected = Arrays.asList(
|
||||
Arrays.asList(10, "John", 'I'),
|
||||
Arrays.asList(10, "John", 'J'),
|
||||
Arrays.asList(10, "Jack", 'I'),
|
||||
Arrays.asList(10, "Jack", 'J'),
|
||||
Arrays.asList(20, "John", 'I'),
|
||||
Arrays.asList(20, "John", 'J'),
|
||||
Arrays.asList(20, "Jack", 'I'),
|
||||
Arrays.asList(20, "Jack", 'J')
|
||||
);
|
||||
List<List<Object>> cartesianProduct = cp.getCartesianProductRecursive(sets);
|
||||
|
||||
assertEquals(expected, cartesianProduct);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingIterativeApproach_thenCalculateCartesianProduct() {
|
||||
List<List<Object>> expected = Arrays.asList(
|
||||
Arrays.asList(20, "Jack", 'J'),
|
||||
Arrays.asList(10, "Jack", 'J'),
|
||||
Arrays.asList(20, "John", 'J'),
|
||||
Arrays.asList(10, "John", 'J'),
|
||||
Arrays.asList(20, "Jack", 'I'),
|
||||
Arrays.asList(10, "Jack", 'I'),
|
||||
Arrays.asList(20, "John", 'I'),
|
||||
Arrays.asList(10, "John", 'I')
|
||||
);
|
||||
List<List<Object>> cartesianProduct = cp.getCartesianProductIterative(sets);
|
||||
|
||||
assertEquals(expected, cartesianProduct);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingGuava_thenCalculateCartesianProduct() {
|
||||
List<Set<Object>> sets = new ArrayList<>();
|
||||
sets.add(new HashSet<>(Arrays.asList(10, 20)));
|
||||
sets.add(new HashSet<>(Arrays.asList("John", "Jack")));
|
||||
sets.add(new HashSet<>(Arrays.asList('I', 'J')));
|
||||
|
||||
List<List<Object>> expected = Arrays.asList(
|
||||
Arrays.asList(20, "John", 'I'),
|
||||
Arrays.asList(20, "John", 'J'),
|
||||
Arrays.asList(20, "Jack", 'I'),
|
||||
Arrays.asList(20, "Jack", 'J'),
|
||||
Arrays.asList(10, "John", 'I'),
|
||||
Arrays.asList(10, "John", 'J'),
|
||||
Arrays.asList(10, "Jack", 'I'),
|
||||
Arrays.asList(10, "Jack", 'J')
|
||||
);
|
||||
List<List<Object>> cartesianProduct = cp.getCartesianProductUsingGuava(sets);
|
||||
|
||||
assertEquals(expected, cartesianProduct);
|
||||
}
|
||||
}
|
||||
+19
-13
@@ -7,31 +7,37 @@ import java.util.concurrent.Phaser;
|
||||
|
||||
class LongRunningAction implements Runnable {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(LongRunningAction.class);
|
||||
private String threadName;
|
||||
private Phaser ph;
|
||||
private static final Logger log = LoggerFactory.getLogger(LongRunningAction.class);
|
||||
private final String threadName;
|
||||
private final Phaser ph;
|
||||
|
||||
LongRunningAction(String threadName, Phaser ph) {
|
||||
this.threadName = threadName;
|
||||
this.ph = ph;
|
||||
|
||||
this.randomWait();
|
||||
|
||||
ph.register();
|
||||
log.info("Thread {} registered during phase {}", threadName, ph.getPhase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
log.info("This is phase {}", ph.getPhase());
|
||||
log.info("Thread {} before long running action", threadName);
|
||||
|
||||
log.info("Thread {} BEFORE long running action in phase {}", threadName, ph.getPhase());
|
||||
ph.arriveAndAwaitAdvance();
|
||||
|
||||
randomWait();
|
||||
|
||||
log.info("Thread {} AFTER long running action in phase {}", threadName, ph.getPhase());
|
||||
ph.arriveAndDeregister();
|
||||
}
|
||||
|
||||
// Simulating real work
|
||||
private void randomWait() {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
Thread.sleep((long) (Math.random() * 100));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
log.debug("Thread {} action completed and waiting for others", threadName);
|
||||
ph.arriveAndAwaitAdvance();
|
||||
log.debug("Thread {} proceeding in phase {}", threadName, ph.getPhase());
|
||||
|
||||
ph.arriveAndDeregister();
|
||||
}
|
||||
}
|
||||
+13
-21
@@ -7,8 +7,6 @@ import org.junit.runners.MethodSorters;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Phaser;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
@@ -16,38 +14,32 @@ import static junit.framework.TestCase.assertEquals;
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class PhaserUnitTest {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(PhaserUnitTest.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(PhaserUnitTest.class);
|
||||
|
||||
@Test
|
||||
public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() {
|
||||
//given
|
||||
ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() throws InterruptedException {
|
||||
Phaser ph = new Phaser(1);
|
||||
assertEquals(0, ph.getPhase());
|
||||
|
||||
//when
|
||||
executorService.submit(new LongRunningAction("thread-1", ph));
|
||||
executorService.submit(new LongRunningAction("thread-2", ph));
|
||||
executorService.submit(new LongRunningAction("thread-3", ph));
|
||||
new Thread(new LongRunningAction("thread-1", ph)).start();
|
||||
new Thread(new LongRunningAction("thread-2", ph)).start();
|
||||
new Thread(new LongRunningAction("thread-3", ph)).start();
|
||||
|
||||
//then
|
||||
log.debug("Thread {} waiting for others", Thread.currentThread().getName());
|
||||
log.info("Thread {} waiting for others", Thread.currentThread().getName());
|
||||
ph.arriveAndAwaitAdvance();
|
||||
log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
|
||||
|
||||
log.info("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
|
||||
assertEquals(1, ph.getPhase());
|
||||
|
||||
//and
|
||||
executorService.submit(new LongRunningAction("thread-4", ph));
|
||||
executorService.submit(new LongRunningAction("thread-5", ph));
|
||||
new Thread(new LongRunningAction("thread-4", ph)).start();
|
||||
new Thread(new LongRunningAction("thread-5", ph)).start();
|
||||
|
||||
log.debug("Thread {} waiting for others", Thread.currentThread().getName());
|
||||
log.info("Thread {} waiting for new phase", Thread.currentThread().getName());
|
||||
ph.arriveAndAwaitAdvance();
|
||||
log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
|
||||
|
||||
log.info("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
|
||||
assertEquals(2, ph.getPhase());
|
||||
|
||||
|
||||
ph.arriveAndDeregister();
|
||||
Thread.sleep(1000);
|
||||
assertEquals(true, ph.isTerminated());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
<version>${fscontext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>activation</artifactId>
|
||||
<version>1.1</version>
|
||||
<groupId>org.eclipse.angus</groupId>
|
||||
<artifactId>angus-activation</artifactId>
|
||||
<version>${angus-activation.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -73,10 +73,6 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>${maven-javadoc-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- Build an executable JAR -->
|
||||
@@ -131,13 +127,15 @@
|
||||
|
||||
<properties>
|
||||
<!-- maven plugins -->
|
||||
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
|
||||
<hsqldb.version>2.4.0</hsqldb.version>
|
||||
<maven-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
|
||||
<hsqldb.version>2.7.1</hsqldb.version>
|
||||
<!-- Mime Type Libraries -->
|
||||
<tika.version>1.18</tika.version>
|
||||
<tika.version>2.8.0</tika.version>
|
||||
<jmime-magic.version>0.1.5</jmime-magic.version>
|
||||
<maven-jar-plugin.version>3.1.0</maven-jar-plugin.version>
|
||||
<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
|
||||
<fscontext.version>4.4.2</fscontext.version>
|
||||
<jakarta-activation-api.version>2.1.2</jakarta-activation-api.version>
|
||||
<angus-activation.version>2.0.1</angus-activation.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+1
-1
@@ -10,7 +10,7 @@ import java.net.URLConnection;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import javax.activation.MimetypesFileTypeMap;
|
||||
import jakarta.activation.MimetypesFileTypeMap;
|
||||
|
||||
import org.apache.tika.Tika;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${google-guava.version}</version>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
@@ -47,7 +47,6 @@
|
||||
<commons-codec.version>1.15</commons-codec.version>
|
||||
<jaxb-api.version>2.3.1</jaxb-api.version>
|
||||
<spring-security-crypto.version>6.0.3</spring-security-crypto.version>
|
||||
<google-guava.version>31.0.1-jre</google-guava.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.23.1</version>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -55,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -81,7 +81,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${google.guava.version}</version>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.oath.cyclops</groupId>
|
||||
@@ -114,6 +114,7 @@
|
||||
|
||||
<properties>
|
||||
<!-- testing -->
|
||||
<assertj.version>3.23.1</assertj.version>
|
||||
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
|
||||
<maven.compiler.source>12</maven.compiler.source>
|
||||
<maven.compiler.target>12</maven.compiler.target>
|
||||
@@ -123,7 +124,6 @@
|
||||
<io.varv.version>1.0.0-alpha-4</io.varv.version>
|
||||
<io.reactor3.version>3.5.1</io.reactor3.version>
|
||||
<apache.commons.collection4.version>4.4</apache.commons.collection4.version>
|
||||
<google.guava.version>31.1-jre</google.guava.version>
|
||||
<cyclops.version>10.4.1</cyclops.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -14,33 +14,6 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>${jmh-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>${jmh-generator.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.codepoetics</groupId>
|
||||
<artifactId>protonpack</artifactId>
|
||||
@@ -57,17 +30,7 @@
|
||||
<version>${streamex.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${asspectj.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>${asspectj.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>pl.touk</groupId>
|
||||
<groupId>com.pivovarit</groupId>
|
||||
<artifactId>throwing-function</artifactId>
|
||||
<version>${throwing-function.version}</version>
|
||||
</dependency>
|
||||
@@ -96,15 +59,13 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<vavr.version>0.9.0</vavr.version>
|
||||
<protonpack.version>1.15</protonpack.version>
|
||||
<streamex.version>0.6.5</streamex.version>
|
||||
<joda.version>2.10</joda.version>
|
||||
<throwing-function.version>1.3</throwing-function.version>
|
||||
<asspectj.version>1.8.9</asspectj.version>
|
||||
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<vavr.version>0.10.4</vavr.version>
|
||||
<protonpack.version>1.16</protonpack.version>
|
||||
<streamex.version>0.8.1</streamex.version>
|
||||
<throwing-function.version>1.5.1</throwing-function.version>
|
||||
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+3
-4
@@ -1,8 +1,8 @@
|
||||
package com.baeldung.stream.filter;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import pl.touk.throwing.ThrowingPredicate;
|
||||
import pl.touk.throwing.exception.WrappedException;
|
||||
import com.pivovarit.function.ThrowingPredicate;
|
||||
import com.pivovarit.function.exception.WrappedException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
@@ -156,5 +156,4 @@ public class StreamFilterUnitTest {
|
||||
})
|
||||
.collect(Collectors.toList())).isInstanceOf(RuntimeException.class);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons.lang3.version}</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ibm.icu</groupId>
|
||||
@@ -42,8 +42,6 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<commons.lang3.version>3.12.0</commons.lang3.version>
|
||||
<guava.version>31.1-jre</guava.version>
|
||||
<icu4j.version>61.1</icu4j.version>
|
||||
</properties>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user