/src/main/java/de/jbee/lang/seq/ElementaryList.java

http://github.com/jbee/jadamant · Java · 169 lines · 126 code · 24 blank · 19 comment · 14 complexity · cf3058330df473995e65c41779a589d5 MD5 · raw file

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