[英]Convert a set to map in java
I have a set and I want to convert it to map in order to use it later in guava's Maps.difference()
.我有一套,我想将其转换为地图,以便稍后在番石榴的
Maps.difference()
中使用它。 I only care about the keys in the difference.我只关心差异中的关键。
Came up with this version:想出了这个版本:
private <T> Map<T, T> toMap(Set<T> set) {
return set.stream().collect(Collectors.toMap(Function.identity(), Function.identity()));
}
However, I know that usually, a set has a backing field of map.但是,我知道通常,一个集合有一个 map 的支持字段。 This is the method I use to create the map:
这是我用来创建地图的方法:
public static <E> Set<E> newConcurrentHashSet() {
return Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>());
}
Since I only need the keys I thought maybe I can get a view of this field somehow.因为我只需要钥匙,我想也许我可以以某种方式了解这个领域。 any idea?
任何想法?
I ended up with a fairly straight-forward one line solution with Java 8 as follows:我最终得到了一个相当简单的 Java 8 单行解决方案,如下所示:
Map<String, Foo> map = fooSet.stream().collect(Collectors.toMap(Foo::getKey, e -> e));
Set<Foo> fooSet
Set<Foo> fooSet
getKey
which returns a String getKey
的 getter,它返回一个字符串You can convert a Set
to a Map
(same key and value taken from elements of Set
) as shown below:您可以将
Set
转换为Map
(取自Set
元素的相同键和值),如下所示:
private <T> Map<T, T> toMap(Set<T> set) {
Map<T, T> map = new ConcurrentHashMap<>();
set.forEach(t -> map.put(t, t));//contains same key and value pair
return map;
}
Improvement of developer 's answer:改进开发人员的回答:
Map<String, Foo> map = fooSet.stream().collect(Collectors.toMap(Foo::getKey, Function.identity()));
or if you statically import Collectors.toMap
and Function.identity
:或者如果您静态导入
Collectors.toMap
和Function.identity
:
Map<String, Foo> map = fooSet.stream().collect(toMap(Foo::getKey, identity()));
I would like to know which items only on left, which only on right, which in common (similar to map difference)
我想知道哪些项目只在左边,哪些只在右边,哪些是共同点(类似于地图差异)
Use removeAll()
and [ retainAll()][3]
.使用
removeAll()
和 [ retainAll()][3]
。
Example:例子:
Set<Integer> set1 = new HashSet<>(Arrays.asList(1,3,5,7,9));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3,4,5,6,7));
Set<Integer> onlyIn1 = new HashSet<>(set1);
onlyIn1.removeAll(set2);
Set<Integer> onlyIn2 = new HashSet<>(set2);
onlyIn2.removeAll(set1);
Set<Integer> inBoth = new HashSet<>(set1);
inBoth.retainAll(set2);
System.out.println("set1: " + set1);
System.out.println("set2: " + set2);
System.out.println("onlyIn1: " + onlyIn1);
System.out.println("onlyIn2: " + onlyIn2);
System.out.println("inBoth : " + inBoth);
Output输出
set1: [1, 3, 5, 7, 9]
set2: [3, 4, 5, 6, 7]
onlyIn1: [1, 9]
onlyIn2: [4, 6]
inBoth : [3, 5, 7]
Now, if you want to know all values and where they were found, you can do this (Java 8):现在,如果您想知道所有值以及它们的位置,您可以这样做(Java 8):
Set<Integer> setA = new HashSet<>(Arrays.asList(1,3,5,7,9));
Set<Integer> setB = new HashSet<>(Arrays.asList(3,4,5,6,7));
Map<Integer, String> map = new HashMap<>();
for (Integer i : setA)
map.put(i, "In A");
for (Integer i : setB)
map.compute(i, (k, v) -> (v == null ? "In B" : "In Both"));
System.out.println("setA: " + setA);
System.out.println("setB: " + setB);
map.entrySet().stream().forEach(System.out::println);
Output输出
setA: [1, 3, 5, 7, 9]
setB: [3, 4, 5, 6, 7]
1=In A
3=In Both
4=In B
5=In Both
6=In B
7=In Both
9=In A
See similar answer here . 在这里看到类似的答案。
Assuming that your original set is a set of values (no keys in original data!), you will need to specify keys for the newly created map.假设您的原始集合是一组值(原始数据中没有键!),您将需要为新创建的映射指定键。 Guava's
Maps.uniqueIndex
might be helpful (see here ) Guava 的
Maps.uniqueIndex
可能会有所帮助(请参阅此处)
Otherwise, if your original set is a set of keys (no values in original data!) that you want to retain, you will need to specify default or specific values for the newly created map.否则,如果您的原始集合是要保留的一组键(原始数据中没有值!),您将需要为新创建的映射指定默认值或特定值。 Guava's
Maps.toMap
might be helpful here. Guava 的
Maps.toMap
在这里可能会有所帮助。 (See more here ) ( 在这里查看更多)
package com.example;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Set<Foo> s = new HashSet<>();
s.add(new Foo("cccc"));
s.add(new Foo("aaaa"));
s.add(new Foo("bbb"));
Map<String, Foo> m = s.stream().collect(Collectors.toMap(Foo::getKey, Function.identity()));
System.out.println(m);
}
}
class Foo {
String name;
Foo(String name){this.name = name;}
String getKey() {return name;}
}
The returned Collector is not concurrent.
返回的 Collector 不是并发的。 For parallel stream pipelines, the combiner function operates by merging the keys from one map into another, which can be an expensive operation.
对于并行流管道,组合器功能通过将键从一个映射合并到另一个映射来操作,这可能是一项昂贵的操作。 If it is not required that results are inserted into the Map in encounter order, using toConcurrentMap(Function, Function) may offer better parallel performance.
如果不需要将结果按遇到顺序插入 Map,使用 toConcurrentMap(Function, Function) 可能会提供更好的并行性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.