我如何使用Multimap
使用java
每次打印每个键的不同值。例如:
L has values 000,001,10
I has values 101, 100,00
我需要输出如下:
ALI
第一行包含每个键的第一个值001 000 101
第二行包含每个键的第二个值110 001 100
第三行包含每个键的第三个值11 10 00
此代码部分:
public static Multimap<String, String> Reading() throws IOException {
Multimap<String, String> myMultimap = ArrayListMultimap.create();
FileInputStream file = new FileInputStream("BBBB.txt");
InputStreamReader fr = new InputStreamReader(file);
BufferedReader br = new BufferedReader(fr);
String line = "";
while ((line = br.readLine()) != null) {
String[] columns= line.split(" ");
myMultimap.put(columns[1],columns[0]);
}
输出显示每个键的值
Ali
[011,110 ,11][ 000,001,10][101, 100,00]
答案 0 :(得分:0)
你应该意识到你必须对你的数据保持状态:对于每个键,数据结构必须记住它在值的迭代中的位置。
因此,您必须展开Map合约。因此,您必须èxtendthe
Map`功能。
我建议如下(重新使用HashMap和List作为Wrapper类):
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
}
编辑:为了回答如何将String完全解码为符号列表,只需进一步扩展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());
}
}
此解码器使用如下(记住它继承了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
}