/src/main/java/de/jbee/lang/seq/ElementaryList.java
Java | 169 lines | 126 code | 24 blank | 19 comment | 14 complexity | cf3058330df473995e65c41779a589d5 MD5 | raw file
1/** 2 * 3 */ 4package de.jbee.lang.seq; 5 6import de.jbee.lang.Array; 7import de.jbee.lang.List; 8import de.jbee.lang.Sequence; 9import de.jbee.lang.Traversal; 10import de.jbee.lang.dev.Nonnull; 11 12/** 13 * A list consists of a single element and another subsequent {@link List} as tail. 14 * 15 * So a {@linkplain ElementaryList} will not have {@link #length()} of 1 as soon as the tail list 16 * isn't empty. 17 * 18 * @author Jan Bernitt (jan.bernitt@gmx.de) 19 */ 20final class ElementaryList<E> 21 implements List<E> { 22 23 /** 24 * @return A single element list with an empty tail. 25 */ 26 static <E> List<E> element( E element ) { 27 return element( element, List.with.<E> noElements() ); 28 } 29 30 /** 31 * @return A single element list with the <code>tail</code> given. 32 */ 33 static <E> List<E> element( E element, List<E> tail ) { 34 Nonnull.element( element ); 35 return new ElementaryList<E>( element, tail ); 36 } 37 38 private final E element; 39 private final List<E> tail; 40 41 private ElementaryList( E element, List<E> tail ) { 42 super(); 43 this.element = element; 44 this.tail = tail; 45 } 46 47 @Override 48 public void traverse( int start, Traversal<? super E> traversal ) { 49 if ( start > 0 ) { 50 tail.traverse( start - 1, traversal ); 51 } else { 52 while ( start == 0 ) { 53 start += traversal.incrementOn( element ); 54 } 55 tail.traverse( start, traversal ); 56 } 57 } 58 59 @Override 60 public List<E> subsequent() { 61 return tail; 62 } 63 64 @Override 65 public List<E> append( E e ) { 66 Nonnull.element( e ); 67 return tail.isEmpty() 68 // if tail is empty another single element list would be appended to this one. 69 ? List.with.elements( Array.sequence( element, e ) ) 70 : thisWithTail( tail.append( e ) ); 71 } 72 73 @Override 74 public E at( int index ) { 75 return index == 0 76 ? element 77 : tail.at( index - 1 ); 78 } 79 80 @Override 81 public List<E> concat( List<E> other ) { 82 return thisWithTail( tail.concat( other ) ); 83 } 84 85 @Override 86 public List<E> deleteAt( int index ) { 87 return index == 0 88 ? tail 89 : thisWithTail( tail.deleteAt( index - 1 ) ); 90 } 91 92 @Override 93 public List<E> drop( int count ) { 94 return count <= 0 95 ? this 96 : count == 1 97 ? tail 98 : tail.drop( count - 1 ); 99 } 100 101 @Override 102 public void fill( int offset, Object[] dest, int start, int length ) { 103 if ( start == 0 ) { 104 dest[offset] = element; 105 tail.fill( offset + 1, dest, 0, length - 1 ); 106 } else { 107 tail.fill( offset, dest, start - 1, length ); 108 } 109 } 110 111 @Override 112 public List<E> insertAt( int index, E e ) { 113 return index == 0 114 ? prepand( e ) 115 : index == 1 116 ? EVolutionList.dominant( length() + 1, new Object[] { element, e }, tail ) 117 : thisWithTail( tail.insertAt( index - 1, e ) ); 118 } 119 120 @Override 121 public boolean isEmpty() { 122 return false; 123 } 124 125 @Override 126 public List<E> prepand( E e ) { 127 Nonnull.element( e ); 128 //TODO not use StackList directly - Lister has to be extended to support tail list arguments in some way 129 return EVolutionList.dominant( length() + 1, new Object[] { e, element }, tail ); 130 } 131 132 @Override 133 public List<E> replaceAt( int index, E e ) { 134 return index == 0 135 ? element( e, tail ) 136 : thisWithTail( tail.replaceAt( index - 1, e ) ); 137 } 138 139 @Override 140 public int length() { 141 return tail.length() + 1; 142 } 143 144 @Override 145 public List<E> take( int count ) { 146 return count > 0 147 ? thisWithTail( tail.take( count - 1 ) ) 148 : List.with.<E> noElements(); 149 } 150 151 @Override 152 public List<E> tidyUp() { 153 final List<E> tidyTail = tail.tidyUp(); 154 return tidyTail == tail 155 ? this 156 : thisWithTail( tidyTail ); 157 } 158 159 @Override 160 public String toString() { 161 return "[" + String.valueOf( element ) + "]" + Sequence.CONCAT_OPERATOR_SYMBOL 162 + tail.toString(); 163 } 164 165 private List<E> thisWithTail( List<E> tail ) { 166 return new ElementaryList<E>( element, tail ); 167 } 168 169}