如何使用Multimap,因为我需要输出表格?

时间:2017-07-17 13:17:28

标签: java

我如何使用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]

1 个答案:

答案 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
}