BAEL-5167: add sample key implementations and test the correct functionality and the performance of those keys in a HashMap (#11260)
This commit is contained in:
parent
5276659f6f
commit
7b47645746
|
@ -0,0 +1,6 @@
|
|||
## Java Collections Cookbooks and Examples
|
||||
|
||||
This module contains articles about Map data structures in Java.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Using a Custom Class as a Key in a Java HashMap](https://www.baeldung.com/custom-key-hashmap)
|
|
@ -0,0 +1,34 @@
|
|||
<?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-collections-maps-4</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-collections-maps-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>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M5</version>
|
||||
<configuration>
|
||||
<!-- those tests are not made for CI purposes, but for manual testing -->
|
||||
<groups>!performance</groups>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.maps;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class CoordinateKey {
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int hashCode;
|
||||
|
||||
public CoordinateKey(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.hashCode = Objects.hash(x, y);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
CoordinateKey that = (CoordinateKey) o;
|
||||
return x == that.x && y == that.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.hashCode;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.baeldung.maps;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class CoordinateMutableKey {
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
public CoordinateMutableKey(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
CoordinateMutableKey that = (CoordinateMutableKey) o;
|
||||
return x == that.x && y == that.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, y);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.maps;
|
||||
|
||||
public class CoordinateSlowKey extends CoordinateKey {
|
||||
|
||||
public CoordinateSlowKey(int x, int y) {
|
||||
super(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package com.baeldung.maps;
|
||||
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
public class CoordinateKeyUnitTest {
|
||||
|
||||
private Map<CoordinateKey, Color> pixels = new HashMap<>();
|
||||
|
||||
@Test
|
||||
void testOptimalKey() {
|
||||
// setup
|
||||
CoordinateKey coord = new CoordinateKey(1, 2);
|
||||
pixels.put(coord, Color.CYAN);
|
||||
// read out color correctly
|
||||
assertEquals(Color.CYAN, pixels.get(coord));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSlowKey() {
|
||||
// setup
|
||||
CoordinateKey coord = new CoordinateSlowKey(1, 2);
|
||||
pixels.put(coord, Color.CYAN);
|
||||
// read out color correctly
|
||||
assertEquals(Color.CYAN, pixels.get(coord));
|
||||
}
|
||||
|
||||
// Performance Test Parameters - change here
|
||||
private static final int MAX_X = 100;
|
||||
private static final int MAX_Y = 100;
|
||||
private static final int COUNT_OF_QUERIES = 1000;
|
||||
private static final int QUERY_X = 1;
|
||||
private static final int QUERY_Y = 1;
|
||||
|
||||
@Tag("performance")
|
||||
@Test
|
||||
void testKeyPerformance() {
|
||||
// generate some sample keys and values
|
||||
for (int x = 0; x < MAX_X; x++) {
|
||||
for (int y = 0; y < MAX_Y; y++) {
|
||||
pixels.put(new CoordinateKey(x, y), new Color(x % 255, y % 255, (x + y) % 255));
|
||||
}
|
||||
}
|
||||
// read out multiple times and measure time
|
||||
CoordinateKey coord = new CoordinateKey(QUERY_X, QUERY_Y);
|
||||
long t1 = System.currentTimeMillis();
|
||||
for (int i = 0; i < COUNT_OF_QUERIES; i++) {
|
||||
assertNotNull(pixels.get(coord));
|
||||
}
|
||||
long t2 = System.currentTimeMillis();
|
||||
System.out.printf("Optimal key performance: %d ms%n", t2 - t1);
|
||||
}
|
||||
|
||||
@Tag("performance")
|
||||
@Test
|
||||
void testSlowKeyPerformance() {
|
||||
// generate some sample keys and values
|
||||
for (int x = 0; x < MAX_X; x++) {
|
||||
for (int y = 0; y < MAX_Y; y++) {
|
||||
pixels.put(new CoordinateSlowKey(x, y), new Color(x % 255, y % 255, (x + y) % 255));
|
||||
}
|
||||
}
|
||||
// read out multiple times and measure time
|
||||
CoordinateKey coord = new CoordinateSlowKey(QUERY_X, QUERY_Y);
|
||||
long t1 = System.currentTimeMillis();
|
||||
for (int i = 0; i < COUNT_OF_QUERIES; i++) {
|
||||
assertNotNull(pixels.get(coord));
|
||||
}
|
||||
long t2 = System.currentTimeMillis();
|
||||
System.out.printf("Slow key performance: %d ms%n", t2 - t1);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.maps;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
public class CoordinateMutableKeyUnitTest {
|
||||
|
||||
@Test
|
||||
void testKeyMutable() {
|
||||
// setup
|
||||
Map<CoordinateMutableKey, Color> pixels = new HashMap<>();
|
||||
CoordinateMutableKey coord = new CoordinateMutableKey(1, 2);
|
||||
pixels.put(coord, Color.CYAN);
|
||||
// read out color correctly
|
||||
assertEquals(Color.CYAN, pixels.get(coord));
|
||||
// change key's hashcode should result in null value
|
||||
coord.setX(10);
|
||||
assertNull(pixels.get(coord));
|
||||
}
|
||||
|
||||
}
|
|
@ -38,6 +38,7 @@
|
|||
<module>core-java-collections-maps</module>
|
||||
<module>core-java-collections-maps-2</module>
|
||||
<module>core-java-collections-maps-3</module>
|
||||
<module>core-java-collections-maps-4</module>
|
||||
<module>core-java-concurrency-2</module>
|
||||
<module>core-java-concurrency-advanced</module>
|
||||
<module>core-java-concurrency-advanced-2</module>
|
||||
|
@ -138,4 +139,4 @@
|
|||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
|
Loading…
Reference in New Issue