在本文中,我们将给您介绍关于ConcurrentHashMap.newKeySet的详细内容,并且为您解答与Collections.newSetFromMap的相关问题,此外,我们还将为您提供关于Ar
在本文中,我们将给您介绍关于ConcurrentHashMap.newKeySet的详细内容,并且为您解答与Collections.newSetFromMap的相关问题,此外,我们还将为您提供关于Arrays.asList()与Collections.singletonList()、Collections.emptyMap()与新的HashMap()、Collections.newSetFromMap(Map
- ConcurrentHashMap.newKeySet()与Collections.newSetFromMap()
- Arrays.asList()与Collections.singletonList()
- Collections.emptyMap()与新的HashMap()
- Collections.newSetFromMap(Map
map) - Collectors.toConcurrentMap和通过Collectors.toMap供应商选项将地图转换为ConcurrentHashMap有什么区别?
ConcurrentHashMap.newKeySet()与Collections.newSetFromMap()
Java 8引入了获取并发Set
实现的新方法
// Pre-Java-8 way to create a concurrent setSet<String> oldStyle = Collections.newSetFromMap(new ConcurrentHashMap<>());// New method in Java 8Set<String> newStyle = ConcurrentHashMap.newKeySet();
有什么理由喜欢新方法吗?
有什么优点/缺点吗?
答案1
小编典典ConcurrentHashMap.newKeySet()
应该会更有效,因为它删除了一个间接级别。Collections.newSetFromMap(map)
主要基于将操作重定向到map.keySet()
,但ConcurrentHashMap.newKeySet()
与map.keySet()
自身非常接近(仅在具有附加支持的情况下)。
至于功能,我认为没有区别。
Arrays.asList()与Collections.singletonList()
使用Arrays.asList(something)优于Collections.singletonList(something)来构成包含一项的列表是否有优势(或有很大不同)?后者使返回的列表也不可变。
答案1
小编典典Collections.singletonList(something)
是 不可变的,
而数组Arrays.asList(something)
是固定大小的List
表示形式,列表和数组在堆中连接在一起。
Arrays.asList(something)
允许对其进行 非结构更改 ,这些 更改 将同时反映到List和联合数组中。UnsupportedOperationException
尽管您可以为特定索引设置元素,但它会添加,删除元素。
对返回的列表所做的任何更改Collections.singletonList(something)
都会导致UnsupportedOperationException
。
同样,返回的列表的容量Collections.singletonList(something)
将始终为
1,这Arrays.asList(something)
与其后备阵列的容量不同。
Collections.emptyMap()与新的HashMap()
我可以使用哪些情况Collections.emptyMap()
?文档说,如果我希望我的收藏集是不可变的,则可以使用此方法。
为什么我要一个不变的空集合? 有什么意义?
Collections.newSetFromMap(Map map)
Collections提供了一种保证元素唯一性的Map实现,就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。这就是newSetFromMap方法:
public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
return new SetFromMap<>(map);
}
从Collections中可以看到,这里使用了一个内部类SetFromMap,它实现了Set接口。使用方法就是将Map的实例作为构造参数传入构造方法,并且这个Map必须是空的,否则抛出非法参数的异常:
SetFromMap(Map<E, Boolean> map) {
if (!map.isEmpty())
throw new IllegalArgumentException("Map is non-empty");
m = map;
s = map.keySet();
}
一般的最佳实践是,用一个空的Map传入构造方法,比如:
Set<Object> weakHashSet = Collections.newSetFromMap(new WeakHashMap<Object, Boolean>());
Set中的值就用Map的key来存储。用Map的put方法来add,就是这样:
public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
这里的m就是持有的Map。又因为addAll的实现是多次调用add方法,因为在这里就是多次调用m.put,而addAll在Collections中已经实现了。因此addAll是唯一一个继承的方法。具体的内部类定义见下:
private static class SetFromMap<E> extends AbstractSet<E>
implements Set<E>, Serializable
{
private final Map<E, Boolean> m; // The backing map
private transient Set<E> s; // Its keySet
SetFromMap(Map<E, Boolean> map) {
if (!map.isEmpty())
throw new IllegalArgumentException("Map is non-empty");
m = map;
s = map.keySet();
}
public void clear() { m.clear(); }
public int size() { return m.size(); }
public boolean isEmpty() { return m.isEmpty(); }
public boolean contains(Object o) { return m.containsKey(o); }
public boolean remove(Object o) { return m.remove(o) != null; }
public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
public Iterator<E> iterator() { return s.iterator(); }
public Object[] toArray() { return s.toArray(); }
public <T> T[] toArray(T[] a) { return s.toArray(a); }
public String toString() { return s.toString(); }
public int hashCode() { return s.hashCode(); }
public boolean equals(Object o) { return o == this || s.equals(o); }
public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
public boolean removeAll(Collection<?> c) {return s.removeAll(c);}
public boolean retainAll(Collection<?> c) {return s.retainAll(c);}
// addAll is the only inherited implementation
private static final long serialVersionUID = 2454657854757543876L;
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
s = m.keySet();
}
}
--------------------------------------------应用实例------------------------------------------------
在spring framework中AbstractBeanFactory中使用了一个名为alreadyCreated的Set来存放已经定义过得bean的名字。它的定义如下:
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(64));
因为java中没有ConcurrentSet这种东西,而从逻辑上讲又应当使用一个Set来实现,因此这里就使用了上面所说的方法。它是一个SetFromMap的实例。这样,既保持了alreadyCreated作为一个Set变量的逻辑意义,又通过传入的ConcurrentHashMap保证了它的并发性。
Collectors.toConcurrentMap和通过Collectors.toMap供应商选项将地图转换为ConcurrentHashMap有什么区别?
我想通过Java 8 和接口将a Map
转换为ConcurrentHashMap
via ,我可以使用两个选项。Stream``Collector
首先:
Map<Integer,String> mb = persons.stream()
.collect(Collectors.toMap(
p -> p.age,p -> p.name,(name1,name2) -> name1+";"+name2,ConcurrentHashMap::new));
第二个:
Map<Integer,String> mb1 = persons.stream()
.collect(Collectors.toConcurrentMap(
p -> p.age,p -> p.name));
哪个是更好的选择?什么时候应该使用每个选项?
关于ConcurrentHashMap.newKeySet和与Collections.newSetFromMap的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Arrays.asList()与Collections.singletonList()、Collections.emptyMap()与新的HashMap()、Collections.newSetFromMap(Map
本文标签: