Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
f7b8d67c0b
@ -13,22 +13,22 @@ public class KadaneAlgorithm {
|
|||||||
int start = 0;
|
int start = 0;
|
||||||
int end = 0;
|
int end = 0;
|
||||||
|
|
||||||
int maxSoFar = 0, maxEndingHere = 0;
|
int maxSoFar = arr[0], maxEndingHere = arr[0];
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
|
||||||
if (arr[i] > maxEndingHere + arr[i]) {
|
if (arr[i] > maxEndingHere + arr[i]) {
|
||||||
start = i;
|
start = i;
|
||||||
maxEndingHere = arr[i];
|
maxEndingHere = arr[i];
|
||||||
} else
|
} else {
|
||||||
maxEndingHere = maxEndingHere + arr[i];
|
maxEndingHere = maxEndingHere + arr[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (maxSoFar < maxEndingHere) {
|
if (maxSoFar < maxEndingHere) {
|
||||||
maxSoFar = maxEndingHere;
|
maxSoFar = maxEndingHere;
|
||||||
end = i;
|
end = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.info("Found Maximum Subarray between {} and {}", start, end);
|
logger.info("Found Maximum Subarray between {} and {}", Math.min(start, end), end);
|
||||||
return maxSoFar;
|
return maxSoFar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,22 @@ class KadaneAlgorithmUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturns6() {
|
void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturns6() {
|
||||||
//given
|
//given
|
||||||
int[] arr = new int[]{-3, 1, -8, 4, -1, 2, 1, -5, 5};
|
int[] arr = new int[] { -3, 1, -8, 4, -1, 2, 1, -5, 5 };
|
||||||
//when
|
//when
|
||||||
KadaneAlgorithm algorithm = new KadaneAlgorithm();
|
KadaneAlgorithm algorithm = new KadaneAlgorithm();
|
||||||
int maxSum = algorithm.maxSubArraySum(arr);
|
int maxSum = algorithm.maxSubArraySum(arr);
|
||||||
//then
|
//then
|
||||||
assertEquals(6, maxSum);
|
assertEquals(6, maxSum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenArrayWithAllNegativeNumbersWhenMaximumSubarrayThenReturnsExpectedResult() {
|
||||||
|
//given
|
||||||
|
int[] arr = new int[] { -8, -7, -5, -4, -3, -1, -2 };
|
||||||
|
//when
|
||||||
|
KadaneAlgorithm algorithm = new KadaneAlgorithm();
|
||||||
|
int maxSum = algorithm.maxSubArraySum(arr);
|
||||||
|
//then
|
||||||
|
assertEquals(-1, maxSum);
|
||||||
|
}
|
||||||
}
|
}
|
@ -11,3 +11,4 @@ This module contains articles about Apache POI
|
|||||||
- [Get String Value of Excel Cell with Apache POI](https://www.baeldung.com/java-apache-poi-cell-string-value)
|
- [Get String Value of Excel Cell with Apache POI](https://www.baeldung.com/java-apache-poi-cell-string-value)
|
||||||
- [Read Excel Cell Value Rather Than Formula With Apache POI](https://www.baeldung.com/apache-poi-read-cell-value-formula)
|
- [Read Excel Cell Value Rather Than Formula With Apache POI](https://www.baeldung.com/apache-poi-read-cell-value-formula)
|
||||||
- [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas)
|
- [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas)
|
||||||
|
- [Insert a Row in Excel Using Apache POI](https://www.baeldung.com/apache-poi-insert-excel-row)
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.baeldung.poi.excel.insert;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
public class ExcelInsertRowUnitTest {
|
||||||
|
private static final String FILE_NAME = "test.xlsx";
|
||||||
|
private static final String NEW_FILE_NAME = "new_test.xlsx";
|
||||||
|
private String fileLocation;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws URISyntaxException {
|
||||||
|
fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenWorkbook_whenInsertRowBetween_thenRowCreated() throws IOException {
|
||||||
|
int startRow = 2;
|
||||||
|
int rowNumber = 1;
|
||||||
|
Workbook workbook = new XSSFWorkbook(fileLocation);
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
int lastRow = sheet.getLastRowNum();
|
||||||
|
if (lastRow < startRow) {
|
||||||
|
sheet.createRow(startRow);
|
||||||
|
}
|
||||||
|
sheet.shiftRows(startRow, lastRow, rowNumber, true, true);
|
||||||
|
sheet.createRow(startRow);
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(NEW_FILE_NAME);
|
||||||
|
workbook.write(outputStream);
|
||||||
|
File file = new File(NEW_FILE_NAME);
|
||||||
|
|
||||||
|
final int expectedRowResult = 5;
|
||||||
|
Assertions.assertEquals(expectedRowResult, workbook.getSheetAt(0).getLastRowNum());
|
||||||
|
|
||||||
|
outputStream.close();
|
||||||
|
file.delete();
|
||||||
|
workbook.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,9 +5,10 @@ This module contains articles about Java 10 core features
|
|||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Java 10 LocalVariable Type-Inference](http://www.baeldung.com/java-10-local-variable-type-inference)
|
- [Java 10 LocalVariable Type-Inference](http://www.baeldung.com/java-10-local-variable-type-inference)
|
||||||
- [Guide to Java 10](http://www.baeldung.com/java-10-overview)
|
- [New Features in Java 10](https://www.baeldung.com/java-10-overview)
|
||||||
- [Copy a List to Another List in Java](http://www.baeldung.com/java-copy-list-to-another)
|
- [Copy a List to Another List in Java](http://www.baeldung.com/java-copy-list-to-another)
|
||||||
- [Deep Dive Into the New Java JIT Compiler – Graal](https://www.baeldung.com/graal-java-jit-compiler)
|
- [Deep Dive Into the New Java JIT Compiler – Graal](https://www.baeldung.com/graal-java-jit-compiler)
|
||||||
- [Copying Sets in Java](https://www.baeldung.com/java-copy-sets)
|
- [Copying Sets in Java](https://www.baeldung.com/java-copy-sets)
|
||||||
- [Converting between a List and a Set in Java](https://www.baeldung.com/convert-list-to-set-and-set-to-list)
|
- [Converting between a List and a Set in Java](https://www.baeldung.com/convert-list-to-set-and-set-to-list)
|
||||||
- [Java IndexOutOfBoundsException “Source Does Not Fit in Dest”](https://www.baeldung.com/java-indexoutofboundsexception)
|
- [Java IndexOutOfBoundsException “Source Does Not Fit in Dest”](https://www.baeldung.com/java-indexoutofboundsexception)
|
||||||
|
- [Collect a Java Stream to an Immutable Collection](https://www.baeldung.com/java-stream-immutable-collection)
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.java10.streams;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toUnmodifiableList;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class StreamToImmutableJava10UnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingCollectorsToUnmodifiableList_thenSuccess() {
|
||||||
|
List<String> givenList = Arrays.asList("a", "b", "c");
|
||||||
|
List<String> result = givenList.stream()
|
||||||
|
.collect(toUnmodifiableList());
|
||||||
|
|
||||||
|
System.out.println(result.getClass());
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
## Relevant Articles:
|
## Relevant Articles:
|
||||||
|
|
||||||
|
|
||||||
- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)
|
- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)
|
||||||
- [Java 12 New Features](https://www.baeldung.com/java-12-new-features)
|
- [New Features in Java 12](https://www.baeldung.com/java-12-new-features)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
|
|
||||||
- [Java Switch Statement](https://www.baeldung.com/java-switch)
|
- [Java Switch Statement](https://www.baeldung.com/java-switch)
|
||||||
- [New Java 13 Features](https://www.baeldung.com/java-13-new-features)
|
- [New Features in Java 13](https://www.baeldung.com/java-13-new-features)
|
||||||
|
@ -10,4 +10,4 @@ This module contains articles about Java 14.
|
|||||||
- [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception)
|
- [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception)
|
||||||
- [Foreign Memory Access API in Java 14](https://www.baeldung.com/java-foreign-memory-access)
|
- [Foreign Memory Access API in Java 14](https://www.baeldung.com/java-foreign-memory-access)
|
||||||
- [Java 14 Record Keyword](https://www.baeldung.com/java-record-keyword)
|
- [Java 14 Record Keyword](https://www.baeldung.com/java-record-keyword)
|
||||||
- [Java 14 – New Features](https://www.baeldung.com/java-14-new-features)
|
- [New Features in Java 14](https://www.baeldung.com/java-14-new-features)
|
||||||
|
@ -4,7 +4,7 @@ This module contains articles about core Java features that have been introduced
|
|||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Java 9 New Features](https://www.baeldung.com/new-java-9)
|
- [New Features in Java 9](https://www.baeldung.com/new-java-9)
|
||||||
- [Java 9 Variable Handles Demystified](http://www.baeldung.com/java-variable-handles)
|
- [Java 9 Variable Handles Demystified](http://www.baeldung.com/java-variable-handles)
|
||||||
- [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client)
|
- [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client)
|
||||||
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.annotations;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
|
||||||
|
@RetentionAnnotation
|
||||||
|
@Generated("Available only on source code")
|
||||||
|
public class AnnotatedClass {
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.TYPE;
|
||||||
|
|
||||||
|
@Target(TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface RetentionAnnotation {
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.annotations;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
public class AnnotatedClassUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAnnotationRetentionPolicyRuntime_shouldAccess() {
|
||||||
|
AnnotatedClass anAnnotatedClass = new AnnotatedClass();
|
||||||
|
Annotation[] annotations = anAnnotatedClass.getClass().getAnnotations();
|
||||||
|
assertThat(annotations.length, is(1));
|
||||||
|
}
|
||||||
|
}
|
@ -3,4 +3,4 @@
|
|||||||
This module contains articles about Java Character Class
|
This module contains articles about Java Character Class
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Character#isAlphabetic vs Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic)
|
- [Character#isAlphabetic vs. Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic)
|
||||||
|
@ -5,3 +5,4 @@
|
|||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap)
|
- [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap)
|
||||||
|
- [Java Deque vs. Stack](https://www.baeldung.com/java-deque-vs-stack)
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<assertj.version>3.18.0</assertj.version>
|
<assertj.version>3.19.0</assertj.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.baeldung.collections.dequestack;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class ArrayLifoStack<E> implements LifoStack<E> {
|
||||||
|
private final Deque<E> deque = new ArrayDeque<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void push(E item) {
|
||||||
|
deque.addFirst(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E pop() {
|
||||||
|
return deque.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E peek() {
|
||||||
|
return deque.peekFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
// implementing methods from the Collection interface
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return deque.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return deque.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return deque.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return deque.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] toArray() {
|
||||||
|
return deque.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T[] toArray(T[] a) {
|
||||||
|
return deque.toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(E e) {
|
||||||
|
return deque.add(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
return deque.remove(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(Collection<?> c) {
|
||||||
|
return deque.containsAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(Collection<? extends E> c) {
|
||||||
|
return deque.addAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(Collection<?> c) {
|
||||||
|
return deque.removeAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(Collection<?> c) {
|
||||||
|
return deque.retainAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
deque.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.collections.dequestack;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface LifoStack<E> extends Collection<E> {
|
||||||
|
|
||||||
|
E peek();
|
||||||
|
|
||||||
|
E pop();
|
||||||
|
|
||||||
|
void push(E item);
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package com.baeldung.collections.dequestack;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class StackVsDequeUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenAStack_whenAccessByIndex_thenElementCanBeRead() {
|
||||||
|
Stack<String> myStack = new Stack<>();
|
||||||
|
myStack.push("I am the 1st element."); //index 0
|
||||||
|
myStack.push("I am the 2nd element."); //index 1
|
||||||
|
myStack.push("I am the 3rd element."); //index 2
|
||||||
|
//access by index
|
||||||
|
assertThat(myStack.get(0)).isEqualTo("I am the 1st element.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenAStack_whenIterate_thenFromBottomToTop() {
|
||||||
|
Stack<String> myStack = new Stack<>();
|
||||||
|
myStack.push("I am at the bottom.");
|
||||||
|
myStack.push("I am in the middle.");
|
||||||
|
myStack.push("I am at the top.");
|
||||||
|
|
||||||
|
Iterator<String> it = myStack.iterator();
|
||||||
|
|
||||||
|
assertThat(it).toIterable().containsExactly(
|
||||||
|
"I am at the bottom.",
|
||||||
|
"I am in the middle.",
|
||||||
|
"I am at the top.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenAStack_whenAddOrRemoveByIndex_thenElementCanBeAddedOrRemoved() {
|
||||||
|
Stack<String> myStack = new Stack<>();
|
||||||
|
myStack.push("I am the 1st element.");
|
||||||
|
myStack.push("I am the 3rd element.");
|
||||||
|
|
||||||
|
assertThat(myStack.size()).isEqualTo(2);
|
||||||
|
|
||||||
|
//insert by index
|
||||||
|
myStack.add(1, "I am the 2nd element.");
|
||||||
|
assertThat(myStack.size()).isEqualTo(3);
|
||||||
|
assertThat(myStack.get(1)).isEqualTo("I am the 2nd element.");
|
||||||
|
//remove by index
|
||||||
|
myStack.remove(1);
|
||||||
|
assertThat(myStack.size()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenADeque_whenAddOrRemoveLastElement_thenTheLastElementCanBeAddedOrRemoved() {
|
||||||
|
Deque<String> myStack = new ArrayDeque<>();
|
||||||
|
myStack.push("I am the 1st element.");
|
||||||
|
myStack.push("I am the 2nd element.");
|
||||||
|
myStack.push("I am the 3rd element.");
|
||||||
|
|
||||||
|
assertThat(myStack.size()).isEqualTo(3);
|
||||||
|
|
||||||
|
//insert element to the bottom of the stack
|
||||||
|
myStack.addLast("I am the NEW element.");
|
||||||
|
assertThat(myStack.size()).isEqualTo(4);
|
||||||
|
assertThat(myStack.peek()).isEqualTo("I am the 3rd element.");
|
||||||
|
|
||||||
|
//remove element from the bottom of the stack
|
||||||
|
String removedStr = myStack.removeLast();
|
||||||
|
assertThat(myStack.size()).isEqualTo(3);
|
||||||
|
assertThat(removedStr).isEqualTo("I am the NEW element.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenADeque_whenIterate_thenFromTopToBottom() {
|
||||||
|
Deque<String> myStack = new ArrayDeque<>();
|
||||||
|
myStack.push("I am at the bottom.");
|
||||||
|
myStack.push("I am in the middle.");
|
||||||
|
myStack.push("I am at the top.");
|
||||||
|
|
||||||
|
Iterator<String> it = myStack.iterator();
|
||||||
|
|
||||||
|
assertThat(it).toIterable().containsExactly(
|
||||||
|
"I am at the top.",
|
||||||
|
"I am in the middle.",
|
||||||
|
"I am at the bottom.");
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import org.openjdk.jmh.runner.options.Options;
|
|||||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -18,12 +19,12 @@ import java.util.concurrent.TimeUnit;
|
|||||||
@State(Scope.Thread)
|
@State(Scope.Thread)
|
||||||
public class PrimitivesListPerformance {
|
public class PrimitivesListPerformance {
|
||||||
|
|
||||||
private List<Integer> arrayList = new ArrayList<>();
|
private List<Integer> arrayList = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||||
private TIntArrayList tList = new TIntArrayList();
|
private TIntArrayList tList = new TIntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||||
private cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList();
|
private cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||||
private IntArrayList fastUtilList = new IntArrayList();
|
private IntArrayList fastUtilList = new IntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||||
|
|
||||||
private int getValue = 10;
|
private int getValue = 4;
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
public boolean addArrayList() {
|
public boolean addArrayList() {
|
||||||
|
@ -7,4 +7,6 @@ This module contains articles about Map data structures in Java.
|
|||||||
- [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps)
|
- [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps)
|
||||||
- [The Map.computeIfAbsent() Method](https://www.baeldung.com/java-map-computeifabsent)
|
- [The Map.computeIfAbsent() Method](https://www.baeldung.com/java-map-computeifabsent)
|
||||||
- [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap)
|
- [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap)
|
||||||
|
- [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor)
|
||||||
|
- [Converting java.util.Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap)
|
||||||
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)
|
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)
|
||||||
|
@ -20,6 +20,11 @@
|
|||||||
<artifactId>jmh-core</artifactId>
|
<artifactId>jmh-core</artifactId>
|
||||||
<version>${jmh-core.version}</version>
|
<version>${jmh-core.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.baeldung.map.propertieshashmap;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class PropertiesToHashMapConverter {
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
public static HashMap<String, String> typeCastConvert(Properties prop) {
|
||||||
|
Map step1 = prop;
|
||||||
|
Map<String, String> step2 = (Map<String, String>) step1;
|
||||||
|
return new HashMap<>(step2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, String> loopConvert(Properties prop) {
|
||||||
|
HashMap<String, String> retMap = new HashMap<>();
|
||||||
|
for (Map.Entry<Object, Object> entry : prop.entrySet()) {
|
||||||
|
retMap.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
|
||||||
|
}
|
||||||
|
return retMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, String> streamConvert(Properties prop) {
|
||||||
|
return prop.entrySet().stream().collect(
|
||||||
|
Collectors.toMap(
|
||||||
|
e -> String.valueOf(e.getKey()),
|
||||||
|
e -> String.valueOf(e.getValue()),
|
||||||
|
(prev, next) -> next, HashMap::new
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String, String> guavaConvert(Properties prop) {
|
||||||
|
return Maps.newHashMap(Maps.fromProperties(prop));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.baeldung.map.hashmap.loadfactor;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class HashMapLoadFactorUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreateMapWithDefaultParam_thenSucces() {
|
||||||
|
Map<String, String> mapWithDefaultParams = new HashMap<>();
|
||||||
|
mapWithDefaultParams.put("1", "one");
|
||||||
|
mapWithDefaultParams.put("2", "two");
|
||||||
|
mapWithDefaultParams.put("3", "three");
|
||||||
|
mapWithDefaultParams.put("4", "four");
|
||||||
|
mapWithDefaultParams.put("5", "five");
|
||||||
|
|
||||||
|
Assert.assertEquals(5, mapWithDefaultParams.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreateMapWithInitialCapacity_thenSucces() {
|
||||||
|
Map<String, String> mapWithInitialCapacity = new HashMap<>(5);
|
||||||
|
mapWithInitialCapacity.put("1", "one");
|
||||||
|
mapWithInitialCapacity.put("2", "two");
|
||||||
|
mapWithInitialCapacity.put("3", "three");
|
||||||
|
|
||||||
|
Assert.assertEquals(3, mapWithInitialCapacity.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreateMapWithInitialCapacityAndLF_thenSucces() {
|
||||||
|
Map<String, String> mapWithInitialCapacityAndLF = new HashMap<>(5, 0.5f);
|
||||||
|
mapWithInitialCapacityAndLF.put("1", "one");
|
||||||
|
mapWithInitialCapacityAndLF.put("2", "two");
|
||||||
|
mapWithInitialCapacityAndLF.put("3", "three");
|
||||||
|
mapWithInitialCapacityAndLF.put("4", "four");
|
||||||
|
mapWithInitialCapacityAndLF.put("5", "five");
|
||||||
|
mapWithInitialCapacityAndLF.put("6", "six");
|
||||||
|
mapWithInitialCapacityAndLF.put("7", "seven");
|
||||||
|
mapWithInitialCapacityAndLF.put("8", "eight");
|
||||||
|
mapWithInitialCapacityAndLF.put("9", "nine");
|
||||||
|
mapWithInitialCapacityAndLF.put("10", "ten");
|
||||||
|
|
||||||
|
Assert.assertEquals(10, mapWithInitialCapacityAndLF.size());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,192 @@
|
|||||||
|
package com.baeldung.map.propertieshashmap;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class PropertiesToHashMapConverterUnitTest {
|
||||||
|
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
private final static String propertyFileName = "toHashMap.properties";
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setup() throws IOException {
|
||||||
|
properties = new Properties();
|
||||||
|
try (InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName)) {
|
||||||
|
if (is != null) {
|
||||||
|
properties.load(is);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingPropertiesLoaded_whenCheck_thenEquals() {
|
||||||
|
assertEquals(3, properties.size());
|
||||||
|
assertEquals("str_value", properties.get("property1"));
|
||||||
|
assertEquals("123", properties.get("property2"));
|
||||||
|
assertEquals("", properties.get("property3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPropertiesModified_thenTypeSafeIssues() {
|
||||||
|
compromiseProperties(properties);
|
||||||
|
|
||||||
|
assertEquals(5, properties.size());
|
||||||
|
|
||||||
|
assertNull(properties.getProperty("property4"));
|
||||||
|
assertNotEquals(String.class, properties.get("property4").getClass());
|
||||||
|
assertEquals(456, properties.get("property4"));
|
||||||
|
|
||||||
|
|
||||||
|
assertNull(properties.getProperty("5"));
|
||||||
|
assertNotEquals(String.class, properties.get(5).getClass());
|
||||||
|
assertEquals(10.11, properties.get(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingNonModifiedProperties_whenTypeCastConvert_thenNoTypeSafeIssues() {
|
||||||
|
HashMap<String, String> hMap = PropertiesToHashMapConverter.typeCastConvert(properties);
|
||||||
|
|
||||||
|
assertEquals(3, hMap.size());
|
||||||
|
assertEquals(String.class, hMap.get("property1").getClass());
|
||||||
|
assertEquals(properties.get("property1"), hMap.get("property1"));
|
||||||
|
assertEquals(String.class, hMap.get("property2").getClass());
|
||||||
|
assertEquals(properties.get("property2"), hMap.get("property2"));
|
||||||
|
assertEquals(String.class, hMap.get("property3").getClass());
|
||||||
|
assertEquals(properties.get("property3"), hMap.get("property3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingModifiedProperties_whenTypeCastConvert_thenClassCastException() {
|
||||||
|
compromiseProperties(properties);
|
||||||
|
HashMap<String, String> hMap = PropertiesToHashMapConverter.typeCastConvert(properties);
|
||||||
|
assertEquals(5, hMap.size());
|
||||||
|
|
||||||
|
assertThrows(ClassCastException.class, () -> {
|
||||||
|
String s = hMap.get("property4");
|
||||||
|
});
|
||||||
|
assertEquals(Integer.class, ((Object) hMap.get("property4")).getClass());
|
||||||
|
|
||||||
|
assertNull(hMap.get("5"));
|
||||||
|
assertNotNull(hMap.get(5));
|
||||||
|
assertThrows(ClassCastException.class, () -> {
|
||||||
|
String s = hMap.get(5);
|
||||||
|
});
|
||||||
|
assertEquals(Double.class, ((Object) hMap.get(5)).getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingNonModifiedProperties_whenLoopConvert_thenNoTypeSafeIssues() {
|
||||||
|
HashMap<String, String> hMap = PropertiesToHashMapConverter.loopConvert(properties);
|
||||||
|
|
||||||
|
assertEquals(3, hMap.size());
|
||||||
|
assertEquals(String.class, hMap.get("property1").getClass());
|
||||||
|
assertEquals(properties.get("property1"), hMap.get("property1"));
|
||||||
|
assertEquals(String.class, hMap.get("property2").getClass());
|
||||||
|
assertEquals(properties.get("property2"), hMap.get("property2"));
|
||||||
|
assertEquals(String.class, hMap.get("property3").getClass());
|
||||||
|
assertEquals(properties.get("property3"), hMap.get("property3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingModifiedProperties_whenLoopConvert_thenNoClassCastException() {
|
||||||
|
compromiseProperties(properties);
|
||||||
|
HashMap<String, String> hMap = PropertiesToHashMapConverter.loopConvert(properties);
|
||||||
|
assertEquals(5, hMap.size());
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
String s = hMap.get("property4");
|
||||||
|
});
|
||||||
|
assertEquals(String.class, hMap.get("property4").getClass());
|
||||||
|
assertEquals("456", hMap.get("property4"));
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
String s = hMap.get("5");
|
||||||
|
});
|
||||||
|
assertEquals("10.11", hMap.get("5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingNonModifiedProperties_whenStreamConvert_thenNoTypeSafeIssues() {
|
||||||
|
HashMap<String, String> hMap = PropertiesToHashMapConverter.streamConvert(properties);
|
||||||
|
|
||||||
|
assertEquals(3, hMap.size());
|
||||||
|
assertEquals(String.class, hMap.get("property1").getClass());
|
||||||
|
assertEquals(properties.get("property1"), hMap.get("property1"));
|
||||||
|
assertEquals(String.class, hMap.get("property2").getClass());
|
||||||
|
assertEquals(properties.get("property2"), hMap.get("property2"));
|
||||||
|
assertEquals(String.class, hMap.get("property3").getClass());
|
||||||
|
assertEquals(properties.get("property3"), hMap.get("property3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingModifiedProperties_whenStreamConvert_thenNoClassCastException() {
|
||||||
|
compromiseProperties(properties);
|
||||||
|
HashMap<String, String> hMap = PropertiesToHashMapConverter.streamConvert(properties);
|
||||||
|
assertEquals(5, hMap.size());
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
String s = hMap.get("property4");
|
||||||
|
});
|
||||||
|
assertEquals(String.class, hMap.get("property4").getClass());
|
||||||
|
assertEquals("456", hMap.get("property4"));
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> {
|
||||||
|
String s = hMap.get("5");
|
||||||
|
});
|
||||||
|
assertEquals("10.11", hMap.get("5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingModifiedProperties_whenLoopConvertAndStreamConvert_thenHashMapsSame() {
|
||||||
|
compromiseProperties(properties);
|
||||||
|
HashMap<String, String> hMap1 = PropertiesToHashMapConverter.loopConvert(properties);
|
||||||
|
HashMap<String, String> hMap2 = PropertiesToHashMapConverter.streamConvert(properties);
|
||||||
|
|
||||||
|
assertEquals(hMap2, hMap1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingNonModifiedProperties_whenGuavaConvert_thenNoTypeSafeIssues() {
|
||||||
|
HashMap<String, String> hMap = PropertiesToHashMapConverter.guavaConvert(properties);
|
||||||
|
|
||||||
|
assertEquals(3, hMap.size());
|
||||||
|
assertEquals(String.class, hMap.get("property1").getClass());
|
||||||
|
assertEquals(properties.get("property1"), hMap.get("property1"));
|
||||||
|
assertEquals(String.class, hMap.get("property2").getClass());
|
||||||
|
assertEquals(properties.get("property2"), hMap.get("property2"));
|
||||||
|
assertEquals(String.class, hMap.get("property3").getClass());
|
||||||
|
assertEquals(properties.get("property3"), hMap.get("property3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingModifiedProperties_whenGuavaConvert_thenUnableToConvertAndThrowException() {
|
||||||
|
compromiseProperties(properties);
|
||||||
|
assertThrows(Exception.class, () -> PropertiesToHashMapConverter.guavaConvert(properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingModifiedPropertiesWithNoIntegerValue_whenGuavaConvert_thenNullPointerException() {
|
||||||
|
properties.put("property4", 456);
|
||||||
|
assertThrows(NullPointerException.class, () -> PropertiesToHashMapConverter.guavaConvert(properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void havingModifiedPropertiesWithNoIntegerKey_whenGuavaConvert_thenClassCastException() {
|
||||||
|
properties.put(5, 10.11);
|
||||||
|
assertThrows(ClassCastException.class, () -> PropertiesToHashMapConverter.guavaConvert(properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void compromiseProperties(Properties prop) {
|
||||||
|
prop.put("property4", 456);
|
||||||
|
prop.put(5, 10.11);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
property1=str_value
|
||||||
|
property2=123
|
||||||
|
property3=
|
@ -21,14 +21,16 @@ public class ThreadPoolInParallelStreamIntegrationTest {
|
|||||||
long lastNum = 1_000_000;
|
long lastNum = 1_000_000;
|
||||||
|
|
||||||
List<Long> aList = LongStream.rangeClosed(firstNum, lastNum).boxed().collect(Collectors.toList());
|
List<Long> aList = LongStream.rangeClosed(firstNum, lastNum).boxed().collect(Collectors.toList());
|
||||||
|
|
||||||
ForkJoinPool customThreadPool = new ForkJoinPool(4);
|
ForkJoinPool customThreadPool = new ForkJoinPool(4);
|
||||||
long actualTotal = customThreadPool
|
|
||||||
.submit(() -> aList.parallelStream()
|
|
||||||
.reduce(0L, Long::sum))
|
|
||||||
.get();
|
|
||||||
|
|
||||||
assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal);
|
try {
|
||||||
|
long actualTotal = customThreadPool
|
||||||
|
.submit(() -> aList.parallelStream().reduce(0L, Long::sum))
|
||||||
|
.get();
|
||||||
|
assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal);
|
||||||
|
} finally {
|
||||||
|
customThreadPool.shutdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -5,12 +5,12 @@ import com.google.common.io.CharSource;
|
|||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.io.input.ReaderInputStream;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class JavaXToInputStreamUnitTest {
|
public class JavaXToInputStreamUnitTest {
|
||||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
@ -28,7 +28,7 @@ public class JavaXToInputStreamUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
public final void givenUsingGuava_whenConvertingStringToInputStream_thenCorrect() throws IOException {
|
public final void givenUsingGuava_whenConvertingStringToInputStream_thenCorrect() throws IOException {
|
||||||
final String initialString = "text";
|
final String initialString = "text";
|
||||||
final InputStream targetStream = new ReaderInputStream(CharSource.wrap(initialString).openStream());
|
final InputStream targetStream = CharSource.wrap(initialString).asByteSource(StandardCharsets.UTF_8).openStream();
|
||||||
|
|
||||||
IOUtils.closeQuietly(targetStream);
|
IOUtils.closeQuietly(targetStream);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baeldung.servicemodule</groupId>
|
<groupId>com.baeldung.servicemodule</groupId>
|
||||||
<artifactId>servicemodule</artifactId>
|
<artifactId>servicemodule2</artifactId>
|
||||||
<version>${servicemodule.version}</version>
|
<version>${servicemodule.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -77,7 +77,6 @@
|
|||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
<!-- instrumentation -->
|
<!-- instrumentation -->
|
||||||
<javaassist.version>3.27.0-GA</javaassist.version>
|
<javaassist.version>3.27.0-GA</javaassist.version>
|
||||||
<esapi.version>2.1.0.1</esapi.version>
|
|
||||||
<sun.tools.version>1.8.0</sun.tools.version>
|
<sun.tools.version>1.8.0</sun.tools.version>
|
||||||
<jol-core.version>0.10</jol-core.version>
|
<jol-core.version>0.10</jol-core.version>
|
||||||
<asm.version>8.0.1</asm.version>
|
<asm.version>8.0.1</asm.version>
|
||||||
|
@ -11,4 +11,5 @@ This module contains articles about core features in the Java language
|
|||||||
- [The transient Keyword in Java](https://www.baeldung.com/java-transient-keyword)
|
- [The transient Keyword in Java](https://www.baeldung.com/java-transient-keyword)
|
||||||
- [How to Access an Iteration Counter in a For Each Loop](https://www.baeldung.com/java-foreach-counter)
|
- [How to Access an Iteration Counter in a For Each Loop](https://www.baeldung.com/java-foreach-counter)
|
||||||
- [Comparing Doubles in Java](https://www.baeldung.com/java-comparing-doubles)
|
- [Comparing Doubles in Java](https://www.baeldung.com/java-comparing-doubles)
|
||||||
|
- [Guide to Implementing the compareTo Method](https://www.baeldung.com/java-compareto)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-lang-2)
|
- [[<-- Prev]](/core-java-modules/core-java-lang-2)
|
||||||
|
5
core-java-modules/core-java-lang-4/README.md
Normal file
5
core-java-modules/core-java-lang-4/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## Core Java Lang (Part 4)
|
||||||
|
|
||||||
|
This module contains articles about core features in the Java language
|
||||||
|
|
||||||
|
- [The Java final Keyword – Impact on Performance](https://www.baeldung.com/java-final-performance)
|
47
core-java-modules/core-java-lang-4/pom.xml
Normal file
47
core-java-modules/core-java-lang-4/pom.xml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?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-lang-4</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>core-java-lang-4</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
|
<artifactId>core-java-modules</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.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>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>core-java-lang-4</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<jmh.version>1.28</jmh.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung.finalkeyword;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class BenchmarkRunner {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
org.openjdk.jmh.Main.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
public static String concatNonFinalStrings() {
|
||||||
|
String x = "x";
|
||||||
|
String y = "y";
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
public static String concatFinalStrings() {
|
||||||
|
final String x = "x";
|
||||||
|
final String y = "y";
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.baeldung.finalkeyword;
|
||||||
|
|
||||||
|
import java.io.Console;
|
||||||
|
|
||||||
|
public class ClassVariableFinal {
|
||||||
|
|
||||||
|
static final boolean doX = false;
|
||||||
|
static final boolean doY = true;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Console console = System.console();
|
||||||
|
if (doX) {
|
||||||
|
console.writer().println("x");
|
||||||
|
} else if (doY) {
|
||||||
|
console.writer().println("y");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.baeldung.finalkeyword;
|
||||||
|
|
||||||
|
import java.io.Console;
|
||||||
|
|
||||||
|
public class ClassVariableNonFinal {
|
||||||
|
|
||||||
|
static boolean doX = false;
|
||||||
|
static boolean doY = true;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Console console = System.console();
|
||||||
|
if (doX) {
|
||||||
|
console.writer().println("x");
|
||||||
|
} else if (doY) {
|
||||||
|
console.writer().println("y");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,5 @@
|
|||||||
|
|
||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
|
|
||||||
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
|
|
||||||
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
|
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
|
||||||
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
|
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
|
||||||
|
@ -8,3 +8,4 @@ This module contains articles about generics in Java
|
|||||||
- [Raw Types in Java](https://www.baeldung.com/raw-types-java)
|
- [Raw Types in Java](https://www.baeldung.com/raw-types-java)
|
||||||
- [Super Type Tokens in Java Generics](https://www.baeldung.com/java-super-type-tokens)
|
- [Super Type Tokens in Java Generics](https://www.baeldung.com/java-super-type-tokens)
|
||||||
- [Java Warning “unchecked conversion”](https://www.baeldung.com/java-unchecked-conversion)
|
- [Java Warning “unchecked conversion”](https://www.baeldung.com/java-unchecked-conversion)
|
||||||
|
- [Java Warning “Unchecked Cast”](https://www.baeldung.com/java-warning-unchecked-cast)
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.uncheckedcast;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.Month;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class UncheckedCast {
|
||||||
|
public static Map getRawMap() {
|
||||||
|
Map rawMap = new HashMap();
|
||||||
|
rawMap.put("date 1", LocalDate.of(2021, Month.FEBRUARY, 10));
|
||||||
|
rawMap.put("date 2", LocalDate.of(1992, Month.AUGUST, 8));
|
||||||
|
rawMap.put("date 3", LocalDate.of(1976, Month.NOVEMBER, 18));
|
||||||
|
return rawMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map getRawMapWithMixedTypes() {
|
||||||
|
Map rawMap = new HashMap();
|
||||||
|
rawMap.put("date 1", LocalDate.of(2021, Month.FEBRUARY, 10));
|
||||||
|
rawMap.put("date 2", LocalDate.of(1992, Month.AUGUST, 8));
|
||||||
|
rawMap.put("date 3", LocalDate.of(1976, Month.NOVEMBER, 18));
|
||||||
|
rawMap.put("date 4", new Date());
|
||||||
|
return rawMap;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.uncheckedcast;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.Month;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class UncheckedCastUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRawMap_whenCastToTypedMap_shouldHaveCompilerWarning() {
|
||||||
|
Map<String, LocalDate> castFromRawMap = (Map<String, LocalDate>) UncheckedCast.getRawMap();
|
||||||
|
Assert.assertEquals(3, castFromRawMap.size());
|
||||||
|
Assert.assertEquals(castFromRawMap.get("date 2"), LocalDate.of(1992, Month.AUGUST, 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void givenMixTypedRawMap_whenCastToTypedMap_shouldThrowClassCastException() {
|
||||||
|
Map<String, LocalDate> castFromRawMap = (Map<String, LocalDate>) UncheckedCast.getRawMapWithMixedTypes();
|
||||||
|
Assert.assertEquals(4, castFromRawMap.size());
|
||||||
|
Assert.assertTrue(castFromRawMap.get("date 4").isAfter(castFromRawMap.get("date 3")));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
package com.baeldung.classfile;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import com.baeldung.classfile.HelloWorld.HelloSomeone;
|
||||||
|
|
||||||
|
public class Outer {
|
||||||
|
|
||||||
|
// Static Nested class
|
||||||
|
static class StaticNested {
|
||||||
|
public String message() {
|
||||||
|
return "This is a static Nested Class";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-static Nested class
|
||||||
|
class Nested {
|
||||||
|
public String message() {
|
||||||
|
return "This is a non-static Nested Class";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local class
|
||||||
|
public String message() {
|
||||||
|
class Local {
|
||||||
|
private String message() {
|
||||||
|
return "This is a Local Class within a method";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Local local = new Local();
|
||||||
|
return local.message();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local class within if clause
|
||||||
|
public String message(String name) {
|
||||||
|
if (StringUtils.isEmpty(name)) {
|
||||||
|
class Local {
|
||||||
|
private String message() {
|
||||||
|
return "This is a Local Class within if clause";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Local local = new Local();
|
||||||
|
return local.message();
|
||||||
|
} else
|
||||||
|
return "Welcome to " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Anonymous Inner class extending a class
|
||||||
|
public String greet() {
|
||||||
|
Outer anonymous = new Outer() {
|
||||||
|
public String greet() {
|
||||||
|
return "Running Anonymous Class...";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return anonymous.greet();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Anonymous inner class implementing an interface
|
||||||
|
public String greet(String name) {
|
||||||
|
|
||||||
|
HelloWorld helloWorld = new HelloWorld() {
|
||||||
|
public String greet(String name) {
|
||||||
|
return "Welcome to " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
return helloWorld.greet(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Anonymous inner class implementing nested interface
|
||||||
|
public String greetSomeone(String name) {
|
||||||
|
|
||||||
|
HelloSomeone helloSomeOne = new HelloSomeone() {
|
||||||
|
public String greet(String name) {
|
||||||
|
return "Hello " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
return helloSomeOne.greet(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nested interface within a class
|
||||||
|
interface HelloOuter {
|
||||||
|
public String hello(String name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enum within a class
|
||||||
|
enum Color {
|
||||||
|
RED, GREEN, BLUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HelloWorld {
|
||||||
|
|
||||||
|
public String greet(String name);
|
||||||
|
|
||||||
|
// Nested class within an interface
|
||||||
|
class InnerClass {
|
||||||
|
public String greet(String name) {
|
||||||
|
return "Inner class within an interface";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nested interface within an interfaces
|
||||||
|
interface HelloSomeone {
|
||||||
|
public String greet(String name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enum within an interface
|
||||||
|
enum Directon {
|
||||||
|
NORTH, SOUTH, EAST, WEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Level {
|
||||||
|
LOW, MEDIUM, HIGH;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Foods {
|
||||||
|
|
||||||
|
DRINKS, EATS;
|
||||||
|
|
||||||
|
// Enum within Enum
|
||||||
|
enum DRINKS {
|
||||||
|
APPLE_JUICE, COLA;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EATS {
|
||||||
|
POTATO, RICE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.baeldung.classfile;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import com.baeldung.classfile.Outer.Nested;
|
||||||
|
|
||||||
|
public class OuterUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_static_nestedClass_then_verifyOutput() {
|
||||||
|
Outer.StaticNested nestedClass = new Outer.StaticNested();
|
||||||
|
assertEquals("This is a static Nested Class", nestedClass.message());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_nestedClass_then_verifyOutput() {
|
||||||
|
Outer outer = new Outer();
|
||||||
|
Nested nestedClass = outer.new Nested();
|
||||||
|
assertEquals("This is a non-static Nested Class", nestedClass.message());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_localClass_then_verifyOutput() {
|
||||||
|
Outer outer = new Outer();
|
||||||
|
assertEquals("This is a Local Class within a method", outer.message());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_localClassInIfClause_then_verifyOutput() {
|
||||||
|
Outer outer = new Outer();
|
||||||
|
assertEquals("Welcome to Baeldung", outer.message("Baeldung"));
|
||||||
|
assertEquals("This is a Local Class within if clause", outer.message(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_anonymousClass_then_verifyOutput() {
|
||||||
|
Outer outer = new Outer();
|
||||||
|
assertEquals("Running Anonymous Class...", outer.greet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_anonymousClassHelloWorld_then_verifyOutput() {
|
||||||
|
Outer outer = new Outer();
|
||||||
|
assertEquals("Welcome to Baeldung", outer.greet("Baeldung"));
|
||||||
|
}
|
||||||
|
}
|
@ -14,5 +14,12 @@
|
|||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.6.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.baeldung.selector;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.Pipe;
|
||||||
|
import java.nio.channels.SelectableChannel;
|
||||||
|
import java.nio.channels.Selector;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import static java.nio.channels.SelectionKey.OP_READ;
|
||||||
|
|
||||||
|
public class SelectorManualTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenWakeUpCalledOnSelector_thenBlockedThreadReturns() throws IOException, InterruptedException {
|
||||||
|
Pipe pipe = Pipe.open();
|
||||||
|
|
||||||
|
Selector selector = Selector.open();
|
||||||
|
SelectableChannel channel = pipe.source();
|
||||||
|
channel.configureBlocking(false);
|
||||||
|
channel.register(selector, OP_READ);
|
||||||
|
|
||||||
|
List<String> invocationStepsTracker = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
Thread thread = new Thread(() -> {
|
||||||
|
invocationStepsTracker.add(">> Count down");
|
||||||
|
latch.countDown();
|
||||||
|
try {
|
||||||
|
invocationStepsTracker.add(">> Start select");
|
||||||
|
selector.select();
|
||||||
|
invocationStepsTracker.add(">> End select");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
invocationStepsTracker.add(">> Start await");
|
||||||
|
thread.start();
|
||||||
|
latch.await();
|
||||||
|
invocationStepsTracker.add(">> End await");
|
||||||
|
|
||||||
|
invocationStepsTracker.add(">> Wakeup thread");
|
||||||
|
|
||||||
|
selector.wakeup();
|
||||||
|
channel.close();
|
||||||
|
|
||||||
|
assertThat(invocationStepsTracker)
|
||||||
|
.containsExactly(
|
||||||
|
">> Start await",
|
||||||
|
">> Count down",
|
||||||
|
">> Start select",
|
||||||
|
">> End await",
|
||||||
|
">> Wakeup thread",
|
||||||
|
">> End select"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -4,3 +4,4 @@
|
|||||||
- [Set Field Value With Reflection](https://www.baeldung.com/java-set-private-field-value)
|
- [Set Field Value With Reflection](https://www.baeldung.com/java-set-private-field-value)
|
||||||
- [Checking If a Method is Static Using Reflection in Java](https://www.baeldung.com/java-check-method-is-static)
|
- [Checking If a Method is Static Using Reflection in Java](https://www.baeldung.com/java-check-method-is-static)
|
||||||
- [Checking if a Java Class is ‘abstract’ Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract)
|
- [Checking if a Java Class is ‘abstract’ Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract)
|
||||||
|
- [Invoking a Private Method in Java](https://www.baeldung.com/java-call-private-method)
|
||||||
|
@ -14,6 +14,15 @@
|
|||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<finalName>core-java-reflection-2</finalName>
|
<finalName>core-java-reflection-2</finalName>
|
||||||
<resources>
|
<resources>
|
||||||
@ -40,5 +49,6 @@
|
|||||||
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
|
||||||
<source.version>1.8</source.version>
|
<source.version>1.8</source.version>
|
||||||
<target.version>1.8</target.version>
|
<target.version>1.8</target.version>
|
||||||
|
<spring.version>5.3.4</spring.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.reflection.access.privatemethods;
|
||||||
|
|
||||||
|
public class LongArrayUtil {
|
||||||
|
|
||||||
|
public static int indexOf(long[] array, long target) {
|
||||||
|
return indexOf(array, target, 0, array.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int indexOf(long[] array, long target, int start, int end) {
|
||||||
|
for (int i = start; i < end; i++) {
|
||||||
|
if (array[i] == target) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.reflection.access.privatemethods;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class InvokePrivateMethodsUnitTest {
|
||||||
|
|
||||||
|
private final long[] someLongArray = new long[] { 1L, 2L, 1L, 4L, 2L };
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenSearchingForLongValueInSubsequenceUsingReflection_thenTheCorrectIndexOfTheValueIsReturned() throws Exception {
|
||||||
|
Method indexOfMethod = LongArrayUtil.class.getDeclaredMethod("indexOf", long[].class, long.class, int.class, int.class);
|
||||||
|
indexOfMethod.setAccessible(true);
|
||||||
|
|
||||||
|
assertEquals(2, indexOfMethod.invoke(LongArrayUtil.class, someLongArray, 1L, 1, someLongArray.length), "The index should be 2.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenSearchingForLongValueInSubsequenceUsingSpring_thenTheCorrectIndexOfTheValueIsReturned() throws Exception {
|
||||||
|
int indexOfSearchTarget = ReflectionTestUtils.invokeMethod(LongArrayUtil.class, "indexOf", someLongArray, 1L, 1, someLongArray.length);
|
||||||
|
assertEquals(2, indexOfSearchTarget, "The index should be 2.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,4 +15,5 @@ This module contains articles about core Java Security
|
|||||||
- [Security Context Basics: User, Subject and Principal](https://www.baeldung.com/security-context-basics)
|
- [Security Context Basics: User, Subject and Principal](https://www.baeldung.com/security-context-basics)
|
||||||
- [Java AES Encryption and Decryption](https://www.baeldung.com/java-aes-encryption-decryption)
|
- [Java AES Encryption and Decryption](https://www.baeldung.com/java-aes-encryption-decryption)
|
||||||
- [InvalidAlgorithmParameterException: Wrong IV Length](https://www.baeldung.com/java-invalidalgorithmparameter-exception)
|
- [InvalidAlgorithmParameterException: Wrong IV Length](https://www.baeldung.com/java-invalidalgorithmparameter-exception)
|
||||||
|
- [The java.security.egd JVM Option](https://www.baeldung.com/java-security-egd)
|
||||||
- More articles: [[<-- prev]](/core-java-modules/core-java-security)
|
- More articles: [[<-- prev]](/core-java-modules/core-java-security)
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
<module>core-java-lang</module>
|
<module>core-java-lang</module>
|
||||||
<module>core-java-lang-2</module>
|
<module>core-java-lang-2</module>
|
||||||
<module>core-java-lang-3</module>
|
<module>core-java-lang-3</module>
|
||||||
|
<module>core-java-lang-4</module>
|
||||||
<module>core-java-lang-math</module>
|
<module>core-java-lang-math</module>
|
||||||
<module>core-java-lang-math-2</module>
|
<module>core-java-lang-math-2</module>
|
||||||
<module>core-java-lang-math-3</module>
|
<module>core-java-lang-math-3</module>
|
||||||
|
@ -10,10 +10,8 @@ public class CircularBuffer<E> {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public CircularBuffer(int capacity) {
|
public CircularBuffer(int capacity) {
|
||||||
|
|
||||||
this.capacity = (capacity < 1) ? DEFAULT_CAPACITY : capacity;
|
this.capacity = (capacity < 1) ? DEFAULT_CAPACITY : capacity;
|
||||||
this.data = (E[]) new Object[capacity];
|
this.data = (E[]) new Object[this.capacity];
|
||||||
|
|
||||||
this.readSequence = 0;
|
this.readSequence = 0;
|
||||||
this.writeSequence = -1;
|
this.writeSequence = -1;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
public class CircularLinkedList {
|
public class CircularLinkedList {
|
||||||
|
|
||||||
final Logger LOGGER = LoggerFactory.getLogger(CircularLinkedList.class);
|
final Logger logger = LoggerFactory.getLogger(CircularLinkedList.class);
|
||||||
|
|
||||||
private Node head = null;
|
private Node head = null;
|
||||||
private Node tail = null;
|
private Node tail = null;
|
||||||
@ -42,24 +42,29 @@ public class CircularLinkedList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deleteNode(int valueToDelete) {
|
public void deleteNode(int valueToDelete) {
|
||||||
|
|
||||||
Node currentNode = head;
|
Node currentNode = head;
|
||||||
|
if (head == null) {
|
||||||
if (head != null) {
|
return;
|
||||||
if (currentNode.value == valueToDelete) {
|
|
||||||
head = head.nextNode;
|
|
||||||
tail.nextNode = head;
|
|
||||||
} else {
|
|
||||||
do {
|
|
||||||
Node nextNode = currentNode.nextNode;
|
|
||||||
if (nextNode.value == valueToDelete) {
|
|
||||||
currentNode.nextNode = nextNode.nextNode;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentNode = currentNode.nextNode;
|
|
||||||
} while (currentNode != head);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
do {
|
||||||
|
Node nextNode = currentNode.nextNode;
|
||||||
|
if (nextNode.value == valueToDelete) {
|
||||||
|
if (tail == head) {
|
||||||
|
head = null;
|
||||||
|
tail = null;
|
||||||
|
} else {
|
||||||
|
currentNode.nextNode = nextNode.nextNode;
|
||||||
|
if (head == nextNode) {
|
||||||
|
head = head.nextNode;
|
||||||
|
}
|
||||||
|
if (tail == nextNode) {
|
||||||
|
tail = currentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentNode = nextNode;
|
||||||
|
} while (currentNode != head);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void traverseList() {
|
public void traverseList() {
|
||||||
@ -68,7 +73,7 @@ public class CircularLinkedList {
|
|||||||
|
|
||||||
if (head != null) {
|
if (head != null) {
|
||||||
do {
|
do {
|
||||||
LOGGER.info(currentNode.value + " ");
|
logger.info(currentNode.value + " ");
|
||||||
currentNode = currentNode.nextNode;
|
currentNode = currentNode.nextNode;
|
||||||
} while (currentNode != head);
|
} while (currentNode != head);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.baeldung.circularlinkedlist;
|
package com.baeldung.circularlinkedlist;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class CircularLinkedListUnitTest {
|
public class CircularLinkedListUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -23,7 +23,7 @@ public class CircularLinkedListUnitTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenACircularLinkedList_WhenDeletingElements_ThenListDoesNotContainThoseElements() {
|
public void givenACircularLinkedList_WhenDeletingInOrderHeadMiddleTail_ThenListDoesNotContainThoseElements() {
|
||||||
CircularLinkedList cll = createCircularLinkedList();
|
CircularLinkedList cll = createCircularLinkedList();
|
||||||
|
|
||||||
assertTrue(cll.containsNode(13));
|
assertTrue(cll.containsNode(13));
|
||||||
@ -39,6 +39,32 @@ public class CircularLinkedListUnitTest {
|
|||||||
assertFalse(cll.containsNode(46));
|
assertFalse(cll.containsNode(46));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenACircularLinkedList_WhenDeletingInOrderTailMiddleHead_ThenListDoesNotContainThoseElements() {
|
||||||
|
CircularLinkedList cll = createCircularLinkedList();
|
||||||
|
|
||||||
|
assertTrue(cll.containsNode(46));
|
||||||
|
cll.deleteNode(46);
|
||||||
|
assertFalse(cll.containsNode(46));
|
||||||
|
|
||||||
|
assertTrue(cll.containsNode(1));
|
||||||
|
cll.deleteNode(1);
|
||||||
|
assertFalse(cll.containsNode(1));
|
||||||
|
|
||||||
|
assertTrue(cll.containsNode(13));
|
||||||
|
cll.deleteNode(13);
|
||||||
|
assertFalse(cll.containsNode(13));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenACircularLinkedListWithOneNode_WhenDeletingElement_ThenListDoesNotContainTheElement() {
|
||||||
|
CircularLinkedList cll = new CircularLinkedList();
|
||||||
|
cll.addNode(1);
|
||||||
|
cll.deleteNode(1);
|
||||||
|
assertFalse(cll.containsNode(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private CircularLinkedList createCircularLinkedList() {
|
private CircularLinkedList createCircularLinkedList() {
|
||||||
CircularLinkedList cll = new CircularLinkedList();
|
CircularLinkedList cll = new CircularLinkedList();
|
||||||
|
|
||||||
|
@ -3,3 +3,4 @@
|
|||||||
- [Introduction to Docker Compose](https://www.baeldung.com/docker-compose)
|
- [Introduction to Docker Compose](https://www.baeldung.com/docker-compose)
|
||||||
- [Reusing Docker Layers with Spring Boot](https://www.baeldung.com/docker-layers-spring-boot)
|
- [Reusing Docker Layers with Spring Boot](https://www.baeldung.com/docker-layers-spring-boot)
|
||||||
- [Running Spring Boot with PostgreSQL in Docker Compose](https://www.baeldung.com/spring-boot-postgresql-docker)
|
- [Running Spring Boot with PostgreSQL in Docker Compose](https://www.baeldung.com/spring-boot-postgresql-docker)
|
||||||
|
- [How To Configure Java Heap Size Inside a Docker Container](https://www.baeldung.com/ops/docker-jvm-heap-size)
|
||||||
|
4
docker/heap-sizing/Dockerfile
Normal file
4
docker/heap-sizing/Dockerfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
FROM openjdk:8u92-jdk-alpine
|
||||||
|
COPY /src /src/
|
||||||
|
RUN mkdir /app && ls /src && javac /src/main/java/com/baeldung/docker/heapsizing/PrintXmxXms.java -d /app
|
||||||
|
CMD java -version && java $JAVA_OPTS -cp /app com.baeldung.docker.heapsizing.PrintXmxXms
|
61
docker/heap-sizing/pom.xml
Normal file
61
docker/heap-sizing/pom.xml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 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.4.2</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.baeldung.docker</groupId>
|
||||||
|
<artifactId>heap-sizing</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>heap-sizing</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>11</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor</groupId>
|
||||||
|
<artifactId>reactor-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<image>
|
||||||
|
<name>heapsizing-demo</name>
|
||||||
|
</image>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.google.cloud.tools</groupId>
|
||||||
|
<artifactId>jib-maven-plugin</artifactId>
|
||||||
|
<version>2.7.1</version>
|
||||||
|
|
||||||
|
<configuration>
|
||||||
|
<to>
|
||||||
|
<image>heapsizing-demo-jib</image>
|
||||||
|
</to>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.baeldung.docker.heapsizing;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static com.baeldung.docker.heapsizing.PrintXmxXms.logMemory;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class HeapSizingApplication {
|
||||||
|
private static final Logger logger = Logger.getLogger(HeapSizingApplication.class.getName());
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(HeapSizingApplication.class, args);
|
||||||
|
logMemory(logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.baeldung.docker.heapsizing;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.MemoryMXBean;
|
||||||
|
import java.lang.management.MemoryPoolMXBean;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class PrintXmxXms {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(PrintXmxXms.class.getName());
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
logMemory(logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We're reusing this method in HeapSizingApplication, therefore this method was extracted
|
||||||
|
* to avoid repetition.
|
||||||
|
*/
|
||||||
|
static void logMemory(Logger logger) {
|
||||||
|
float mb = 1024f * 1024f;
|
||||||
|
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
|
||||||
|
|
||||||
|
// xmx controls the maximum size of the memory allocation pool,
|
||||||
|
// which includes the heap, the garbage collector's survivor space, and other pools.
|
||||||
|
float xmx = memoryBean.getHeapMemoryUsage().getMax() / mb;
|
||||||
|
float xms = memoryBean.getHeapMemoryUsage().getInit() / mb;
|
||||||
|
logger.log(Level.INFO, "Initial Memory (xms) : {0}mb", xms);
|
||||||
|
logger.log(Level.INFO, "Max Memory (xmx) : {0}mb", xmx);
|
||||||
|
|
||||||
|
for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
|
||||||
|
logger.log(Level.INFO, "Pool: {0} (type {1}) = {2}", new Object[]{ mp.getName(), mp.getType(), mp.getUsage().getMax() / mb });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,3 @@
|
|||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Kotlin vs Java](https://www.baeldung.com/kotlin/kotlin-vs-java)
|
- [Kotlin vs Java](https://www.baeldung.com/kotlin/vs-java)
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package com.baeldung.jackson.bidirection;
|
package com.baeldung.jackson.bidirection;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||||
|
|
||||||
public class ItemWithRef {
|
public class ItemWithRef {
|
||||||
public int id;
|
public int id;
|
||||||
public String itemName;
|
public String itemName;
|
||||||
|
|
||||||
@JsonManagedReference
|
@JsonBackReference
|
||||||
public UserWithRef owner;
|
public UserWithRef owner;
|
||||||
|
|
||||||
public ItemWithRef() {
|
public ItemWithRef() {
|
||||||
|
@ -3,13 +3,13 @@ package com.baeldung.jackson.bidirection;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||||
|
|
||||||
public class UserWithRef {
|
public class UserWithRef {
|
||||||
public int id;
|
public int id;
|
||||||
public String name;
|
public String name;
|
||||||
|
|
||||||
@JsonBackReference
|
@JsonManagedReference
|
||||||
public List<ItemWithRef> userItems;
|
public List<ItemWithRef> userItems;
|
||||||
|
|
||||||
public UserWithRef() {
|
public UserWithRef() {
|
||||||
@ -19,7 +19,7 @@ public class UserWithRef {
|
|||||||
public UserWithRef(final int id, final String name) {
|
public UserWithRef(final int id, final String name) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
userItems = new ArrayList<ItemWithRef>();
|
userItems = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addItem(final ItemWithRef item) {
|
public void addItem(final ItemWithRef item) {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package com.baeldung.jackson.bidirection;
|
package com.baeldung.jackson.bidirection;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
|
|
||||||
public class JacksonBidirectionRelationUnitTest {
|
public class JacksonBidirectionRelationUnitTest {
|
||||||
|
|
||||||
@Test(expected = JsonMappingException.class)
|
@Test (expected = JsonMappingException.class)
|
||||||
public void givenBidirectionRelation_whenSerializing_thenException() throws JsonProcessingException {
|
public void givenBidirectionRelation_whenSerializing_thenException() throws JsonProcessingException {
|
||||||
final User user = new User(1, "John");
|
final User user = new User(1, "John");
|
||||||
final Item item = new Item(2, "book", user);
|
final Item item = new Item(2, "book", user);
|
||||||
@ -26,16 +28,39 @@ public class JacksonBidirectionRelationUnitTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenBidirectionRelation_whenUsingJacksonReferenceAnnotation_thenCorrect() throws JsonProcessingException {
|
public void givenBidirectionRelation_whenUsingJacksonReferenceAnnotationWithSerialization_thenCorrect() throws JsonProcessingException {
|
||||||
final UserWithRef user = new UserWithRef(1, "John");
|
final UserWithRef user = new UserWithRef(1, "John");
|
||||||
final ItemWithRef item = new ItemWithRef(2, "book", user);
|
final ItemWithRef item = new ItemWithRef(2, "book", user);
|
||||||
user.addItem(item);
|
user.addItem(item);
|
||||||
|
|
||||||
final String result = new ObjectMapper().writeValueAsString(item);
|
final String itemJson = new ObjectMapper().writeValueAsString(item);
|
||||||
|
final String userJson = new ObjectMapper().writeValueAsString(user);
|
||||||
|
|
||||||
assertThat(result, containsString("book"));
|
assertThat(itemJson, containsString("book"));
|
||||||
assertThat(result, containsString("John"));
|
assertThat(itemJson, not(containsString("John")));
|
||||||
assertThat(result, not(containsString("userItems")));
|
|
||||||
|
assertThat(userJson, containsString("John"));
|
||||||
|
assertThat(userJson, containsString("userItems"));
|
||||||
|
assertThat(userJson, containsString("book"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBidirectionRelation_whenUsingJacksonReferenceAnnotationWithDeserialization_thenCorrect() throws JsonProcessingException {
|
||||||
|
final UserWithRef user = new UserWithRef(1, "John");
|
||||||
|
final ItemWithRef item = new ItemWithRef(2, "book", user);
|
||||||
|
user.addItem(item);
|
||||||
|
|
||||||
|
final String itemJson = new ObjectMapper().writeValueAsString(item);
|
||||||
|
final String userJson = new ObjectMapper().writeValueAsString(user);
|
||||||
|
|
||||||
|
final ItemWithRef itemRead = new ObjectMapper().readValue(itemJson, ItemWithRef.class);
|
||||||
|
final UserWithRef userRead = new ObjectMapper().readValue(userJson, UserWithRef.class);
|
||||||
|
|
||||||
|
assertThat(itemRead.itemName, is("book"));
|
||||||
|
assertThat(itemRead.owner, nullValue());
|
||||||
|
|
||||||
|
assertThat(userRead.name, is("John"));
|
||||||
|
assertThat(userRead.userItems.get(0).itemName, is("book"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -3,3 +3,4 @@
|
|||||||
- [Java Map With Case-Insensitive Keys](https://www.baeldung.com/java-map-with-case-insensitive-keys)
|
- [Java Map With Case-Insensitive Keys](https://www.baeldung.com/java-map-with-case-insensitive-keys)
|
||||||
- [Using a Byte Array as Map Key in Java](https://www.baeldung.com/java-map-key-byte-array)
|
- [Using a Byte Array as Map Key in Java](https://www.baeldung.com/java-map-key-byte-array)
|
||||||
- [Using the Map.Entry Java Class](https://www.baeldung.com/java-map-entry)
|
- [Using the Map.Entry Java Class](https://www.baeldung.com/java-map-entry)
|
||||||
|
- [Optimizing HashMap’s Performance](https://www.baeldung.com/java-hashmap-optimize-performance)
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.baeldung.map.hashing;
|
||||||
|
|
||||||
|
class Member {
|
||||||
|
Integer id;
|
||||||
|
String name;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.map.hashing;
|
||||||
|
|
||||||
|
public class MemberWithBadHashing extends Member {
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return name.hashCode();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.map.hashing;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.hash.HashFunction;
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
|
||||||
|
public class MemberWithGuavaHashing extends Member {
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
HashFunction hashFunction = Hashing.murmur3_32();
|
||||||
|
return hashFunction.newHasher()
|
||||||
|
.putInt(id)
|
||||||
|
.putString(name, Charsets.UTF_8)
|
||||||
|
.hash().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.map.hashing;
|
||||||
|
|
||||||
|
public class MemberWithId extends Member {
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
MemberWithId that = (MemberWithId) o;
|
||||||
|
|
||||||
|
return id.equals(that.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.map.hashing;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class MemberWithIdAndName extends Member {
|
||||||
|
public static final int PRIME = 31;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
MemberWithObjects that = (MemberWithObjects) o;
|
||||||
|
return Objects.equals(id, that.id) &&
|
||||||
|
Objects.equals(name, that.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = id.hashCode();
|
||||||
|
result = PRIME * result + (name == null ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.baeldung.map.hashing;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class MemberWithObjects extends Member {
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
MemberWithObjects that = (MemberWithObjects) o;
|
||||||
|
return Objects.equals(id, that.id) &&
|
||||||
|
Objects.equals(name, that.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package com.baeldung.map.hashing;
|
||||||
|
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.SplittableRandom;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class HashingUnitTest {
|
||||||
|
|
||||||
|
public static final int SAMPLES = 1000000;
|
||||||
|
private SplittableRandom random = new SplittableRandom();
|
||||||
|
|
||||||
|
private String[] names = {"John", "Adam", "Suzie"};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenPrimitiveByteArrayKey_whenRetrievingFromMap_shouldRetrieveDifferentObjects() {
|
||||||
|
// bad hashing example is prohibitively slow for bigger samples
|
||||||
|
// Duration[] badHashing = testDuration(MemberWithBadHashing::new);
|
||||||
|
Duration[] withId = testDuration(MemberWithId::new);
|
||||||
|
Duration[] withObjects = testDuration(MemberWithObjects::new);
|
||||||
|
Duration[] withIdAndName = testDuration(MemberWithIdAndName::new);
|
||||||
|
|
||||||
|
// System.out.println("Inserting with bad hashing:");
|
||||||
|
// System.out.println(badHashing[0]);
|
||||||
|
// System.out.println("Getting with bad hashing:");
|
||||||
|
// System.out.println(badHashing[1]);
|
||||||
|
|
||||||
|
System.out.println("Inserting with id hashing:");
|
||||||
|
System.out.println(withId[0]);
|
||||||
|
System.out.println("Getting with id hashing:");
|
||||||
|
System.out.println(withId[1]);
|
||||||
|
|
||||||
|
System.out.println("Inserting with id and name hashing:");
|
||||||
|
System.out.println(withIdAndName[0]);
|
||||||
|
System.out.println("Getting with id and name hashing:");
|
||||||
|
System.out.println(withIdAndName[1]);
|
||||||
|
|
||||||
|
System.out.println("Inserting with Objects hashing:");
|
||||||
|
System.out.println(withObjects[0]);
|
||||||
|
System.out.println("Getting with Objects hashing:");
|
||||||
|
System.out.println(withObjects[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String randomName() {
|
||||||
|
return names[random.nextInt(2)];
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Member> Duration[] testDuration(Supplier<T> factory) {
|
||||||
|
HashMap<T, String> map = new HashMap<>();
|
||||||
|
Stopwatch stopwatch = Stopwatch.createUnstarted();
|
||||||
|
|
||||||
|
stopwatch.start();
|
||||||
|
for(int i = 0; i < SAMPLES; i++) {
|
||||||
|
T member = factory.get();
|
||||||
|
member.id = i;
|
||||||
|
member.name = randomName();
|
||||||
|
map.put(member, member.name);
|
||||||
|
}
|
||||||
|
stopwatch.stop();
|
||||||
|
Duration elapsedInserting = stopwatch.elapsed();
|
||||||
|
stopwatch.reset();
|
||||||
|
|
||||||
|
stopwatch.start();
|
||||||
|
for (T key : map.keySet()) {
|
||||||
|
map.get(key);
|
||||||
|
}
|
||||||
|
stopwatch.stop();
|
||||||
|
Duration elapsedGetting = stopwatch.elapsed();
|
||||||
|
stopwatch.reset();
|
||||||
|
|
||||||
|
return new Duration[]{elapsedInserting, elapsedGetting};
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,7 @@ public class JavaRMIIntegrationTest {
|
|||||||
MessengerServiceImpl server = new MessengerServiceImpl();
|
MessengerServiceImpl server = new MessengerServiceImpl();
|
||||||
server.createStubAndBind();
|
server.createStubAndBind();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
fail("Exception Occurred");
|
fail("Exception Occurred: " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,11 +34,9 @@ public class JavaRMIIntegrationTest {
|
|||||||
|
|
||||||
String expectedMessage = "Server Message";
|
String expectedMessage = "Server Message";
|
||||||
assertEquals(responseMessage, expectedMessage);
|
assertEquals(responseMessage, expectedMessage);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | NotBoundException e) {
|
||||||
fail("Exception Occurred");
|
fail("Exception Occurred: " + e);
|
||||||
} catch (NotBoundException nb) {
|
};
|
||||||
fail("Exception Occurred");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -47,3 +47,4 @@ Available commands (assumes httpie - https://github.com/jkbrzt/httpie):
|
|||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
- [Supercharge Java Authentication with JSON Web Tokens (JWTs)](https://www.baeldung.com/java-json-web-tokens-jjwt)
|
- [Supercharge Java Authentication with JSON Web Tokens (JWTs)](https://www.baeldung.com/java-json-web-tokens-jjwt)
|
||||||
|
- [Decode a JWT Token in Java](https://www.baeldung.com/java-jwt-token-decode)
|
||||||
|
@ -41,6 +41,12 @@
|
|||||||
<artifactId>jjwt</artifactId>
|
<artifactId>jjwt</artifactId>
|
||||||
<version>${jjwt.version}</version>
|
<version>${jjwt.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package io.jsonwebtoken.jjwtfun.util;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator;
|
||||||
|
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
import static io.jsonwebtoken.SignatureAlgorithm.HS256;
|
||||||
|
|
||||||
|
public class JWTDecoderUtil {
|
||||||
|
|
||||||
|
public static String decodeJWTToken(String token) {
|
||||||
|
Base64.Decoder decoder = Base64.getDecoder();
|
||||||
|
|
||||||
|
String[] chunks = token.split("\\.");
|
||||||
|
|
||||||
|
String header = new String(decoder.decode(chunks[0]));
|
||||||
|
String payload = new String(decoder.decode(chunks[1]));
|
||||||
|
|
||||||
|
return header + " " + payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decodeJWTToken(String token, String secretKey) throws Exception {
|
||||||
|
Base64.Decoder decoder = Base64.getDecoder();
|
||||||
|
|
||||||
|
String[] chunks = token.split("\\.");
|
||||||
|
|
||||||
|
String header = new String(decoder.decode(chunks[0]));
|
||||||
|
String payload = new String(decoder.decode(chunks[1]));
|
||||||
|
|
||||||
|
String tokenWithoutSignature = chunks[0] + "." + chunks[1];
|
||||||
|
String signature = chunks[2];
|
||||||
|
|
||||||
|
SignatureAlgorithm sa = HS256;
|
||||||
|
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), sa.getJcaName());
|
||||||
|
|
||||||
|
DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec);
|
||||||
|
|
||||||
|
if (!validator.isValid(tokenWithoutSignature, signature)) {
|
||||||
|
throw new Exception("Could not verify JWT token integrity!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return header + " " + payload;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package io.jsonwebtoken.jjwtfun.util;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
class JWTDecoderUtilUnitTest {
|
||||||
|
|
||||||
|
private final static String SIMPLE_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9";
|
||||||
|
private final static String SIGNED_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.qH7Zj_m3kY69kxhaQXTa-ivIpytKXXjZc1ZSmapZnGE";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenSimpleToken_whenDecoding_thenStringOfHeaderPayloadAreReturned() {
|
||||||
|
assertThat(JWTDecoderUtil.decodeJWTToken(SIMPLE_TOKEN))
|
||||||
|
.contains(SignatureAlgorithm.HS256.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenSignedToken_whenDecodingWithInvalidSecret_thenIntegrityIsNotValidated() {
|
||||||
|
assertThatThrownBy(() -> JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "BAD_SECRET"))
|
||||||
|
.hasMessage("Could not verify JWT token integrity!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenSignedToken_whenDecodingWithValidSecret_thenIntegrityIsValidated() throws Exception {
|
||||||
|
assertThat(JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "MySecretKey"))
|
||||||
|
.contains("Baeldung User");
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ It contains the code of a simple API for some CRUD operations built using Spring
|
|||||||
|
|
||||||
- Maven
|
- Maven
|
||||||
- JDK 8
|
- JDK 8
|
||||||
- MongoDB
|
- MongoDB (Note: for the Write Extracted Data to a File Using JMeter example MongoDB is not required)
|
||||||
|
|
||||||
### Running
|
### Running
|
||||||
|
|
||||||
@ -36,6 +36,14 @@ Or create a new one via a POST:
|
|||||||
$ curl -X POST -H "Content-Type:application/json" -d '{ "firstName" : "Dassi", "lastName" : "Orleando", "phoneNumber": "+237 545454545", "email": "mymail@yahoo.fr" }' localhost:8080/students
|
$ curl -X POST -H "Content-Type:application/json" -d '{ "firstName" : "Dassi", "lastName" : "Orleando", "phoneNumber": "+237 545454545", "email": "mymail@yahoo.fr" }' localhost:8080/students
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Available UUID API
|
||||||
|
|
||||||
|
You can view the test response using curl:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ curl localhost:8080/api/uuid
|
||||||
|
```
|
||||||
|
|
||||||
Now with default configurations it will be available at: [http://localhost:8080](http://localhost:8080)
|
Now with default configurations it will be available at: [http://localhost:8080](http://localhost:8080)
|
||||||
|
|
||||||
Enjoy it :)
|
Enjoy it :)
|
||||||
@ -44,3 +52,4 @@ Enjoy it :)
|
|||||||
|
|
||||||
- [Intro to Performance Testing using JMeter](https://www.baeldung.com/jmeter)
|
- [Intro to Performance Testing using JMeter](https://www.baeldung.com/jmeter)
|
||||||
- [Configure Jenkins to Run and Show JMeter Tests](https://www.baeldung.com/jenkins-and-jmeter)
|
- [Configure Jenkins to Run and Show JMeter Tests](https://www.baeldung.com/jenkins-and-jmeter)
|
||||||
|
- [Write Extracted Data to a File Using JMeter](https://www.baeldung.com/jmeter-write-to-file)
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.controller;
|
||||||
|
|
||||||
|
import com.baeldung.model.Response;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class RetrieveUuidController {
|
||||||
|
|
||||||
|
@GetMapping("/api/uuid")
|
||||||
|
public Response uuid() {
|
||||||
|
return new Response(format("Test message... %s.", UUID.randomUUID()));
|
||||||
|
}
|
||||||
|
}
|
40
jmeter/src/main/java/com/baeldung/model/Response.java
Normal file
40
jmeter/src/main/java/com/baeldung/model/Response.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung.model;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Response {
|
||||||
|
private Instant timestamp;
|
||||||
|
private UUID uuid;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public Response(String message) {
|
||||||
|
this.timestamp = Instant.now();
|
||||||
|
this.uuid = UUID.randomUUID();
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(Instant timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUuid(UUID uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
124
jmeter/src/main/resources/FileExtractionExample.jmx
Normal file
124
jmeter/src/main/resources/FileExtractionExample.jmx
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.1">
|
||||||
|
<hashTree>
|
||||||
|
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
|
||||||
|
<stringProp name="TestPlan.comments">To run this test plan you must also be running the Spring application "JmeterApplication" That can be found in this directory</stringProp>
|
||||||
|
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||||
|
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
|
||||||
|
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||||
|
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||||
|
<collectionProp name="Arguments.arguments"/>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||||
|
</TestPlan>
|
||||||
|
<hashTree>
|
||||||
|
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
|
||||||
|
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||||
|
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||||
|
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||||
|
<stringProp name="LoopController.loops">1</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="ThreadGroup.num_threads">1</stringProp>
|
||||||
|
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
|
||||||
|
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||||
|
<stringProp name="ThreadGroup.duration"></stringProp>
|
||||||
|
<stringProp name="ThreadGroup.delay"></stringProp>
|
||||||
|
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
|
||||||
|
</ThreadGroup>
|
||||||
|
<hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Call GET Test endpoint " enabled="true">
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||||
|
<collectionProp name="Arguments.arguments"/>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/api/test</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree>
|
||||||
|
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor" enabled="true">
|
||||||
|
<stringProp name="JSONPostProcessor.referenceNames">message</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.jsonPathExprs">$.message</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.match_numbers">1</stringProp>
|
||||||
|
<boolProp name="JSONPostProcessor.compute_concat">true</boolProp>
|
||||||
|
<stringProp name="JSONPostProcessor.defaultValues">NOT_FOUND</stringProp>
|
||||||
|
</JSONPostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<BeanShellPostProcessor guiclass="TestBeanGUI" testclass="BeanShellPostProcessor" testname="Response to file using BeanShell PostProcessor" enabled="true">
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
<stringProp name="parameters"></stringProp>
|
||||||
|
<boolProp name="resetInterpreter">false</boolProp>
|
||||||
|
<stringProp name="script">FileWriter fWriter = new FileWriter("<path>/result.txt", true);
|
||||||
|
BufferedWriter buff = new BufferedWriter(fWriter);
|
||||||
|
|
||||||
|
buff.write("Response Code : " + ctx.getPreviousResult().getResponseCode());
|
||||||
|
buff.write(System.getProperty("line.separator"));
|
||||||
|
buff.write("Response Headers : " + ctx.getPreviousResult().getResponseHeaders());
|
||||||
|
buff.write(System.getProperty("line.separator"));
|
||||||
|
buff.write("Response Body : " + new String(ctx.getPreviousResult().getResponseData()));
|
||||||
|
|
||||||
|
buff.write("More complex extraction : " + vars.get("message"));
|
||||||
|
|
||||||
|
buff.close();
|
||||||
|
fWriter.close();</stringProp>
|
||||||
|
</BeanShellPostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<ResultSaver guiclass="ResultSaverGui" testclass="ResultSaver" testname="Response to file using file write Listener" enabled="true">
|
||||||
|
<stringProp name="FileSaver.filename">response</stringProp>
|
||||||
|
<boolProp name="FileSaver.errorsonly">false</boolProp>
|
||||||
|
<boolProp name="FileSaver.successonly">false</boolProp>
|
||||||
|
<boolProp name="FileSaver.skipsuffix">false</boolProp>
|
||||||
|
<boolProp name="FileSaver.skipautonumber">false</boolProp>
|
||||||
|
</ResultSaver>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
|
||||||
|
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||||
|
<objProp>
|
||||||
|
<name>saveConfig</name>
|
||||||
|
<value class="SampleSaveConfiguration">
|
||||||
|
<time>true</time>
|
||||||
|
<latency>true</latency>
|
||||||
|
<timestamp>true</timestamp>
|
||||||
|
<success>true</success>
|
||||||
|
<label>true</label>
|
||||||
|
<code>true</code>
|
||||||
|
<message>true</message>
|
||||||
|
<threadName>true</threadName>
|
||||||
|
<dataType>true</dataType>
|
||||||
|
<encoding>false</encoding>
|
||||||
|
<assertions>true</assertions>
|
||||||
|
<subresults>true</subresults>
|
||||||
|
<responseData>false</responseData>
|
||||||
|
<samplerData>false</samplerData>
|
||||||
|
<xml>false</xml>
|
||||||
|
<fieldNames>true</fieldNames>
|
||||||
|
<responseHeaders>false</responseHeaders>
|
||||||
|
<requestHeaders>false</requestHeaders>
|
||||||
|
<responseDataOnError>false</responseDataOnError>
|
||||||
|
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||||
|
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||||
|
<bytes>true</bytes>
|
||||||
|
<sentBytes>true</sentBytes>
|
||||||
|
<url>true</url>
|
||||||
|
<threadCounts>true</threadCounts>
|
||||||
|
<idleTime>true</idleTime>
|
||||||
|
<connectTime>true</connectTime>
|
||||||
|
</value>
|
||||||
|
</objProp>
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
</ResultCollector>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
</hashTree>
|
||||||
|
</hashTree>
|
||||||
|
</jmeterTestPlan>
|
35
jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java
Normal file
35
jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class JmeterIntegrationTest {
|
||||||
|
|
||||||
|
MockMvc mvc;
|
||||||
|
|
||||||
|
public JmeterIntegrationTest(WebApplicationContext wac) {
|
||||||
|
this.mvc = MockMvcBuilders.webAppContextSetup(wac).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingUUIDController_thenWeShouldRecieveRandomizedResponse() throws Exception {
|
||||||
|
MockHttpServletResponse response = mvc.perform(get("/api/uuid"))
|
||||||
|
.andDo(print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andReturn()
|
||||||
|
.getResponse();
|
||||||
|
|
||||||
|
assertThat(response.getContentAsString())
|
||||||
|
.contains("Test message...");
|
||||||
|
}
|
||||||
|
}
|
13
kubernetes/k8s-intro/README.md
Normal file
13
kubernetes/k8s-intro/README.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Kubernetes Java API Sample Code
|
||||||
|
|
||||||
|
This module contains sample code used to show how to use the Kubernetes client Java API.
|
||||||
|
|
||||||
|
Before running those samples, make sure that your environment is correctly configured to access
|
||||||
|
a working Kubernetes cluster.
|
||||||
|
|
||||||
|
An easy way to check that everything is working as expected is issuing any *kubectl get* command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ kubectl get nodes
|
||||||
|
```
|
||||||
|
If you get a valid response, then you're good to go.
|
41
kubernetes/k8s-intro/pom.xml
Normal file
41
kubernetes/k8s-intro/pom.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<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>kubernetes-parent</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>k8s-intro</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.kubernetes</groupId>
|
||||||
|
<artifactId>client-java</artifactId>
|
||||||
|
<version>11.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.2.3</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<!-- http://maven.apache.org/plugins/maven-compiler-plugin/ -->
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
import io.kubernetes.client.openapi.ApiCallback;
|
||||||
|
import io.kubernetes.client.openapi.ApiException;
|
||||||
|
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||||
|
import okhttp3.Call;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ApiInvoker<R> {
|
||||||
|
Call apply(CoreV1Api api, ApiCallback<R> callback) throws ApiException;
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.kubernetes.client.openapi.ApiCallback;
|
||||||
|
import io.kubernetes.client.openapi.ApiException;
|
||||||
|
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||||
|
import okhttp3.Call;
|
||||||
|
|
||||||
|
public class AsyncHelper<R> implements ApiCallback<R> {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AsyncHelper.class);
|
||||||
|
|
||||||
|
private CoreV1Api api;
|
||||||
|
private CompletableFuture<R> callResult;
|
||||||
|
|
||||||
|
private AsyncHelper(CoreV1Api api) {
|
||||||
|
this.api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> CompletableFuture<T> doAsync(CoreV1Api api, ApiInvoker<T> invoker) {
|
||||||
|
|
||||||
|
AsyncHelper<T> p = new AsyncHelper<>(api);
|
||||||
|
return p.execute(invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<R> execute( ApiInvoker<R> invoker) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
callResult = new CompletableFuture<>();
|
||||||
|
log.info("[I38] Calling API...");
|
||||||
|
final Call call = invoker.apply(api,this);
|
||||||
|
log.info("[I41] API Succesfully invoked: method={}, url={}",
|
||||||
|
call.request().method(),
|
||||||
|
call.request().url());
|
||||||
|
return callResult;
|
||||||
|
}
|
||||||
|
catch(ApiException aex) {
|
||||||
|
callResult.completeExceptionally(aex);
|
||||||
|
return callResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(ApiException e, int statusCode, Map<String, List<String>> responseHeaders) {
|
||||||
|
log.error("[E53] onFailure",e);
|
||||||
|
callResult.completeExceptionally(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(R result, int statusCode, Map<String, List<String>> responseHeaders) {
|
||||||
|
log.error("[E61] onSuccess: statusCode={}",statusCode);
|
||||||
|
callResult.complete(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUploadProgress(long bytesWritten, long contentLength, boolean done) {
|
||||||
|
log.info("[E61] onUploadProgress: bytesWritten={}, contentLength={}, done={}",bytesWritten,contentLength,done);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDownloadProgress(long bytesRead, long contentLength, boolean done) {
|
||||||
|
log.info("[E75] onDownloadProgress: bytesRead={}, contentLength={}, done={}",bytesRead,contentLength,done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
|
||||||
|
import io.kubernetes.client.openapi.ApiClient;
|
||||||
|
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||||
|
import io.kubernetes.client.openapi.models.V1NodeList;
|
||||||
|
import io.kubernetes.client.util.Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ListNodes {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
ApiClient client = Config.defaultClient();
|
||||||
|
CoreV1Api api = new CoreV1Api(client);
|
||||||
|
V1NodeList nodeList = api.listNode(null, null, null, null, null, null, null, null, 10, false);
|
||||||
|
nodeList.getItems()
|
||||||
|
.stream()
|
||||||
|
.forEach((node) -> System.out.println(node.getMetadata()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.kubernetes.client.openapi.ApiClient;
|
||||||
|
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||||
|
import io.kubernetes.client.openapi.models.V1NodeList;
|
||||||
|
import io.kubernetes.client.util.Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ListNodesAsync {
|
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(ListNodesAsync.class);
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
// Initial setup
|
||||||
|
ApiClient client = Config.defaultClient();
|
||||||
|
CoreV1Api api = new CoreV1Api(client);
|
||||||
|
|
||||||
|
// Start async call
|
||||||
|
CompletableFuture<V1NodeList> p = AsyncHelper.doAsync(api,(capi,cb) ->
|
||||||
|
capi.listNodeAsync(null, null, null, null, null, null, null, null, 10, false, cb)
|
||||||
|
);
|
||||||
|
|
||||||
|
p.thenAcceptAsync((nodeList) -> {
|
||||||
|
log.info("[I40] Processing results...");
|
||||||
|
nodeList.getItems()
|
||||||
|
.stream()
|
||||||
|
.forEach((node) -> System.out.println(node.getMetadata()));
|
||||||
|
});
|
||||||
|
|
||||||
|
log.info("[I46] Waiting results...");
|
||||||
|
p.get(10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.kubernetes.client.openapi.ApiClient;
|
||||||
|
import io.kubernetes.client.openapi.apis.CoreV1Api;
|
||||||
|
import io.kubernetes.client.openapi.models.V1NodeList;
|
||||||
|
import io.kubernetes.client.openapi.models.V1PodList;
|
||||||
|
import io.kubernetes.client.util.Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ListPodsPaged {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ListPodsPaged.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
ApiClient client = Config.defaultClient();
|
||||||
|
CoreV1Api api = new CoreV1Api(client);
|
||||||
|
String continuationToken = null;
|
||||||
|
int limit = 2; // Just for illustration purposes. Real world values would range from ~100 to ~1000/page
|
||||||
|
Long remaining = null;
|
||||||
|
do {
|
||||||
|
log.info("==========================================================================");
|
||||||
|
log.info("Retrieving data: continuationToken={}, remaining={}", continuationToken,remaining);
|
||||||
|
V1PodList items = api.listPodForAllNamespaces(null, continuationToken, null, null, limit, null, null, null, 10, false);
|
||||||
|
continuationToken = items.getMetadata().getContinue();
|
||||||
|
remaining = items.getMetadata().getRemainingItemCount();
|
||||||
|
items.getItems()
|
||||||
|
.stream()
|
||||||
|
.forEach((node) -> System.out.println(node.getMetadata()));
|
||||||
|
} while( continuationToken != null );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class ListNodesAsyncLiveTest {
|
||||||
|
@Test
|
||||||
|
void whenListNodes_thenSuccess() throws Exception {
|
||||||
|
ListNodesAsync.main(new String[] {});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class ListNodesLiveTest {
|
||||||
|
@Test
|
||||||
|
void whenListNodes_thenSuccess() throws Exception {
|
||||||
|
ListNodes.main(new String[] {});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.kubernetes.intro;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class ListPodsPagedLiveTest {
|
||||||
|
@Test
|
||||||
|
void whenListPodsPage_thenSuccess() throws Exception {
|
||||||
|
ListPodsPaged.main(new String[] {});
|
||||||
|
}
|
||||||
|
}
|
11
kubernetes/k8s-intro/src/test/resources/logback.xml
Normal file
11
kubernetes/k8s-intro/src/test/resources/logback.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="debug">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
13
kubernetes/pom.xml
Normal file
13
kubernetes/pom.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<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>
|
||||||
|
<artifactId>kubernetes-parent</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>k8s-intro</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
@ -7,5 +7,6 @@ This module contains articles about HTTP libraries.
|
|||||||
- [Jetty ReactiveStreams HTTP Client](https://www.baeldung.com/jetty-reactivestreams-http-client)
|
- [Jetty ReactiveStreams HTTP Client](https://www.baeldung.com/jetty-reactivestreams-http-client)
|
||||||
- [Decode an OkHttp JSON Response](https://www.baeldung.com/okhttp-json-response)
|
- [Decode an OkHttp JSON Response](https://www.baeldung.com/okhttp-json-response)
|
||||||
- [Retrofit 2 – Dynamic URL](https://www.baeldung.com/retrofit-dynamic-url)
|
- [Retrofit 2 – Dynamic URL](https://www.baeldung.com/retrofit-dynamic-url)
|
||||||
|
- [Adding Interceptors in OkHTTP](https://www.baeldung.com/java-okhttp-interceptors)
|
||||||
- More articles [[<-- prev]](/libraries-http)
|
- More articles [[<-- prev]](/libraries-http)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
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">
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>libraries-http-2</artifactId>
|
<artifactId>libraries-http-2</artifactId>
|
||||||
<name>libraries-http-2</name>
|
<name>libraries-http-2</name>
|
||||||
@ -13,12 +13,17 @@
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Dependencies for response decoder with okhttp -->
|
<!-- Dependencies for response decoder with okhttp -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup.okhttp3</groupId>
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
<artifactId>okhttp</artifactId>
|
<artifactId>okhttp</artifactId>
|
||||||
<version>${okhttp.version}</version>
|
<version>${okhttp.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
|
<artifactId>logging-interceptor</artifactId>
|
||||||
|
<version>${okhttp.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
@ -81,9 +86,9 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<okhttp.version>3.14.2</okhttp.version>
|
<okhttp.version>4.9.1</okhttp.version>
|
||||||
<gson.version>2.8.5</gson.version>
|
<gson.version>2.8.5</gson.version>
|
||||||
<mockwebserver.version>3.14.2</mockwebserver.version>
|
<mockwebserver.version>4.9.1</mockwebserver.version>
|
||||||
<jetty.httpclient.version>1.0.3</jetty.httpclient.version>
|
<jetty.httpclient.version>1.0.3</jetty.httpclient.version>
|
||||||
<jetty.server.version>9.4.19.v20190610</jetty.server.version>
|
<jetty.server.version>9.4.19.v20190610</jetty.server.version>
|
||||||
<rxjava2.version>2.2.11</rxjava2.version>
|
<rxjava2.version>2.2.11</rxjava2.version>
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.okhttp.interceptors;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import okhttp3.Interceptor;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class CacheControlResponeInterceptor implements Interceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response intercept(Chain chain) throws IOException {
|
||||||
|
Response response = chain.proceed(chain.request());
|
||||||
|
return response.newBuilder()
|
||||||
|
.header("Cache-Control", "no-store")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.okhttp.interceptors;
|
||||||
|
|
||||||
|
public class ErrorMessage {
|
||||||
|
|
||||||
|
private final int status;
|
||||||
|
private final String detail;
|
||||||
|
|
||||||
|
public ErrorMessage(int status, String detail) {
|
||||||
|
this.status = status;
|
||||||
|
this.detail = detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDetail() {
|
||||||
|
return detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.baeldung.okhttp.interceptors;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import okhttp3.Interceptor;
|
||||||
|
import okhttp3.MediaType;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
|
|
||||||
|
public class ErrorResponseInterceptor implements Interceptor {
|
||||||
|
|
||||||
|
public static final MediaType APPLICATION_JSON = MediaType.get("application/json; charset=utf-8");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response intercept(Chain chain) throws IOException {
|
||||||
|
Response response = chain.proceed(chain.request());
|
||||||
|
|
||||||
|
if(!response.isSuccessful()) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
String body = gson.toJson(new ErrorMessage(response.code(), "The response from the server was not OK"));
|
||||||
|
ResponseBody responseBody = ResponseBody.create(body, APPLICATION_JSON);
|
||||||
|
|
||||||
|
return response.newBuilder()
|
||||||
|
.body(responseBody)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.okhttp.interceptors;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import okhttp3.Interceptor;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class SimpleLoggingInterceptor implements Interceptor {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleLoggingInterceptor.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response intercept(Chain chain) throws IOException {
|
||||||
|
Request request = chain.request();
|
||||||
|
|
||||||
|
LOGGER.info("Intercepted headers: {} from URL: {}", request.headers(), request.url());
|
||||||
|
|
||||||
|
return chain.proceed(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package com.baeldung.okhttp.interceptors;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor;
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor.Level;
|
||||||
|
import okhttp3.mockwebserver.MockResponse;
|
||||||
|
import okhttp3.mockwebserver.MockWebServer;
|
||||||
|
|
||||||
|
public class InterceptorIntegrationTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public MockWebServer server = new MockWebServer();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSimpleLogginInterceptor_whenRequestSent_thenHeadersLogged() throws IOException {
|
||||||
|
server.enqueue(new MockResponse().setBody("Hello Baeldung Readers!"));
|
||||||
|
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.addNetworkInterceptor(new SimpleLoggingInterceptor())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(server.url("/greeting"))
|
||||||
|
.header("User-Agent", "A Baeldung Reader")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
assertEquals("Response code should be: ", 200, response.code());
|
||||||
|
assertEquals("Body should be: ", "Hello Baeldung Readers!", response.body().string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenResponseInterceptor_whenRequestSent_thenCacheControlSetToNoStore() throws IOException {
|
||||||
|
server.enqueue(new MockResponse().setBody("Hello Baeldung Readers!"));
|
||||||
|
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.addInterceptor(getHttpLogger())
|
||||||
|
.addInterceptor(new CacheControlResponeInterceptor())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(server.url("/greeting"))
|
||||||
|
.header("User-Agent", "A Baeldung Reader")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
assertEquals("Response code should be: ", 200, response.code());
|
||||||
|
assertEquals("Body should be: ", "Hello Baeldung Readers!", response.body().string());
|
||||||
|
assertEquals("Response cache-control should be", "no-store", response.header("Cache-Control"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenErrorResponseInterceptor_whenResponseIs500_thenBodyIsJsonWithStatus() throws IOException {
|
||||||
|
server.enqueue(new MockResponse().setResponseCode(500).setBody("Hello Baeldung Readers!"));
|
||||||
|
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.addInterceptor(getHttpLogger())
|
||||||
|
.addInterceptor(new ErrorResponseInterceptor())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(server.url("/greeting"))
|
||||||
|
.header("User-Agent", "A Baeldung Reader")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
assertEquals("Response code should be: ", 500, response.code());
|
||||||
|
assertEquals("Body should be: ", "{\"status\":500,\"detail\":\"The response from the server was not OK\"}",
|
||||||
|
response.body().string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpLoggingInterceptor getHttpLogger() {
|
||||||
|
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
|
||||||
|
logger.setLevel(Level.HEADERS);
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3
maven-modules/maven-plugins/jaxws/README.md
Normal file
3
maven-modules/maven-plugins/jaxws/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Generate WSDL Stubs with Maven](https://www.baeldung.com/maven-wsdl-stubs)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user