From 0483aa0bba7f494372e9e9d757e6d44f4a3011bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Tue, 29 Sep 2020 12:04:38 +0200 Subject: [PATCH] make keys comparable --- .../datastructures/tiny/IndexedMapBase.java | 9 ++- .../xbib/datastructures/tiny/IndexedSet.java | 2 +- .../datastructures/tiny/IndexedSetBase.java | 5 ++ .../org/xbib/datastructures/tiny/TinyMap.java | 30 ++++++++- .../xbib/datastructures/tiny/TinyMapTest.java | 61 +++++++++++++++++++ gradle.properties | 2 +- 6 files changed, 103 insertions(+), 6 deletions(-) diff --git a/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedMapBase.java b/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedMapBase.java index 50ea014..d85aea3 100644 --- a/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedMapBase.java +++ b/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedMapBase.java @@ -174,7 +174,8 @@ public abstract class IndexedMapBase implements IndexedMap { return sb.append('}').toString(); } - private class ValuesView extends IndexedCollectionBase implements IndexedCollectionBase.NoAdditiveChange { + private class ValuesView extends IndexedCollectionBase + implements IndexedCollectionBase.NoAdditiveChange { @Override public V getEntryAt(int index) { @@ -208,7 +209,8 @@ public abstract class IndexedMapBase implements IndexedMap { } } - private class KeysView extends IndexedSetBase implements IndexedCollectionBase.NoAdditiveChange { + private class KeysView extends IndexedSetBase + implements IndexedCollectionBase.NoAdditiveChange { @Override public int getIndex(Object key) { @@ -247,7 +249,8 @@ public abstract class IndexedMapBase implements IndexedMap { } } - private class EntriesView extends IndexedSetBase> implements IndexedCollectionBase.NoAdditiveChange> { + private class EntriesView extends IndexedSetBase> + implements IndexedCollectionBase.NoAdditiveChange> { @Override public int getIndex(Object key) { diff --git a/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedSet.java b/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedSet.java index ef9dbe8..c020f29 100644 --- a/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedSet.java +++ b/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedSet.java @@ -2,5 +2,5 @@ package org.xbib.datastructures.tiny; import java.util.Set; -public interface IndexedSet extends Set, IndexedCollection { +public interface IndexedSet extends Set, IndexedCollection, Comparable> { } diff --git a/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedSetBase.java b/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedSetBase.java index ba12938..dd97f1e 100644 --- a/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedSetBase.java +++ b/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/IndexedSetBase.java @@ -31,4 +31,9 @@ public abstract class IndexedSetBase extends IndexedCollectionBase impleme } return hash; } + + @Override + public int compareTo(IndexedSet indexedSet) { + return Integer.compare(hashCode(), indexedSet.hashCode()); + } } diff --git a/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/TinyMap.java b/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/TinyMap.java index 031b89e..cc8195b 100644 --- a/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/TinyMap.java +++ b/datastructures-tiny/src/main/java/org/xbib/datastructures/tiny/TinyMap.java @@ -41,7 +41,9 @@ public abstract class TinyMap extends IndexedMapBase { } }; - public static class Builder extends IndexedMapBase { + public static class Builder + extends IndexedMapBase + implements Comparable> { private final TinySet.Builder keys; @@ -155,6 +157,32 @@ public abstract class TinyMap extends IndexedMapBase { Arrays.fill(values, 0, keys.rawSize(), null); keys.clear(); } + + @Override + public int hashCode() { + return keys.hashCode() ^ Arrays.hashCode(values); + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Builder)) { + return false; + } + Builder other = (Builder) obj; + if (!keySet().equals(other.keySet())) { + return false; + } + return Arrays.equals(values, other.values); + } + + @Override + public int compareTo(Builder o) { + return keySet().compareTo(o.keySet()); + } } public static class SizeAny extends TinyMap { diff --git a/datastructures-tiny/src/test/java/org/xbib/datastructures/tiny/TinyMapTest.java b/datastructures-tiny/src/test/java/org/xbib/datastructures/tiny/TinyMapTest.java index 41b1f2b..dcaa9d6 100644 --- a/datastructures-tiny/src/test/java/org/xbib/datastructures/tiny/TinyMapTest.java +++ b/datastructures-tiny/src/test/java/org/xbib/datastructures/tiny/TinyMapTest.java @@ -5,13 +5,16 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import java.util.AbstractMap; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -159,6 +162,64 @@ public class TinyMapTest { assertEquals(99999, map.get("aaa99999")); } + @Test + public void testCompareKeys() { + TinyMap.Builder builder1 = TinyMap.builder(); + for (int i = 0; i < 100; i++) { + builder1.put("" + i, i); + } + TinyMap.Builder builder2 = TinyMap.builder(); + for (int i = 0; i < 100; i++) { + builder2.put("" + i, i); + } + assertEquals(0, builder1.keySet().compareTo(builder2.keySet())); + } + + @Test + public void testCompareBuilder() { + TinyMap.Builder builder1 = TinyMap.builder(); + for (int i = 0; i < 100; i++) { + builder1.put("" + i, i); + } + TinyMap.Builder builder2 = TinyMap.builder(); + for (int i = 0; i < 100; i++) { + builder2.put("" + i, i); + } + assertEquals(0, builder1.compareTo(builder2)); + } + + @Test + public void testFailCompareBuilder() { + TinyMap.Builder builder1 = TinyMap.builder(); + for (int i = 0; i < 100; i++) { + builder1.put("" + i, i); + } + TinyMap.Builder builder2 = TinyMap.builder(); + for (int i = 0; i < 101; i++) { + builder2.put("" + i, i); + } + assertNotEquals(0, builder1.compareTo(builder2)); + } + + @Test + public void testSortKeys() { + TinyMap.Builder builder = TinyMap.builder(); + for (int i = 0; i < 100; i++) { + builder.put("" + i, i); + } + assertEquals(100, builder.keySet().stream().sorted().count()); + } + + @Test + public void testSortEntries() { + TinyMap.Builder builder = TinyMap.builder(); + for (int i = 0; i < 100; i++) { + builder.put("" + i, i); + } + Set> set = new HashSet<>(builder.entrySet()); + assertEquals(100, set.size()); + } + private void testCount(int count, boolean withNull) { TinyMap.Builder builder = TinyMap.builder(); LinkedHashMap expectedMap = new LinkedHashMap<>(); diff --git a/gradle.properties b/gradle.properties index 14946aa..3786e99 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = org.xbib name = datastructures -version = 0.0.1 +version = 0.0.2 gradle.wrapper.version = 6.6.1