java 如何将集合转换为映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42921312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to convert a set to map
提问by oshai
I have a set and I want to convert it to map in order to use it later in guava's Maps.difference()
. I only care about the keys in the difference.
Came up with this version:
我有一套,我想将它转换为地图,以便稍后在番石榴的Maps.difference()
. 我只关心差异中的键。
想出了这个版本:
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. This is the method I use to create the map:
但是,我知道通常,一个集合有一个 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?
因为我只需要钥匙,我想也许我可以以某种方式了解这个领域。任何的想法?
回答by Shane
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));
- fooSet is a set of objects of type Foo, i.e.
Set<Foo> fooSet
- Foo has a getter called
getKey
which returns a String
- fooSet 是一组 Foo 类型的对象,即
Set<Foo> fooSet
- Foo 有一个 getter 调用
getKey
它返回一个字符串
回答by developer
You can convert a Set
to a Map
(same key and value taken from elements of Set
) as shown below:
您可以将 a 转换Set
为 a 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;
}
回答by Andreas
From comment:
来自评论:
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
回答by Mantas
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)
假设您的原始集合是一组值(原始数据中没有键!),您将需要为新创建的映射指定键。番石榴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. (See more here)
否则,如果您的原始集合是要保留的一组键(原始数据中没有值!),您将需要为新创建的映射指定默认值或特定值。番石榴Maps.toMap
可能会在这里有所帮助。(在这里查看更多)
回答by Bj?rn Kahlert
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()));