我想要一个可以有重复键的映射表。
我知道有很多映射表实现(Eclipse 显示了大约50个),所以我相信一定有一个允许这样做的。我知道编写自己的映射表很容易,但我更愿意使用一些现有的解决方案。
可能在 commons-collections 或 google-collections 中有相关的东西?
我想要一个可以有重复键的映射表。
我知道有很多映射表实现(Eclipse 显示了大约50个),所以我相信一定有一个允许这样做的。我知道编写自己的映射表很容易,但我更愿意使用一些现有的解决方案。
可能在 commons-collections 或 google-collections 中有相关的东西?
您正在寻找一个multimap,实际上commons-collections和Guava都有几个实现。Multimaps允许通过维护每个键的值集合来使用多个键,即您可以将单个对象放入映射中,但是检索到的是一个集合。
如果您可以使用Java 5,我建议使用Guava的Multimap
,因为它支持泛型。
com.google.common.collect.HashMultimap
有readObject
/writeObject
方法,ArrayListMultimap和Immutable{List,Set}Multimap也有。我认为一个无用的反序列化实例是值得报告的错误。 - nd.我们不需要依赖于Google Collections外部库。您可以简单地实现以下Map:
Map<String, ArrayList<String>> hashMap = new HashMap<String, ArrayList>();
public static void main(String... arg) {
// Add data with duplicate keys
addValues("A", "a1");
addValues("A", "a2");
addValues("B", "b");
// View data.
Iterator it = hashMap.keySet().iterator();
ArrayList tempList = null;
while (it.hasNext()) {
String key = it.next().toString();
tempList = hashMap.get(key);
if (tempList != null) {
for (String value: tempList) {
System.out.println("Key : "+key+ " , Value : "+value);
}
}
}
}
private void addValues(String key, String value) {
ArrayList tempList = null;
if (hashMap.containsKey(key)) {
tempList = hashMap.get(key);
if(tempList == null)
tempList = new ArrayList();
tempList.add(value);
} else {
tempList = new ArrayList();
tempList.add(value);
}
hashMap.put(key,tempList);
}
请确保对代码进行微调。Multimap<Integer, String> multimap = ArrayListMultimap.create();
multimap.put(1, "A");
multimap.put(1, "B");
multimap.put(1, "C");
multimap.put(1, "A");
multimap.put(2, "A");
multimap.put(2, "B");
multimap.put(2, "C");
multimap.put(3, "A");
System.out.println(multimap.get(1));
System.out.println(multimap.get(2));
System.out.println(multimap.get(3));
输出为:
[A,B,C,A]
[A,B,C]
[A]
注意:我们需要导入库文件。
http://www.java2s.com/Code/Jar/g/Downloadgooglecollectionsjar.htm
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
或者 https://commons.apache.org/proper/commons-collections/download_collections.cgi
import org.apache.commons.collections.MultiMap;
import org.apache.commons.collections.map.MultiValueMap;
TreeMap<String, ArrayList<MyClass>>
解决了我的重复键需求。 - Joe如果你想遍历一个键值对列表(正如你在评论中所写的),那么使用List或数组会更好。首先将你的键和值组合起来:
public class Pair
{
public Class1 key;
public Class2 value;
public Pair(Class1 key, Class2 value)
{
this.key = key;
this.value = value;
}
}
用你想要作为键和值的类型替换Class1和Class2。
现在,你可以把它们放进数组或列表中并遍历它们:
Pair[] pairs = new Pair[10];
...
for (Pair pair : pairs)
{
...
}
List<Map.Entry<K,V>>
来解决。我们不需要使用任何外部库或Map的新实现。可以像这样创建一个地图条目:Map.Entry<String, Integer> entry = new AbstractMap.SimpleEntry<String, Integer>("key", 1);
。请注意保留 HTML 标记。org.springframework.util.MultiValueMap是Spring框架中的一个工具类,用于存储键值对,其中每个键可以有多个值。
org.apache.commons.collections4是Apache Commons项目中的一个工具类,也用于存储键值对,其中每个键可以有多个值。
您可以使用具有自定义比较器的TreeMap,以使每个键与其他键不相等。它还会保留插入顺序,就像LinkedHashMap一样。因此,最终结果就像是允许重复键的LinkedHashMap!
这是一种非常简单的实现,不需要任何第三方依赖项或MultiMaps的复杂性。
import java.util.Map;
import java.util.TreeMap;
...
...
//Define a TreeMap with a custom Comparator
Map<Integer, String> map = new TreeMap<>((a, b) -> 1); // See notes 1 and 2
//Populate the map
map.put(1, "One");
map.put(3, "Three");
map.put(1, "One One");
map.put(7, "Seven");
map.put(2, "Two");
map.put(1, "One One One");
//Display the map entries:
map.entrySet().forEach(System.out::println);
//See note number 3 for the following:
Map<Integer, String> sortedTreeMap = map.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue,
(x, y) -> x, () -> new TreeMap<>((a, b) -> 1)
));
//Display the entries of this sorted TreeMap:
sortedTreeMap.entrySet().forEach(System.out::println);
...
注意:
从我的错误中学习... 请不要自行实现此功能。 Guava multimap 是最好的选择。
在 multimaps 中常见的改进是禁止重复的键值对。
在您的实现中实施/更改这一点可能很麻烦。
在 Guava 中,它就像这样简单:
HashMultimap<String, Integer> no_dupe_key_plus_val = HashMultimap.create();
ArrayListMultimap<String, Integer> allow_dupe_key_plus_val = ArrayListMultimap.create();
不需要花哨的库。地图由唯一键定义,所以不要弯曲它们,使用列表。流很强大。
import java.util.AbstractMap.SimpleImmutableEntry;
List<SimpleImmutableEntry<String, String>> nameToLocationMap = Arrays.asList(
new SimpleImmutableEntry<>("A", "A1"),
new SimpleImmutableEntry<>("A", "A2"),
new SimpleImmutableEntry<>("B", "B1"),
new SimpleImmutableEntry<>("B", "B1"),
);
就是这样。使用示例:
List<String> allBsLocations = nameToLocationMap.stream()
.filter(x -> x.getKey().equals("B"))
.map(x -> x.getValue())
.collect(Collectors.toList());
nameToLocationMap.stream().forEach(x ->
do stuff with: x.getKey()...x.getValue()...