1 package org.opendaylight.yangtools.triemap;
3 import java.util.AbstractMap.SimpleImmutableEntry;
4 import java.util.Iterator;
6 import java.util.Map.Entry;
9 * Mimic immutable ListMap in Scala
11 * @author Roman Levenstein <romixlev@gmail.com>
15 abstract class ListMap<K,V> {
19 static <K,V> ListMap<K, V> map(final K k, final V v, final ListMap<K, V> tail){
20 return new Node<> (k, v, tail);
23 static <K,V> ListMap<K, V> map(final K k, final V v){
24 return new Node<> (k, v, null);
27 static <K,V> ListMap<K, V> map(final K k1, final V v1, final K k2, final V v2){
28 return new Node<> (k1, v1, new Node<>(k2,v2, null));
31 public abstract int size ();
33 public abstract boolean isEmpty() ;
35 abstract public boolean contains(K k, V v);
37 abstract public boolean contains(K key);
39 abstract public Option<V> get (K key);
41 abstract public ListMap<K, V> add (K key, V value);
43 abstract public ListMap<K, V> remove (K key);
45 abstract public Iterator<Map.Entry<K, V>> iterator();
48 static class EmptyListMap<K,V> extends ListMap<K, V> {
50 public ListMap<K,V> add (final K key, final V value) {
51 return ListMap.map(key, value, null);
55 public boolean contains(final K k, final V v) {
60 public boolean contains(final K k) {
65 public ListMap<K,V> remove(final K key) {
75 public boolean isEmpty () {
80 public Option<V> get (final K key) {
81 return Option.makeOption (null);
85 public Iterator<Entry<K, V>> iterator () {
86 return new EmptyListMapIterator<> ();
89 static class EmptyListMapIterator<K,V> implements Iterator<Entry<K, V>> {
92 public boolean hasNext () {
97 public Entry<K, V> next () {
102 public void remove () {
103 throw new RuntimeException("Operation not supported");
109 static class Node<K,V> extends ListMap<K, V> {
113 Node(final K k, final V v, final ListMap<K,V> next) {
120 public ListMap<K,V> add (final K key, final V value) {
121 return ListMap.map(key, value, remove (key));
125 public boolean contains(final K k, final V v) {
126 if(k.equals (this.k) && v.equals (this.v)) {
128 } else if(next != null) {
129 return next.contains (k, v);
135 public boolean contains(final K k) {
136 if(k.equals (this.k)) {
138 } else if(next != null) {
139 return next.contains (k);
145 public ListMap<K,V> remove(final K key) {
153 private ListMap<K, V> remove0 (final K key) {
154 ListMap<K, V> n = this;
155 ListMap<K, V> newN = null;
156 ListMap<K, V> lastN = null;
158 if(n instanceof EmptyListMap) {
162 Node<K, V> nn = (Node<K, V>)n;
163 if (key.equals (nn.k)) {
168 lastN.next = ListMap.map (nn.k, nn.v, null);
171 newN = ListMap.map (nn.k, nn.v, null);
185 return 1+next.size ();
190 public boolean isEmpty () {
195 public Option<V> get (final K key) {
197 return Option.makeOption (v);
200 return next.get (key);
202 return Option.makeOption (null);
207 public Iterator<Entry<K, V>> iterator () {
208 return new NodeIterator<> (this);
211 static class NodeIterator<K,V> implements Iterator<Entry<K, V>> {
214 public NodeIterator (final Node<K, V> n) {
219 public boolean hasNext () {
220 // return n!= null && n.next != null && !(n.next instanceof EmptyListMap);
221 return n!= null && !(n instanceof EmptyListMap);
225 public Entry<K, V> next () {
226 if (n instanceof Node) {
227 Node<K, V> nn = (Node<K, V>) n;
228 Entry<K, V> res = new SimpleImmutableEntry<> (nn.k, nn.v);
237 public void remove () {
238 throw new RuntimeException("Operation not supported");