This commit is contained in:
commit
eedd3ff6ea
|
@ -39,6 +39,16 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-commons</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
|
@ -66,6 +76,8 @@
|
||||||
<commons-codec.version>1.11</commons-codec.version>
|
<commons-codec.version>1.11</commons-codec.version>
|
||||||
<commons-math3.version>3.6.1</commons-math3.version>
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
<guava.version>28.1-jre</guava.version>
|
<guava.version>28.1-jre</guava.version>
|
||||||
|
<jackson.version>2.10.2</jackson.version>
|
||||||
|
<junit.platform.version>1.6.0</junit.platform.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
public class BoruvkaMST {
|
||||||
|
|
||||||
|
private static Tree mst = new Tree();
|
||||||
|
private static int totalWeight;
|
||||||
|
|
||||||
|
public BoruvkaMST(Graph graph) {
|
||||||
|
DisjointSet dSet = new DisjointSet(graph.getNodes());
|
||||||
|
|
||||||
|
// repeat at most log N times or until we have N-1 edges
|
||||||
|
for (int t = 1; t < graph.getNodes() && mst.getEdgeCount() < graph.getNodes() - 1; t = t + t) {
|
||||||
|
|
||||||
|
// foreach tree in forest, find closest edge
|
||||||
|
Edge[] closestEdgeArray = new Edge[graph.getNodes()];
|
||||||
|
for (Edge edge : graph.getAllEdges()) {
|
||||||
|
int first = edge.getFirst();
|
||||||
|
int second = edge.getSecond();
|
||||||
|
int firstParent = dSet.getParent(first);
|
||||||
|
int secondParent = dSet.getParent(second);
|
||||||
|
if (firstParent == secondParent) {
|
||||||
|
continue; // same tree
|
||||||
|
}
|
||||||
|
if (closestEdgeArray[firstParent] == null || edge.getWeight() < closestEdgeArray[firstParent].getWeight()) {
|
||||||
|
closestEdgeArray[firstParent] = edge;
|
||||||
|
}
|
||||||
|
if (closestEdgeArray[secondParent] == null || edge.getWeight() < closestEdgeArray[secondParent].getWeight()) {
|
||||||
|
closestEdgeArray[secondParent] = edge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add newly discovered edges to MST
|
||||||
|
for (int i = 0; i < graph.getNodes(); i++) {
|
||||||
|
Edge edge = closestEdgeArray[i];
|
||||||
|
if (edge != null) {
|
||||||
|
int first = edge.getFirst();
|
||||||
|
int second = edge.getSecond();
|
||||||
|
// don't add the same edge twice
|
||||||
|
if (dSet.getParent(first) != dSet.getParent(second)) {
|
||||||
|
mst.addEdge(edge);
|
||||||
|
totalWeight += edge.getWeight();
|
||||||
|
dSet.union(first, second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<Edge> getMST() {
|
||||||
|
return mst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalWeight() {
|
||||||
|
return totalWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class DisjointSet {
|
||||||
|
|
||||||
|
private int[] nodeParents;
|
||||||
|
private int[] nodeRanks;
|
||||||
|
|
||||||
|
public DisjointSet(int n) {
|
||||||
|
nodeParents = new int[n];
|
||||||
|
nodeRanks = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
nodeParents[i] = i;
|
||||||
|
nodeRanks[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getParent(int node) {
|
||||||
|
while (node != nodeParents[node]) {
|
||||||
|
node = nodeParents[node];
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void union(int node1, int node2) {
|
||||||
|
int node1Parent = getParent(node1);
|
||||||
|
int node2Parent = getParent(node2);
|
||||||
|
if (node1Parent == node2Parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeRanks[node1Parent] < nodeRanks[node2Parent]) {
|
||||||
|
nodeParents[node1Parent] = node2Parent;
|
||||||
|
}
|
||||||
|
else if (nodeRanks[node1Parent] > nodeRanks[node2Parent]) {
|
||||||
|
nodeParents[node2Parent] = node1Parent;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nodeParents[node2Parent] = node1Parent;
|
||||||
|
nodeRanks[node1Parent]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "Parent: " + Arrays.toString(nodeParents) + "Rank: " + Arrays.toString(nodeRanks);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
public class Edge {
|
||||||
|
|
||||||
|
private final int first;
|
||||||
|
private final int second;
|
||||||
|
private final int weight;
|
||||||
|
|
||||||
|
public Edge(int first, int second, int weight) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getWeight() {
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFirst() {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSecond() {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOtherNode(int firstNode) {
|
||||||
|
int secondNode = 0;
|
||||||
|
if (firstNode == first)
|
||||||
|
secondNode = second;
|
||||||
|
else if (firstNode == second)
|
||||||
|
secondNode = first;
|
||||||
|
return secondNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%d-%d %d", first, second, weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
|
||||||
|
public class Graph {
|
||||||
|
|
||||||
|
private int nodes;
|
||||||
|
private int edges;
|
||||||
|
private Tree[] trees;
|
||||||
|
|
||||||
|
public Graph(Input jsonGraph) throws JsonParseException, JsonMappingException, IOException {
|
||||||
|
nodes = jsonGraph.getNodes();
|
||||||
|
trees = (Tree[]) new Tree[nodes];
|
||||||
|
for (int i = 0; i < nodes; i++) {
|
||||||
|
trees[i] = new Tree();
|
||||||
|
}
|
||||||
|
|
||||||
|
int edgesFromInput = jsonGraph.getEdges();
|
||||||
|
for (int i = 0; i < edgesFromInput; i++) {
|
||||||
|
int first = jsonGraph.getEdgeList()
|
||||||
|
.get(i)
|
||||||
|
.getFirst();
|
||||||
|
int second = jsonGraph.getEdgeList()
|
||||||
|
.get(i)
|
||||||
|
.getSecond();
|
||||||
|
int weight = jsonGraph.getEdgeList()
|
||||||
|
.get(i)
|
||||||
|
.getWeight();
|
||||||
|
Edge edge = new Edge(first, second, weight);
|
||||||
|
|
||||||
|
trees[first].addEdge(edge);
|
||||||
|
trees[second].addEdge(edge);
|
||||||
|
edges++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNodes() {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEdges() {
|
||||||
|
return edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<Edge> iterableTree(int i) {
|
||||||
|
return trees[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<Edge> getAllEdges() {
|
||||||
|
Iterable<Edge> list = new Tree();
|
||||||
|
for (int i = 0; i < nodes; i++) {
|
||||||
|
for (Edge edge : iterableTree(i)) {
|
||||||
|
if (edge.getOtherNode(i) > i) {
|
||||||
|
((Tree) list).addEdge(edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Input {
|
||||||
|
private int nodes;
|
||||||
|
private int edges;
|
||||||
|
private List<E> edgeList;
|
||||||
|
|
||||||
|
public int getNodes() {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodes(int nodes) {
|
||||||
|
this.nodes = nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEdges() {
|
||||||
|
return edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEdges(int edges) {
|
||||||
|
this.edges = edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<E> getEdgeList() {
|
||||||
|
return edgeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEdgeList(List<E> edgeList) {
|
||||||
|
this.edgeList = edgeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class E {
|
||||||
|
private int first;
|
||||||
|
private int second;
|
||||||
|
private int weight;
|
||||||
|
|
||||||
|
public int getFirst() {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirst(int first) {
|
||||||
|
this.first = first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSecond() {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecond(int second) {
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWeight() {
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeight(int weight) {
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class Tree implements Iterable<Edge> {
|
||||||
|
private Node root;
|
||||||
|
private int edgeCount;
|
||||||
|
|
||||||
|
private static class Node {
|
||||||
|
private Edge edge;
|
||||||
|
private Node next;
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
String nextStr = next != null ? next.toString() : "";
|
||||||
|
return edge.toString() + " | " + nextStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tree() {
|
||||||
|
root = null;
|
||||||
|
edgeCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEdgeCount() {
|
||||||
|
return edgeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEdge(Edge edge) {
|
||||||
|
Node oldRoot = root;
|
||||||
|
root = new Node();
|
||||||
|
root.edge = edge;
|
||||||
|
root.next = oldRoot;
|
||||||
|
edgeCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
String rootStr = root != null ? root.toString() : "";
|
||||||
|
return "Tree: " + rootStr + "Size: " + edgeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<Edge> iterator() {
|
||||||
|
return new LinkedIterator(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LinkedIterator implements Iterator<Edge> {
|
||||||
|
private Node current;
|
||||||
|
|
||||||
|
public LinkedIterator(Node root) {
|
||||||
|
current = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
return current != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Edge next() {
|
||||||
|
Edge edge = current.edge;
|
||||||
|
current = current.next;
|
||||||
|
return edge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
public class BoruvkaUnitTest {
|
||||||
|
|
||||||
|
private Input input;
|
||||||
|
private static String INPUT_JSON = "/input.json";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void convertInputJsonToObject() throws JsonParseException, JsonMappingException, IOException {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
StringBuilder jsonStr = new StringBuilder();
|
||||||
|
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(BoruvkaMST.class.getResourceAsStream(INPUT_JSON)))) {
|
||||||
|
String line;
|
||||||
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
jsonStr.append(line)
|
||||||
|
.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input = mapper.readValue(jsonStr.toString(), Input.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInputGraph_whenBoruvkaPerformed_thenMinimumSpanningTree() throws JsonParseException, JsonMappingException, IOException {
|
||||||
|
Graph graph = new Graph(input);
|
||||||
|
BoruvkaMST boruvkaMST = new BoruvkaMST(graph);
|
||||||
|
|
||||||
|
Tree mst = (Tree) boruvkaMST.getMST();
|
||||||
|
|
||||||
|
assertEquals(30, boruvkaMST.getTotalWeight());
|
||||||
|
assertEquals(4, mst.getEdgeCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"nodes": 5,
|
||||||
|
"edges": 7,
|
||||||
|
"edgeList": [
|
||||||
|
{
|
||||||
|
"first": 0,
|
||||||
|
"second": 1,
|
||||||
|
"weight": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"first": 0,
|
||||||
|
"second": 2,
|
||||||
|
"weight": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"first": 1,
|
||||||
|
"second": 2,
|
||||||
|
"weight": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"first": 1,
|
||||||
|
"second": 3,
|
||||||
|
"weight": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"first": 2,
|
||||||
|
"second": 3,
|
||||||
|
"weight": 15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"first": 2,
|
||||||
|
"second": 4,
|
||||||
|
"weight": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"first": 3,
|
||||||
|
"second": 4,
|
||||||
|
"weight": 7
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.baeldung.apache</groupId>
|
||||||
|
<artifactId>apache-beam</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.beam</groupId>
|
||||||
|
<artifactId>beam-sdks-java-core</artifactId>
|
||||||
|
<version>${beam.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- runtime scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.beam</groupId>
|
||||||
|
<artifactId>beam-runners-direct-java</artifactId>
|
||||||
|
<version>${beam.version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- test scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<beam.version>2.19.0</beam.version>
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,71 @@
|
||||||
|
package com.baeldung.apache.beam.intro;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.apache.beam.sdk.Pipeline;
|
||||||
|
import org.apache.beam.sdk.io.TextIO;
|
||||||
|
import org.apache.beam.sdk.options.PipelineOptions;
|
||||||
|
import org.apache.beam.sdk.options.PipelineOptionsFactory;
|
||||||
|
import org.apache.beam.sdk.transforms.Count;
|
||||||
|
import org.apache.beam.sdk.transforms.Filter;
|
||||||
|
import org.apache.beam.sdk.transforms.FlatMapElements;
|
||||||
|
import org.apache.beam.sdk.transforms.MapElements;
|
||||||
|
import org.apache.beam.sdk.values.KV;
|
||||||
|
import org.apache.beam.sdk.values.PCollection;
|
||||||
|
import org.apache.beam.sdk.values.TypeDescriptors;
|
||||||
|
|
||||||
|
public class WordCount {
|
||||||
|
|
||||||
|
public static boolean wordCount(String inputFilePath, String outputFilePath) {
|
||||||
|
// We use default options
|
||||||
|
PipelineOptions options = PipelineOptionsFactory.create();
|
||||||
|
// to create the pipeline
|
||||||
|
Pipeline p = Pipeline.create(options);
|
||||||
|
// Here is our workflow graph
|
||||||
|
PCollection<KV<String, Long>> wordCount = p
|
||||||
|
.apply("(1) Read all lines", TextIO.read().from(inputFilePath))
|
||||||
|
.apply("(2) Flatmap to a list of words", FlatMapElements.into(TypeDescriptors.strings())
|
||||||
|
.via(line -> Arrays.asList(line.split("\\s"))))
|
||||||
|
.apply("(3) Lowercase all", MapElements.into(TypeDescriptors.strings())
|
||||||
|
.via(word -> word.toLowerCase()))
|
||||||
|
.apply("(4) Trim punctuations", MapElements.into(TypeDescriptors.strings())
|
||||||
|
.via(word -> trim(word)))
|
||||||
|
.apply("(5) Filter stopwords", Filter.by(word -> !isStopWord(word)))
|
||||||
|
.apply("(6) Count words", Count.perElement());
|
||||||
|
// We convert the PCollection to String so that we can write it to file
|
||||||
|
wordCount.apply(MapElements.into(TypeDescriptors.strings())
|
||||||
|
.via(count -> count.getKey() + " --> " + count.getValue()))
|
||||||
|
.apply(TextIO.write().to(outputFilePath));
|
||||||
|
// Finally we must run the pipeline, otherwise it's only a definition
|
||||||
|
p.run().waitUntilFinish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isStopWord(String word) {
|
||||||
|
String[] stopwords = {"am", "are", "is", "i", "you", "me",
|
||||||
|
"he", "she", "they", "them", "was",
|
||||||
|
"were", "from", "in", "of", "to", "be",
|
||||||
|
"him", "her", "us", "and", "or"};
|
||||||
|
for (String stopword : stopwords) {
|
||||||
|
if (stopword.compareTo(word) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String trim(String word) {
|
||||||
|
return word.replace("(","")
|
||||||
|
.replace(")", "")
|
||||||
|
.replace(",", "")
|
||||||
|
.replace(".", "")
|
||||||
|
.replace("\"", "")
|
||||||
|
.replace("'", "")
|
||||||
|
.replace(":", "")
|
||||||
|
.replace(";", "")
|
||||||
|
.replace("-", "")
|
||||||
|
.replace("?", "")
|
||||||
|
.replace("!", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.apache.beam.intro;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.apache.beam.intro.WordCount;
|
||||||
|
|
||||||
|
public class WordCountUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
// @Ignore
|
||||||
|
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
|
||||||
|
boolean jobDone = WordCount.wordCount("src/test/resources/wordcount.txt", "target/output");
|
||||||
|
assertTrue(jobDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
We've all heard the scare stories about North Korea: the homemade nuclear arsenal built while their people starve and then aimed imprecisely at the rest of the world, a
|
||||||
|
leader so deluded he makes L Ron Hubbard look like a man excessively overburdened with self-doubt and their deep-seated belief that foreign capitalists will invade at any
|
||||||
|
moment and steal all their bauxite.
|
||||||
|
The popular portrayal of this Marxist nation is something like one of the more harrowing episodes of M*A*S*H, only with the cast of wacky characters replaced by twitchy,
|
||||||
|
heavily armed Stalinist meth addicts
|
||||||
|
Cracked would like to take a moment to celebrate the good things about North Korea though, the things that the country's enemies prefer to suppress as part of their politically
|
||||||
|
motivated jealousy. Like how no different to you and me, there's nothing every North Korean likes more after an 18 hour shift at the phosphorus plant than a nice beer to go with
|
||||||
|
his dried fish ration. Ever attentive to its people's needs and in the twinkling of a decade, North Korea's leadership bought, disassembled, transported and rebuilt a British
|
||||||
|
brewery in order to discover and reproduce the secrets of beer and then brew the sweet nectar for its hardworking people, up to 18 bottles at a time. And with minimal fatalities.
|
||||||
|
When was the last time YOUR leader got a beer for YOU, American? (NB do not answer this question if you are Henry Louis Gates).
|
||||||
|
Or how about the fried chicken restaurant that downtown Pyongyang boasts? Yes real chicken, fried and then delivered to your sleeping cube, with optional beer if you like! You
|
||||||
|
don't even have to remove the feathers or pull out the gizzard yourself. Mostly. Americans must eat their fried chicken from a bucket, like swine, sold by a company so secretive
|
||||||
|
that even the very blend of seasoning used is intentionally kept from them. And they call North Korea paranoid?
|
||||||
|
And how many nations would entertain the syphilitic, bourgeois ramblings of Bill Clinton let alone permit him anywhere near their proud womenfolk? Only wise Kim Jong Il could see
|
||||||
|
past Bill's many, many imperfections and treat him with the pity and kindness he deserves, accepting his feeble pleas to pardon the American spies rightly convicted of photographing
|
||||||
|
the nation's sensitive beetroot fields.
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.threaddump;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.ThreadInfo;
|
||||||
|
import java.lang.management.ThreadMXBean;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
public class ThreadDump {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
threadDump(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void threadDump(boolean lockedMonitors, boolean lockedSynchronizers) throws IOException {
|
||||||
|
Path threadDumpFile = Paths.get("ThreadDump.txt");
|
||||||
|
|
||||||
|
StringBuffer threadDump = new StringBuffer(System.lineSeparator());
|
||||||
|
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
|
||||||
|
for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) {
|
||||||
|
threadDump.append(threadInfo.toString());
|
||||||
|
}
|
||||||
|
Files.write(threadDumpFile, threadDump.toString().getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1
pom.xml
1
pom.xml
|
@ -862,6 +862,7 @@
|
||||||
<module>antlr</module>
|
<module>antlr</module>
|
||||||
|
|
||||||
<module>apache-avro</module>
|
<module>apache-avro</module>
|
||||||
|
<module>apache-beam</module>
|
||||||
<module>apache-bval</module>
|
<module>apache-bval</module>
|
||||||
<module>apache-curator</module>
|
<module>apache-curator</module>
|
||||||
<module>apache-cxf</module>
|
<module>apache-cxf</module>
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.version;
|
||||||
|
|
||||||
|
import org.springframework.boot.system.JavaVersion;
|
||||||
|
import org.springframework.boot.system.SystemProperties;
|
||||||
|
import org.springframework.core.SpringVersion;
|
||||||
|
|
||||||
|
public class VersionObtainer {
|
||||||
|
|
||||||
|
public String getSpringVersion() {
|
||||||
|
return SpringVersion.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJavaVersion() {
|
||||||
|
return JavaVersion.getJavaVersion().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJdkVersion() {
|
||||||
|
return SystemProperties.get("java.version");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.version;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest(classes = VersionObtainer.class)
|
||||||
|
public class VersionObtainerUnitTest {
|
||||||
|
|
||||||
|
public VersionObtainer version = new VersionObtainer();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSpringVersion() {
|
||||||
|
String res = version.getSpringVersion();
|
||||||
|
assertThat(res).isNotEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetJdkVersion() {
|
||||||
|
String res = version.getJdkVersion();
|
||||||
|
assertThat(res).isNotEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetJavaVersion() {
|
||||||
|
String res = version.getJavaVersion();
|
||||||
|
assertThat(res).isNotEmpty();
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>2.2.2.RELEASE</version>
|
<version>2.2.2.RELEASE</version>
|
||||||
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Inject a value to a static field
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
```sh
|
||||||
|
mvn clean install
|
||||||
|
mvn spring-boot:run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Request
|
||||||
|
|
||||||
|
**GET**
|
||||||
|
http://localhost:8080/properties
|
||||||
|
|
||||||
|
|
||||||
|
## Response
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"Inject a value to a static field",
|
||||||
|
"Inject a value to a static field",
|
||||||
|
null
|
||||||
|
]
|
||||||
|
```
|
|
@ -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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.2.4.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>static.value.injection</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>static.value.injection</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.junit.vintage</groupId>
|
||||||
|
<artifactId>junit-vintage-engine</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.controller;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class PropertyController {
|
||||||
|
|
||||||
|
@Value("${name}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Value("${name}")
|
||||||
|
private static String NAME_NULL;
|
||||||
|
|
||||||
|
private static String NAME_STATIC;
|
||||||
|
|
||||||
|
@Value("${name}")
|
||||||
|
public void setNameStatic(String name){
|
||||||
|
PropertyController.NAME_STATIC = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/properties")
|
||||||
|
public List<String> getProperties(){
|
||||||
|
return Arrays.asList(this.name, NAME_STATIC, NAME_NULL) ;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
name = Inject a value to a static field
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,48 +16,51 @@ public class MockitoVoidMethodsUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddCalledVerified() {
|
public void whenAddCalledVerified() {
|
||||||
MyList mockVoid = mock(MyList.class);
|
MyList myList = mock(MyList.class);
|
||||||
mockVoid.add(0, "");
|
myList.add(0, "");
|
||||||
verify(mockVoid, times(1)).add(0, "");
|
|
||||||
|
verify(myList, times(1)).add(0, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = Exception.class)
|
@Test(expected = Exception.class)
|
||||||
public void givenNull_addThrows() {
|
public void givenNull_addThrows() {
|
||||||
MyList mockVoid = mock(MyList.class);
|
MyList myList = mock(MyList.class);
|
||||||
doThrow().when(mockVoid).add(isA(Integer.class), isNull());
|
doThrow().when(myList).add(isA(Integer.class), isNull());
|
||||||
mockVoid.add(0, null);
|
|
||||||
|
myList.add(0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddCalledValueCaptured() {
|
public void whenAddCalledValueCaptured() {
|
||||||
MyList mockVoid = mock(MyList.class);
|
MyList myList = mock(MyList.class);
|
||||||
ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class);
|
ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class);
|
||||||
doNothing().when(mockVoid).add(any(Integer.class), valueCapture.capture());
|
doNothing().when(myList).add(any(Integer.class), valueCapture.capture());
|
||||||
mockVoid.add(0, "captured");
|
myList.add(0, "captured");
|
||||||
|
|
||||||
assertEquals("captured", valueCapture.getValue());
|
assertEquals("captured", valueCapture.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddCalledAnswered() {
|
public void whenAddCalledAnswered() {
|
||||||
MyList mockVoid = mock(MyList.class);
|
MyList myList = mock(MyList.class);
|
||||||
doAnswer((Answer<Void>) invocation -> {
|
doAnswer(invocation -> {
|
||||||
Object arg0 = invocation.getArgument(0);
|
Object arg0 = invocation.getArgument(0);
|
||||||
Object arg1 = invocation.getArgument(1);
|
Object arg1 = invocation.getArgument(1);
|
||||||
|
|
||||||
//do something with the arguments here
|
//do something with the arguments here
|
||||||
assertEquals(3, arg0);
|
assertEquals(3, arg0);
|
||||||
assertEquals("answer me", arg1);
|
assertEquals("answer me", arg1);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}).when(mockVoid).add(any(Integer.class), any(String.class));
|
}).when(myList).add(any(Integer.class), any(String.class));
|
||||||
mockVoid.add(3, "answer me");
|
myList.add(3, "answer me");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenAddCalledRealMethodCalled() {
|
public void whenAddCalledRealMethodCalled() {
|
||||||
MyList mockVoid = mock(MyList.class);
|
MyList myList = mock(MyList.class);
|
||||||
doCallRealMethod().when(mockVoid).add(any(Integer.class), any(String.class));
|
doCallRealMethod().when(myList).add(any(Integer.class), any(String.class));
|
||||||
mockVoid.add(1, "real");
|
myList.add(1, "real");
|
||||||
verify(mockVoid, times(1)).add(1, "real");
|
|
||||||
|
verify(myList, times(1)).add(1, "real");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue