From fddaf71a8b12b6e7fc173f26315119399f6454e0 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 7 May 2022 13:50:26 +0800 Subject: [PATCH] add class --- .../core/collection/ConcurrentHashSet.java | 58 +------- .../cn/hutool/core/collection/SetFromMap.java | 139 ++++++++++++++++++ .../cn/hutool/core/collection/SetUtil.java | 12 ++ 3 files changed, 158 insertions(+), 51 deletions(-) create mode 100644 hutool-core/src/main/java/cn/hutool/core/collection/SetFromMap.java diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java b/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java index 21dc35fb0..25f470ad3 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java @@ -1,8 +1,6 @@ package cn.hutool.core.collection; -import java.util.AbstractSet; import java.util.Collection; -import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; /** @@ -13,20 +11,16 @@ import java.util.concurrent.ConcurrentHashMap; * @param 元素类型 * @since 3.1.0 */ -public class ConcurrentHashSet extends AbstractSet implements java.io.Serializable { +public class ConcurrentHashSet extends SetFromMap { private static final long serialVersionUID = 7997886765361607470L; - /** 持有对象。如果值为此对象表示有数据,否则无数据 */ - private static final Boolean PRESENT = true; - private final ConcurrentHashMap map; - // ----------------------------------------------------------------------------------- Constructor start /** * 构造
* 触发因子为默认的0.75 */ public ConcurrentHashSet() { - map = new ConcurrentHashMap<>(); + super(new ConcurrentHashMap<>()); } /** @@ -36,7 +30,7 @@ public class ConcurrentHashSet extends AbstractSet implements java.io.Seri * @param initialCapacity 初始大小 */ public ConcurrentHashSet(final int initialCapacity) { - map = new ConcurrentHashMap<>(initialCapacity); + super(new ConcurrentHashMap<>(initialCapacity)); } /** @@ -46,7 +40,7 @@ public class ConcurrentHashSet extends AbstractSet implements java.io.Seri * @param loadFactor 加载因子。此参数决定数据增长时触发的百分比 */ public ConcurrentHashSet(final int initialCapacity, final float loadFactor) { - map = new ConcurrentHashMap<>(initialCapacity, loadFactor); + super(new ConcurrentHashMap<>(initialCapacity, loadFactor)); } /** @@ -57,7 +51,7 @@ public class ConcurrentHashSet extends AbstractSet implements java.io.Seri * @param concurrencyLevel 线程并发度 */ public ConcurrentHashSet(final int initialCapacity, final float loadFactor, final int concurrencyLevel) { - map = new ConcurrentHashMap<>(initialCapacity, loadFactor, concurrencyLevel); + super(new ConcurrentHashMap<>(initialCapacity, loadFactor, concurrencyLevel)); } /** @@ -65,52 +59,14 @@ public class ConcurrentHashSet extends AbstractSet implements java.io.Seri * @param iter {@link Iterable} */ public ConcurrentHashSet(final Iterable iter) { + super(iter instanceof Collection ? new ConcurrentHashMap<>((int)(((Collection)iter).size() / 0.75f)) : new ConcurrentHashMap<>()); if(iter instanceof Collection) { - final Collection collection = (Collection)iter; - map = new ConcurrentHashMap<>((int)(collection.size() / 0.75f)); - this.addAll(collection); + this.addAll((Collection)iter); }else { - map = new ConcurrentHashMap<>(); for (final E e : iter) { this.add(e); } } } // ----------------------------------------------------------------------------------- Constructor end - - @Override - public Iterator iterator() { - return map.keySet().iterator(); - } - - @Override - public int size() { - return map.size(); - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public boolean contains(final Object o) { - //noinspection SuspiciousMethodCalls - return map.containsKey(o); - } - - @Override - public boolean add(final E e) { - return map.put(e, PRESENT) == null; - } - - @Override - public boolean remove(final Object o) { - return PRESENT.equals(map.remove(o)); - } - - @Override - public void clear() { - map.clear(); - } } diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/SetFromMap.java b/hutool-core/src/main/java/cn/hutool/core/collection/SetFromMap.java new file mode 100644 index 000000000..d4fd92eee --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/collection/SetFromMap.java @@ -0,0 +1,139 @@ +package cn.hutool.core.collection; + +import java.io.IOException; +import java.io.Serializable; +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Stream; + +/** + * 基于Map的Set实现 + * + * @param 元素类型 + * @author guava + */ +public class SetFromMap extends AbstractSet implements Serializable { + private static final long serialVersionUID = 1L; + + private final Map m; // The backing map + private transient Set s; // Its keySet + + public SetFromMap(final Map map) { + m = map; + s = map.keySet(); + } + + @Override + public void clear() { + m.clear(); + } + + @Override + public int size() { + return m.size(); + } + + @Override + public boolean isEmpty() { + return m.isEmpty(); + } + + @SuppressWarnings("SuspiciousMethodCalls") + @Override + public boolean contains(final Object o) { + return m.containsKey(o); + } + + @Override + public boolean remove(final Object o) { + return m.remove(o) != null; + } + + @Override + public boolean add(final E e) { + return m.put(e, Boolean.TRUE) == null; + } + + @Override + public Iterator iterator() { + return s.iterator(); + } + + @Override + public Object[] toArray() { + return s.toArray(); + } + + @SuppressWarnings("SuspiciousToArrayCall") + @Override + public T[] toArray(final T[] a) { + return super.toArray(a); + } + + @Override + public String toString() { + return s.toString(); + } + + @Override + public int hashCode() { + return s.hashCode(); + } + + @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") + @Override + public boolean equals(final Object o) { + return o == this || s.equals(o); + } + + @Override + public boolean containsAll(final Collection c) { + return s.containsAll(c); + } + + @Override + public boolean removeAll(final Collection c) { + return s.removeAll(c); + } + + @Override + public boolean retainAll(final Collection c) { + return s.retainAll(c); + } + + @Override + public void forEach(final Consumer action) { + s.forEach(action); + } + + @Override + public boolean removeIf(final Predicate filter) { + return s.removeIf(filter); + } + + @Override + public Spliterator spliterator() { + return s.spliterator(); + } + + @Override + public Stream stream() { + return s.stream(); + } + + @Override + public Stream parallelStream() { + return s.parallelStream(); + } + + private void readObject(final java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + s = m.keySet(); + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/SetUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/SetUtil.java index bcddcf067..a80396d6e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/SetUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/SetUtil.java @@ -8,6 +8,7 @@ import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; /** @@ -125,6 +126,17 @@ public class SetUtil { return set; } + /** + * 新建一个SetFromMap + * + * @param 集合元素类型 + * @param map Map + * @return SetFromMap对象 + */ + public static SetFromMap of(final Map map) { + return new SetFromMap<>(map); + } + /** * 数组转为一个不可变List
* 类似于Java9中的List.of