// Copyright 2014 Thomas Müller // This file is part of HMMLA, which is licensed under GPLv3. package hmmla.util; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.Map.Entry; public class SymbolTable<T> implements Serializable { private static final long serialVersionUID = 1L; Map<T,Integer> toIndex; Map<Integer,T> fromIndex; public SymbolTable(){ toIndex = new HashMap<T,Integer>(); fromIndex = new HashMap<Integer,T>(); } public SymbolTable(SymbolTable<T> symbol_table) { toIndex = new HashMap<T, Integer>((HashMap<T, Integer>)symbol_table.toIndex); fromIndex = new HashMap<Integer, T>((HashMap<Integer, T>)symbol_table.fromIndex); } public List<Integer> toIndexes (Collection<T> symbols) { List<Integer> indexes = new ArrayList<Integer>(symbols.size()); for (T symbol : symbols){ indexes.add(toIndex(symbol)); } return indexes; } public List<T> toSymbols(Collection<Integer> indexes){ List<T> symbols = new ArrayList<T>(indexes.size()); for (Integer i : indexes){ symbols.add(toSymbol(i)); } return symbols; } public Integer toIndex(T symbol) { return toIndex(symbol, false); } public Integer toIndex(T symbol,boolean insert) { Integer index = toIndex.get(symbol); if (index == null){ if (insert){ index = toIndex.size(); toIndex.put(symbol, index); fromIndex.put(index,symbol); } else{ throw new NoSuchElementException(symbol.toString()); } } return index; } public T toSymbol(Integer index){ T t = fromIndex.get(index); if (t == null){ throw new NoSuchElementException(); } return t; } public Integer size(){ assert toIndex.size() == fromIndex.size(); return toIndex.size(); } public String toString(){ return toIndex.toString(); } public boolean hasSymbol(T object) { return toIndex.containsKey(object); } public Set<Entry<T,Integer>> entrySet(){ return toIndex.entrySet(); } public Collection<T> getSymbols() { return toIndex.keySet(); } public void resize(int size){ if (size >= this.size()){ return; } HashMap<T,Integer> toIndex2 = new HashMap<T,Integer>(); HashMap<Integer,T> fromIndex2 = new HashMap<Integer,T>(); for (int i=0;i<size;i++){ T t = fromIndex.get(i); toIndex2.put(t, i); fromIndex2.put(i, t); } toIndex = toIndex2; fromIndex = fromIndex2; } }