Remove raw use of parameterized in ValueSortMap and provide unit test (#90)
diff --git a/opennlp-similarity/src/main/java/opennlp/tools/similarity/apps/utils/ValueSortMap.java b/opennlp-similarity/src/main/java/opennlp/tools/similarity/apps/utils/ValueSortMap.java
index 0788952..fc2fdeb 100644
--- a/opennlp-similarity/src/main/java/opennlp/tools/similarity/apps/utils/ValueSortMap.java
+++ b/opennlp-similarity/src/main/java/opennlp/tools/similarity/apps/utils/ValueSortMap.java
@@ -25,12 +25,13 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
/**
- * This class is used to show how you can sort a java.uti.Map for values. This
- * also takes care of null and duplicate values present in the map.
+ * Sorts a {@link Map} by its values.
+ * Also takes care of {@code null} and duplicate values present in the map.
*/
public class ValueSortMap {
@@ -112,18 +113,17 @@
int iSize = inMap.size();
// Create new LinkedHashMap that need to be returned
- LinkedHashMap sortedMap = new LinkedHashMap(iSize);
+ LinkedHashMap<K, V> sortedMap = new LinkedHashMap<>(iSize);
- Collection values = inMap.values();
- ArrayList valueList = new ArrayList(values); // To get List of all values in
+ Collection<V> values = inMap.values();
+ List<V> valueList = new ArrayList<>(values); // To get List of all values in
// passed Map
- HashSet distinctValues = new HashSet(values); // To know the distinct values
+ Set<V> distinctValues = new HashSet<>(values); // To know the distinct values
// in passed Map
// Handling for null values: remove them from the list that will be used
// for sorting
- int iNullValueCount = 0; // Total number of null values present in passed
- // Map
+ int iNullValueCount = 0; // Total number of null values present in passed Map
if (distinctValues.contains(null)) {
distinctValues.remove(null);
for (int i = 0; i < valueList.size(); i++) {
@@ -131,7 +131,6 @@
valueList.remove(i);
iNullValueCount++;
i--;
- continue;
}
}
}
@@ -144,11 +143,11 @@
} else if (ascendingOrder) {
// If Boolean ascendingOrder is not null and is true, sort values in
// ascending order
- Collections.sort(valueList);
+ valueList.sort(comparator);
} else {
// If Boolean ascendingOrder is not null and is false, sort values in
// descending order
- Collections.sort(valueList);
+ valueList.sort(comparator);
Collections.reverse(valueList);
}
@@ -158,11 +157,12 @@
if (iSize != (distinctValues.size() + iNullValueCount))
bAllDistinct = false;
- Object key, value, sortedValue;
- Set keySet;
- Iterator itKeyList;
- HashMap hmTmpMap = new HashMap(iSize);
- HashMap hmNullValueMap = new HashMap();
+ K key;
+ V value, sortedValue;
+ Set<K> keySet;
+ Iterator<K> itKeyList;
+ Map<K, V> hmTmpMap = new HashMap<>(iSize);
+ Map<K, V> hmNullValueMap = new HashMap<>();
if (bAllDistinct) {
// There are no multiple same values of the passed map (without considering null)
@@ -173,11 +173,9 @@
value = inMap.get(key);
if (value != null)
- hmTmpMap.put(value, key); // Prepare new temp HashMap with value=key
- // combination
+ hmTmpMap.put((K) value, (V) key); // Prepare new temp HashMap with value=key combination
else
- hmNullValueMap.put(key, value); // Keep all null values in a new temp
- // Map
+ hmNullValueMap.put(key, value); // Keep all null values in a new temp Map
}
if (ascendingOrder != null && !ascendingOrder) {
@@ -187,9 +185,9 @@
}
// Put all not null values in returning LinkedHashMap
- for (Object o : valueList) {
+ for (V o : valueList) {
value = o;
- key = hmTmpMap.get(value);
+ key = (K) hmTmpMap.get((V) value);
sortedMap.put(key, value);
}
@@ -207,11 +205,9 @@
value = inMap.get(key);
if (value != null)
- hmTmpMap.put(key, value); // Prepare new temp HashMap with key=value
- // combination
+ hmTmpMap.put(key, value); // Prepare new temp HashMap with key=value combination
else
- hmNullValueMap.put(key, value); // Keep all null values in a new temp
- // Map
+ hmNullValueMap.put(key, value); // Keep all null values in a new temp Map
}
if (ascendingOrder != null && !ascendingOrder) {
@@ -221,7 +217,7 @@
}
// Put all not null values in returning LinkedHashMap
- for (Object o : valueList) {
+ for (V o : valueList) {
sortedValue = o;
// Search this value in temp HashMap and if found remove it
@@ -247,39 +243,4 @@
return sortedMap;
}
- public static void main(String[] args) {
- HashMap hmValue = new HashMap();
-
- hmValue.put("ZNU", "Zuki Ndulo");
- hmValue.put("YSH", "Yogesh Sharma");
- hmValue.put("HHU", "Hiram Hugesh");
- hmValue.put("MLE", "Marry Lee");
- hmValue.put("FST", "Faran Stott");
- hmValue.put("HET", null);
- hmValue.put("SID", null);
- hmValue.put("AFR", "Alice Fryer");
- hmValue.put("KIQ", null);
- hmValue.put("JBE", "Jim Bell");
- hmValue.put("MAU", null);
- hmValue.put("KAE", null);
- hmValue.put("JBA", "Jim Bader");
- hmValue.put("RAN", "Robert Anthony");
- hmValue.put("CLE", "Carole Lee");
- hmValue.put("JMD", "Jim Bader");
- hmValue.put("ALI", null);
- hmValue.put("GMI", "Gracia Millan");
- hmValue.put("MAL", "Marry Lee");
- hmValue.put("CLE", "Carole Lee");
- hmValue.put("APE", "Annin Peck");
- hmValue.put("HUA", null);
-
- System.out.println("============ Before Sorting ===============");
- System.out.println(hmValue);
-
- // Call method to sort the hmValue Map for it's Values
- Map sortedMap = sortMapByValue(hmValue, false);
-
- System.out.println("============ After Sorting ===============");
- System.out.println(sortedMap);
- }
}
diff --git a/opennlp-similarity/src/test/java/opennlp/tools/similarity/apps/utils/ValueSortMapTest.java b/opennlp-similarity/src/test/java/opennlp/tools/similarity/apps/utils/ValueSortMapTest.java
new file mode 100644
index 0000000..45af6f3
--- /dev/null
+++ b/opennlp-similarity/src/test/java/opennlp/tools/similarity/apps/utils/ValueSortMapTest.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package opennlp.tools.similarity.apps.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ValueSortMapTest {
+
+ private Map<String, String> hmValue;
+
+ @BeforeEach
+ public void setup() {
+ hmValue = new HashMap<>();
+
+ hmValue.put("ZNU", "Zuki Ndulo");
+ hmValue.put("YSH", "Yogesh Sharma");
+ hmValue.put("HHU", "Hiram Hugesh");
+ hmValue.put("MLE", "Marry Lee");
+ hmValue.put("FST", "Faran Stott");
+ hmValue.put("HET", null);
+ hmValue.put("SID", null);
+ hmValue.put("AFR", "Alice Fryer");
+ hmValue.put("KIQ", null);
+ hmValue.put("JBE", "Jim Bell");
+ hmValue.put("MAU", null);
+ hmValue.put("KAE", null);
+ hmValue.put("JBA", "Jim Bader");
+ hmValue.put("RAN", "Robert Anthony");
+ hmValue.put("CLE", "Carole Lee");
+ hmValue.put("JMD", "Jim Bader");
+ hmValue.put("ALI", null);
+ hmValue.put("GMI", "Gracia Millan");
+ hmValue.put("MAL", "Marry Lee");
+ hmValue.put("CLE", "Carole Lee"); // duplicate on purpose !
+ hmValue.put("APE", "Annin Peck");
+ hmValue.put("HUA", null);
+ }
+
+ @Test
+ public void testSortMapByValueWithImplicitOrder() {
+ // Implicit: ascending
+ testSortMapByValue(null);
+ }
+
+ @ParameterizedTest
+ @ValueSource(booleans = {false, true})
+ public void testSortMapByValueWithExplicitOrder(boolean ascending) {
+ testSortMapByValue(ascending);
+ }
+
+ private void testSortMapByValue(Boolean ascending) {
+ final Map<String, String> sortedMap;
+ // Test
+ if (ascending != null) {
+ sortedMap = ValueSortMap.sortMapByValue(hmValue, ascending);
+ } else {
+ sortedMap = ValueSortMap.sortMapByValue(hmValue); // results in ascending order
+ ascending = true;
+ }
+ // Check
+ assertNotNull(sortedMap);
+ assertFalse(sortedMap.isEmpty());
+
+ int countNull = 0;
+ boolean hasNullsAtBegin = false;
+
+ String prevValue = null;
+ String currValue;
+ for(Map.Entry<String, String> entry : sortedMap.entrySet()) {
+ currValue = entry.getValue();
+ if (currValue == null) {
+ if (countNull == 0) {
+ hasNullsAtBegin = true;
+ }
+ countNull++;
+ } else {
+ if (prevValue != null) {
+ int lexComparison = prevValue.compareTo(currValue);
+ if (ascending) {
+ assertTrue(lexComparison < 0 || lexComparison == 0);
+ } else {
+ assertTrue(lexComparison > 0 || lexComparison == 0);
+ }
+ }
+ prevValue = currValue;
+ }
+ }
+ // 7 positions are expected as 'null' values
+ assertEquals(7, countNull);
+ if(ascending) {
+ assertTrue(hasNullsAtBegin);
+ }
+ }
+}