Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -5,7 +5,7 @@ This module contains articles about Java 10 core features
|
||||
### Relevant Articles:
|
||||
|
||||
- [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)
|
||||
- [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)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
## Relevant Articles:
|
||||
|
||||
|
||||
- [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:
|
||||
|
||||
- [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)
|
||||
- [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 – 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:
|
||||
|
||||
- [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)
|
||||
- [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)
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
This module contains articles about Java Character Class
|
||||
|
||||
### 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
-5
@@ -26,7 +26,7 @@ public class Product {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public Product addTagsOfOtherProdcut(Product product) {
|
||||
public Product addTagsOfOtherProduct(Product product) {
|
||||
this.tags.addAll(product.getTags());
|
||||
return this;
|
||||
}
|
||||
@@ -100,11 +100,11 @@ public class Product {
|
||||
HashMap<String, Product> productsByName = new HashMap<>();
|
||||
Product eBike2 = new Product("E-Bike", "A bike with a battery");
|
||||
eBike2.getTags().add("sport");
|
||||
productsByName.merge("E-Bike", eBike2, Product::addTagsOfOtherProdcut);
|
||||
productsByName.merge("E-Bike", eBike2, Product::addTagsOfOtherProduct);
|
||||
|
||||
//Prior to Java 8:
|
||||
if(productsByName.containsKey("E-Bike")) {
|
||||
productsByName.get("E-Bike").addTagsOfOtherProdcut(eBike2);
|
||||
productsByName.get("E-Bike").addTagsOfOtherProduct(eBike2);
|
||||
} else {
|
||||
productsByName.put("E-Bike", eBike2);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ public class Product {
|
||||
|
||||
productsByName.compute("E-Bike", (k,v) -> {
|
||||
if(v != null) {
|
||||
return v.addTagsOfOtherProdcut(eBike2);
|
||||
return v.addTagsOfOtherProduct(eBike2);
|
||||
} else {
|
||||
return eBike2;
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public class Product {
|
||||
|
||||
//Prior to Java 8:
|
||||
if(productsByName.containsKey("E-Bike")) {
|
||||
productsByName.get("E-Bike").addTagsOfOtherProdcut(eBike2);
|
||||
productsByName.get("E-Bike").addTagsOfOtherProduct(eBike2);
|
||||
} else {
|
||||
productsByName.put("E-Bike", eBike2);
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ This module contains articles about Map data structures in Java.
|
||||
- [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps)
|
||||
- [The Map.computeIfAbsent() Method](https://www.baeldung.com/java-map-computeifabsent)
|
||||
- [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap)
|
||||
- [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>${jmh-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
||||
+39
@@ -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));
|
||||
}
|
||||
}
|
||||
+49
@@ -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());
|
||||
}
|
||||
}
|
||||
+192
@@ -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=
|
||||
@@ -17,7 +17,7 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.baeldung.servicemodule</groupId>
|
||||
<artifactId>servicemodule</artifactId>
|
||||
<artifactId>servicemodule2</artifactId>
|
||||
<version>${servicemodule.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -41,4 +41,4 @@
|
||||
<providermodule.version>1.0</providermodule.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -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)
|
||||
- [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)
|
||||
- [Guide to Implementing the compareTo Method](https://www.baeldung.com/java-compareto)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-lang-2)
|
||||
|
||||
@@ -4,6 +4,5 @@
|
||||
|
||||
### 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)
|
||||
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
|
||||
|
||||
+26
@@ -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;
|
||||
}
|
||||
}
|
||||
+25
@@ -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,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
|
||||
@@ -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>
|
||||
+19
@@ -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:
|
||||
|
||||
- [Kotlin vs Java](https://www.baeldung.com/kotlin/kotlin-vs-java)
|
||||
- [Kotlin vs Java](https://www.baeldung.com/kotlin/vs-java)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.baeldung.map.hashing;
|
||||
|
||||
class Member {
|
||||
Integer id;
|
||||
String name;
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.baeldung.map.hashing;
|
||||
|
||||
public class MemberWithBadHashing extends Member {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
}
|
||||
+18
@@ -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;
|
||||
}
|
||||
}
|
||||
+23
@@ -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};
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user