Add entrySet to Multiset and Multimap
Vladimir Sitnikov
sitnikov.vladimir at gmail.com
Wed Apr 22 17:24:55 UTC 2015
Hi,
I think it makes sense to add common superclass for Multisets and
another one for Multimaps.
This removes code duplication between HashMutiset and TreeMultimap for instance.
Another feature is entrySet() method so iterations can be faster
(especially for Tree variants where each get is logN).
The commit does not introduce usages of entrySet.
--
Regards,
Vladimir Sitnikov
-------------- next part --------------
# HG changeset patch
# User Vladimir Sitnikov <sitnikov.vladimir at gmail.com>
# Date 1429722789 -10800
# Wed Apr 22 20:13:09 2015 +0300
# Node ID 763c4cf039d82067e5dcc35c75210d831b3c0951
# Parent d57b9e02ec35c87e3af8865e239d429329b84a2f
Extract common superclass for Multiset and Multimap, add entrySet method
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/DelegatingMultimap.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/DelegatingMultimap.java Wed Apr 22 20:13:09 2015 +0300
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.util;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+public class DelegatingMultimap<K, V> implements Multimap<K, V>, Serializable {
+ private static final long serialVersionUID = 7026540942232962263L;
+
+ protected final Map<K, Collection<V>> map;
+
+ public DelegatingMultimap(Map<K, Collection<V>> map) {
+ this.map = map;
+ }
+
+ protected Collection<V> createValueCollection() {
+ return new ArrayList<V>();
+ }
+
+ @Override
+ public void put(K key, V value) {
+ Collection<V> vs = map.get(key);
+ if (vs == null) {
+ vs = createValueCollection();
+ map.put(key, vs);
+ }
+ vs.add(value);
+ }
+
+ @Override
+ public void putAll(K key, Collection<V> vvs) {
+ Collection<V> vs = map.get(key);
+ if (vs == null) {
+ vs = createValueCollection();
+ map.put(key, vs);
+ }
+ vs.addAll(vvs);
+ }
+
+ @Override
+ public Collection<V> get(K key) {
+ Collection<V> vs = map.get(key);
+ return (vs == null) ? Collections.<V>emptyList() : Collections.unmodifiableCollection(vs);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public void clear() {
+ map.clear();
+ }
+
+ @Override
+ public Collection<K> keys() {
+ return map.keySet();
+ }
+
+ @Override
+ public Collection<V> values() {
+ Collection<V> result = createValueCollection();
+ for (Collection<V> vs : map.values()) {
+ result.addAll(vs);
+ }
+ return result;
+ }
+
+ public Collection<Map.Entry<K, Collection<V>>> entrySet() {
+ return map.entrySet();
+ }
+
+ @Override
+ public void remove(K key) {
+ map.remove(key);
+ }
+
+ @Override
+ public void merge(Multimap<K, V> other) {
+ for (K k : other.keys()) {
+ putAll(k, other.get(k));
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ @SuppressWarnings("unchecked")
+ DelegatingMultimap<K, V> that = (DelegatingMultimap<K, V>) o;
+
+ if (!map.equals(that.map)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return map.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return map.toString();
+ }
+}
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/DelegatingMultiset.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/DelegatingMultiset.java Wed Apr 22 20:13:09 2015 +0300
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.util;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+public class DelegatingMultiset<T> implements Multiset<T>, Serializable {
+ private static final long serialVersionUID = -8454789908011859615L;
+
+ protected final Map<T, Long> map;
+ private long size;
+
+ public DelegatingMultiset(Map<T, Long> map) {
+ this.map = map;
+ }
+
+ @Override
+ public void add(T element) {
+ add(element, 1);
+ }
+
+ @Override
+ public void add(T element, long add) {
+ Long count = map.get(element);
+ if (count == null) {
+ count = 0L;
+ }
+ count += add;
+ size += add;
+ if (count != 0) {
+ map.put(element, count);
+ } else {
+ map.remove(element);
+ }
+ }
+
+ @Override
+ public long count(T element) {
+ Long count = map.get(element);
+ return (count == null) ? 0 : count;
+ }
+
+ @Override
+ public Collection<Map.Entry<T, Long>> entrySet() {
+ return map.entrySet();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public long size() {
+ return size;
+ }
+
+ @Override
+ public Collection<T> keys() {
+ return Collections.unmodifiableCollection(map.keySet());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ @SuppressWarnings("unchecked")
+ DelegatingMultiset<T> that = (DelegatingMultiset<T>) o;
+
+ if (size != that.size) return false;
+ if (!map.equals(that.map)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = map.hashCode();
+ result = 31 * result + (int) (size ^ (size >>> 32));
+ return result;
+ }
+}
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/HashMultimap.java
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/HashMultimap.java Sat Apr 18 14:50:29 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/HashMultimap.java Wed Apr 22 20:13:09 2015 +0300
@@ -25,102 +25,13 @@
package org.openjdk.jmh.util;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.Map;
-public class HashMultimap<K, V> implements Multimap<K, V>, Serializable {
+public class HashMultimap<K, V> extends DelegatingMultimap<K, V> implements Serializable {
private static final long serialVersionUID = 2484428623123444998L;
- private final Map<K, Collection<V>> map;
-
public HashMultimap() {
- map = new HashMap<K, Collection<V>>();
- }
-
- @Override
- public void put(K key, V value) {
- Collection<V> vs = map.get(key);
- if (vs == null) {
- vs = new ArrayList<V>();
- map.put(key, vs);
- }
- vs.add(value);
- }
-
- @Override
- public void putAll(K key, Collection<V> vvs) {
- Collection<V> vs = map.get(key);
- if (vs == null) {
- vs = new ArrayList<V>();
- map.put(key, vs);
- }
- vs.addAll(vvs);
- }
-
- @Override
- public Collection<V> get(K key) {
- Collection<V> vs = map.get(key);
- return (vs == null) ? Collections.<V>emptyList() : Collections.unmodifiableCollection(vs);
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public void clear() {
- map.clear();
- }
-
- @Override
- public Collection<K> keys() {
- return map.keySet();
- }
-
- @Override
- public Collection<V> values() {
- Collection<V> result = new ArrayList<V>();
- for (Collection<V> vs : map.values()) {
- result.addAll(vs);
- }
- return result;
- }
-
- @Override
- public void remove(K key) {
- map.remove(key);
- }
-
- @Override
- public void merge(Multimap<K, V> other) {
- for (K k : other.keys()) {
- putAll(k, other.get(k));
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- HashMultimap that = (HashMultimap) o;
-
- if (!map.equals(that.map)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return map.hashCode();
- }
-
- @Override
- public String toString() {
- return map.toString();
+ super(new HashMap<K, Collection<V>>());
}
}
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/HashMultiset.java
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/HashMultiset.java Sat Apr 18 14:50:29 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/HashMultiset.java Wed Apr 22 20:13:09 2015 +0300
@@ -25,79 +25,12 @@
package org.openjdk.jmh.util;
import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.Map;
-public class HashMultiset<T> implements Multiset<T>, Serializable {
+public class HashMultiset<T> extends DelegatingMultiset<T> implements Serializable {
private static final long serialVersionUID = 8149201968248505516L;
- private final Map<T, Long> map;
- private long size;
-
public HashMultiset() {
- map = new HashMap<T, Long>();
- }
-
- @Override
- public void add(T element) {
- add(element, 1);
- }
-
- @Override
- public void add(T element, long add) {
- Long count = map.get(element);
- if (count == null) {
- count = 0L;
- }
- count += add;
- size += add;
- if (count != 0) {
- map.put(element, count);
- } else {
- map.remove(element);
- }
- }
-
- @Override
- public long count(T element) {
- Long count = map.get(element);
- return (count == null) ? 0 : count;
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public long size() {
- return size;
- }
-
- @Override
- public Collection<T> keys() {
- return Collections.unmodifiableCollection(map.keySet());
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- HashMultiset that = (HashMultiset) o;
-
- if (size != that.size) return false;
- if (!map.equals(that.map)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = map.hashCode();
- result = 31 * result + (int) (size ^ (size >>> 32));
- return result;
+ super(new HashMap<T, Long>());
}
}
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/HashsetMultimap.java
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/HashsetMultimap.java Sat Apr 18 14:50:29 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/HashsetMultimap.java Wed Apr 22 20:13:09 2015 +0300
@@ -25,98 +25,19 @@
package org.openjdk.jmh.util;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Map;
-public class HashsetMultimap<K, V> implements Multimap<K, V>, Serializable {
+public class HashsetMultimap<K, V> extends DelegatingMultimap<K, V> implements Serializable {
private static final long serialVersionUID = -4236100656731956836L;
- private final Map<K, Collection<V>> map;
-
public HashsetMultimap() {
- map = new HashMap<K, Collection<V>>();
+ super(new HashMap<K, Collection<V>>());
}
@Override
- public void put(K key, V value) {
- Collection<V> vs = map.get(key);
- if (vs == null) {
- vs = new HashSet<V>();
- map.put(key, vs);
- }
- vs.add(value);
- }
-
- @Override
- public void putAll(K key, Collection<V> values) {
- Collection<V> vs = map.get(key);
- if (vs == null) {
- vs = new HashSet<V>();
- map.put(key, vs);
- }
- vs.addAll(values);
- }
-
- @Override
- public Collection<V> get(K key) {
- Collection<V> vs = map.get(key);
- return (vs == null) ? Collections.<V>emptyList() : Collections.unmodifiableCollection(vs);
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public void clear() {
- map.clear();
- }
-
- @Override
- public Collection<K> keys() {
- return map.keySet();
- }
-
- @Override
- public Collection<V> values() {
- Collection<V> result = new ArrayList<V>();
- for (Collection<V> vs : map.values()) {
- result.addAll(vs);
- }
- return result;
- }
-
- @Override
- public void remove(K key) {
- map.remove(key);
- }
-
- @Override
- public void merge(Multimap<K, V> other) {
- for (K k : other.keys()) {
- putAll(k, other.get(k));
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- HashsetMultimap that = (HashsetMultimap) o;
-
- if (!map.equals(that.map)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return map.hashCode();
+ protected Collection<V> createValueCollection() {
+ return new HashSet<V>();
}
}
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/Multimap.java
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/Multimap.java Sat Apr 18 14:50:29 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/Multimap.java Wed Apr 22 20:13:09 2015 +0300
@@ -26,6 +26,7 @@
import java.util.Collection;
+import java.util.Map;
/**
* Basic Multimap.
@@ -58,6 +59,13 @@
Collection<V> get(K key);
/**
+ * Get all associations of the multimap.
+ * The method is intended for read-only view.
+ * @return entry set of the multimap
+ */
+ Collection<Map.Entry<K, Collection<V>>> entrySet();
+
+ /**
* Checks if multimap is empty
* @return true, if empty
*/
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/Multiset.java
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/Multiset.java Sat Apr 18 14:50:29 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/Multiset.java Wed Apr 22 20:13:09 2015 +0300
@@ -25,6 +25,7 @@
package org.openjdk.jmh.util;
import java.util.Collection;
+import java.util.Map;
/**
* Basic Multiset.
@@ -56,6 +57,13 @@
long count(T element);
/**
+ * Get all associations of the multiset.
+ * Each entry provides a key and a count of that element.
+ * @return entry set of the multiset
+ */
+ Collection<Map.Entry<T, Long>> entrySet();
+
+ /**
* Answers if Multiset is empty
* @return true, if set is empty
*/
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/TreeMultimap.java
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/TreeMultimap.java Sat Apr 18 14:50:29 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/TreeMultimap.java Wed Apr 22 20:13:09 2015 +0300
@@ -25,97 +25,13 @@
package org.openjdk.jmh.util;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
import java.util.TreeMap;
-public class TreeMultimap<K, V> implements Multimap<K, V>, Serializable {
+public class TreeMultimap<K, V> extends DelegatingMultimap<K, V> implements Serializable {
private static final long serialVersionUID = 1323519395777393861L;
- private final Map<K, Collection<V>> map;
-
public TreeMultimap() {
- map = new TreeMap<K, Collection<V>>();
- }
-
- @Override
- public void put(K key, V value) {
- Collection<V> vs = map.get(key);
- if (vs == null) {
- vs = new ArrayList<V>();
- map.put(key, vs);
- }
- vs.add(value);
- }
-
- @Override
- public void putAll(K key, Collection<V> vvs) {
- Collection<V> vs = map.get(key);
- if (vs == null) {
- vs = new ArrayList<V>();
- map.put(key, vs);
- }
- vs.addAll(vvs);
- }
-
- @Override
- public Collection<V> get(K key) {
- Collection<V> vs = map.get(key);
- return (vs == null) ? Collections.<V>emptyList() : Collections.unmodifiableCollection(vs);
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public void clear() {
- map.clear();
- }
-
- @Override
- public Collection<K> keys() {
- return map.keySet();
- }
-
- @Override
- public Collection<V> values() {
- Collection<V> result = new ArrayList<V>();
- for (Collection<V> vs : map.values()) {
- result.addAll(vs);
- }
- return result;
- }
-
- @Override
- public void remove(K key) {
- map.remove(key);
- }
-
- @Override
- public void merge(Multimap<K, V> other) {
- for (K k : other.keys()) {
- putAll(k, other.get(k));
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- TreeMultimap that = (TreeMultimap) o;
-
- if (!map.equals(that.map)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return map.hashCode();
+ super(new TreeMap<K, Collection<V>>());
}
}
diff -r d57b9e02ec35 -r 763c4cf039d8 jmh-core/src/main/java/org/openjdk/jmh/util/TreeMultiset.java
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/TreeMultiset.java Sat Apr 18 14:50:29 2015 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/TreeMultiset.java Wed Apr 22 20:13:09 2015 +0300
@@ -25,79 +25,12 @@
package org.openjdk.jmh.util;
import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
import java.util.TreeMap;
-public class TreeMultiset<T extends Comparable<T>> implements Multiset<T>, Serializable {
+public class TreeMultiset<T extends Comparable<T>> extends DelegatingMultiset<T> implements Serializable {
private static final long serialVersionUID = 3571810468402616517L;
- private final Map<T, Long> map;
- private long size;
-
public TreeMultiset() {
- map = new TreeMap<T, Long>();
- }
-
- @Override
- public void add(T element) {
- add(element, 1);
- }
-
- @Override
- public void add(T element, long add) {
- Long count = map.get(element);
- if (count == null) {
- count = 0L;
- }
- count += add;
- size += add;
- if (count != 0) {
- map.put(element, count);
- } else {
- map.remove(element);
- }
- }
-
- @Override
- public long count(T element) {
- Long count = map.get(element);
- return (count == null) ? 0 : count;
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public long size() {
- return size;
- }
-
- @Override
- public Collection<T> keys() {
- return Collections.unmodifiableCollection(map.keySet());
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- TreeMultiset that = (TreeMultiset) o;
-
- if (size != that.size) return false;
- if (!map.equals(that.map)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = map.hashCode();
- result = 31 * result + (int) (size ^ (size >>> 32));
- return result;
+ super(new TreeMap<T, Long>());
}
}
More information about the jmh-dev
mailing list