你应该意识到你必须保留状态与你的数据:对于每个键,数据结构必须记住它在值的迭代中的位置。
因此,您必须展开地图合同。因此,您必须提供地图功能。
我提出以下(再使用HashMap和列表作为一个包装类):
package samplingmultimap;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class SamplingMultiMap<K,V> implements Map<K, V>{
private final Map<K, SamplingEntry> contents = new HashMap<>();
/** Internal class holds data and keeps a cursor */
private class SamplingEntry {
private final List<V> data = new ArrayList<>();
private int cursor;
public void add(V value){
data.add(value);
}
public V getNextData() {
if(cursor < data.size()){
return data.get(cursor++); // increment the cursor
} else {
return null; // You may want to re-browse the list, if so do cursor = 0 and return the first result
}
}
}
@Override
public void clear() {
contents.clear();
}
@Override
public boolean containsKey(Object key) {
return contents.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
for(SamplingEntry entry: contents.values()){
if(entry.data.contains(value)){
return true;
}
}
return false;
}
@Override
public Set<Entry<K, V>> entrySet() {
Set<Entry<K, V>> set = new HashSet<>();
for(Entry<K, SamplingEntry> samplingEntry: contents.entrySet()){
for(V value : samplingEntry.getValue().data){
Entry<K, V> singleEntry = new AbstractMap.SimpleEntry<K, V>(samplingEntry.getKey(), value);
set.add(singleEntry);
}
}
return set;
}
@Override
public V get(Object key) {
SamplingEntry entry = contents.get(key);
if(entry != null){
return entry.getNextData();
} else {
return null;
}
}
@Override
public boolean isEmpty() {
return contents.isEmpty();
}
@Override
public Set<K> keySet() {
return contents.keySet();
}
@Override
public V put(K key, V value) {
SamplingEntry existingEntry = contents.get(key);
if(existingEntry == null){
existingEntry = new SamplingEntry();
contents.put(key, existingEntry);
}
existingEntry.add(value);
return value;
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
for(Entry<? extends K, ? extends V> e: m.entrySet()){
put(e.getKey(), e.getValue());
}
}
@Override
public V remove(Object key) {
SamplingEntry oldValue = contents.remove(key);
if(oldValue != null){
return oldValue.getNextData();
} else {
return null;
}
}
@Override
public int size() {
int total = 0;
for(SamplingEntry v:contents.values()){
total += v.data.size();
}
return total;
}
@Override
public Collection<V> values() {
List<V> result = new ArrayList<>();
for(SamplingEntry v:contents.values()){
result.addAll(v.data);
}
return result;
}
}
用法示例为您输入:
public static void main(String[] argc){
// Create and populate the Map
SamplingMultiMap<String, String> map = new SamplingMultiMap<>();
map.put("A", "011");
map.put("A", "110");
map.put("A", "11");
map.put("L", "000");
map.put("L", "001");
map.put("L", "10");
map.put("I", "101");
map.put("I", "100");
map.put("I", "00");
// Get elements one by one
System.out.println(map.get("A")); // returns 011
System.out.println(map.get("A")); // returns 110
System.out.println(map.get("A")); // returns 11
System.out.println(map.get("A")); // returns null (but you may wish to rewind?)
// Order of access is unimportant, state is confined to the Key
System.out.println(map.get("L")); // returns 000
System.out.println(map.get("I")); // returns 101
System.out.println(map.get("L")); // returns 001
System.out.println(map.get("I")); // returns 100
System.out.println(map.get("I")); // returns 00
System.out.println(map.get("L")); // returns 10
}
编辑:要回答如何将字符串完全解码为符号列表,只是进一步扩展了Mapp:
public class MultiDecoder extends SamplingMultiMap<Character, String> {
public List<String> decode(String toDecode) {
return toDecode.chars().mapToObj(c -> (char) c).map(c -> get(c)).collect(Collectors.toList());
}
}
此解码器用于像这样(remeber它继承SamplingMultiMap所以吨必须与编码条目来填充):
public static void main(String[] argc) {
// Create and populate the decoder with all the encodings
MultiDecoder decoder = new MultiDecoder();
decoder.put('A', "011");
decoder.put('A', "110");
decoder.put('A', "11");
decoder.put('L', "000");
decoder.put('L', "001");
decoder.put('L', "10");
decoder.put('I', "101");
decoder.put('I', "100"); // Only 2 entries for 'I'
// Decode an entire String:
System.out.println(decoder.decode("ALI")); // returns ["011", "000", "101"]
System.out.println(decoder.decode("ALI")); // returns ["110", "001", "100"]
System.out.println(decoder.decode("ALI")); // returns [ "11", "10", "101"] // the 'I' encoding loops around independently
System.out.println(decoder.decode("ALI")); // returns ["011", "110", "100"] // The 'A' and 'L' encodings loop now also around
}
确定,所以需要读取与每个相关联的列表的特定元件键?你到目前为止尝试了什么?提示:尝试使用'ListMultimap'而不是'Multimap'来简化操作。 – Thomas
谢谢你我需要每次获得不同的值,例如阿里001 100 010阿里100 111 110其中每次每个字母都有不同的值 – student
这就是你所描述的。那么这样做有什么问题?毕竟,每个字母都有一个_list_值(提示:您可以从列表中获取特定元素)。 – Thomas