add class

This commit is contained in:
Looly 2022-05-07 13:50:26 +08:00
parent 36d75d7030
commit fddaf71a8b
3 changed files with 158 additions and 51 deletions

View File

@ -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 <E> 元素类型
* @since 3.1.0
*/
public class ConcurrentHashSet<E> extends AbstractSet<E> implements java.io.Serializable {
public class ConcurrentHashSet<E> extends SetFromMap<E> {
private static final long serialVersionUID = 7997886765361607470L;
/** 持有对象。如果值为此对象表示有数据,否则无数据 */
private static final Boolean PRESENT = true;
private final ConcurrentHashMap<E, Boolean> map;
// ----------------------------------------------------------------------------------- Constructor start
/**
* 构造<br>
* 触发因子为默认的0.75
*/
public ConcurrentHashSet() {
map = new ConcurrentHashMap<>();
super(new ConcurrentHashMap<>());
}
/**
@ -36,7 +30,7 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> 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<E> extends AbstractSet<E> 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<E> extends AbstractSet<E> 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<E> extends AbstractSet<E> implements java.io.Seri
* @param iter {@link Iterable}
*/
public ConcurrentHashSet(final Iterable<E> iter) {
super(iter instanceof Collection ? new ConcurrentHashMap<>((int)(((Collection<E>)iter).size() / 0.75f)) : new ConcurrentHashMap<>());
if(iter instanceof Collection) {
final Collection<E> collection = (Collection<E>)iter;
map = new ConcurrentHashMap<>((int)(collection.size() / 0.75f));
this.addAll(collection);
this.addAll((Collection<E>)iter);
}else {
map = new ConcurrentHashMap<>();
for (final E e : iter) {
this.add(e);
}
}
}
// ----------------------------------------------------------------------------------- Constructor end
@Override
public Iterator<E> 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();
}
}

View File

@ -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 <E> 元素类型
* @author guava
*/
public class SetFromMap<E> extends AbstractSet<E> implements Serializable {
private static final long serialVersionUID = 1L;
private final Map<E, Boolean> m; // The backing map
private transient Set<E> s; // Its keySet
public SetFromMap(final Map<E, Boolean> 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<E> iterator() {
return s.iterator();
}
@Override
public Object[] toArray() {
return s.toArray();
}
@SuppressWarnings("SuspiciousToArrayCall")
@Override
public <T> 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<? super E> action) {
s.forEach(action);
}
@Override
public boolean removeIf(final Predicate<? super E> filter) {
return s.removeIf(filter);
}
@Override
public Spliterator<E> spliterator() {
return s.spliterator();
}
@Override
public Stream<E> stream() {
return s.stream();
}
@Override
public Stream<E> parallelStream() {
return s.parallelStream();
}
private void readObject(final java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
s = m.keySet();
}
}

View File

@ -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 <T> 集合元素类型
* @param map Map
* @return SetFromMap对象
*/
public static <T> SetFromMap<T> of(final Map<T, Boolean> map) {
return new SetFromMap<>(map);
}
/**
* 数组转为一个不可变List<br>
* 类似于Java9中的List.of