/rlib-common/src/main/java/com/ss/rlib/common/util/linkedlist/impl/FastLinkedList.java

https://bitbucket.org/JavaSabr/rlib · Java · 466 lines · 269 code · 105 blank · 92 comment · 48 complexity · 31c0044a7c7de757cd915ee39269e9e6 MD5 · raw file

  1. package com.ss.rlib.common.util.linkedlist.impl;
  2. import com.ss.rlib.common.util.pools.PoolFactory;
  3. import com.ss.rlib.common.util.pools.ReusablePool;
  4. import org.jetbrains.annotations.NotNull;
  5. import org.jetbrains.annotations.Nullable;
  6. import java.util.Iterator;
  7. import java.util.NoSuchElementException;
  8. import java.util.Objects;
  9. import java.util.function.Function;
  10. /**
  11. * The non thread-safe implementation of the LinkedList.
  12. *
  13. * @param <E> the type parameter
  14. * @author JavaSaBr
  15. */
  16. public class FastLinkedList<E> extends AbstractLinkedList<E> {
  17. private static final long serialVersionUID = 6627882787737291879L;
  18. /**
  19. * The node pool.
  20. */
  21. @NotNull
  22. private final ReusablePool<Node<E>> pool;
  23. /**
  24. * The first element.
  25. */
  26. @Nullable
  27. private Node<E> first;
  28. /**
  29. * The second element.
  30. */
  31. @Nullable
  32. private Node<E> last;
  33. /**
  34. * The size.
  35. */
  36. private int size;
  37. /**
  38. * Instantiates a new Fast linked list.
  39. *
  40. * @param type the type
  41. */
  42. public FastLinkedList(@NotNull final Class<?> type) {
  43. super(type);
  44. this.pool = PoolFactory.newReusablePool(Node.class);
  45. }
  46. @Override
  47. public boolean add(@NotNull final E element) {
  48. linkLast(element);
  49. return true;
  50. }
  51. @Override
  52. public void addFirst(@NotNull final E element) {
  53. linkFirst(element);
  54. }
  55. @Override
  56. public void addLast(@NotNull final E element) {
  57. linkLast(element);
  58. }
  59. @Override
  60. public void apply(@NotNull final Function<? super E, ? extends E> function) {
  61. for (Node<E> node = getFirstNode(); node != null; node = node.getNext()) {
  62. node.setItem(function.apply(node.getItem()));
  63. }
  64. }
  65. @Override
  66. public void clear() {
  67. final ReusablePool<Node<E>> pool = getPool();
  68. for (Node<E> node = getFirstNode(); node != null; node = node.getNext()) {
  69. pool.put(node);
  70. }
  71. setFirstNode(null);
  72. setLastNode(null);
  73. size = 0;
  74. }
  75. @NotNull
  76. @Override
  77. public Iterator<E> descendingIterator() {
  78. return new IteratorImpl<>(this, IteratorImpl.PREV);
  79. }
  80. @Override
  81. public E get(final int index) {
  82. return index < size() >> 1 ? getFirst(index) : getLast(index);
  83. }
  84. /**
  85. * Gets first.
  86. *
  87. * @param index the index
  88. * @return the first
  89. */
  90. @Nullable
  91. protected final E getFirst(final int index) {
  92. int i = 0;
  93. for (Node<E> node = getFirstNode(); node != null; node = node.getNext()) {
  94. if (i == index) return node.getItem();
  95. i++;
  96. }
  97. return null;
  98. }
  99. @Nullable
  100. @Override
  101. public final Node<E> getFirstNode() {
  102. return first;
  103. }
  104. /**
  105. * Sets first node.
  106. *
  107. * @param first the first node.
  108. */
  109. protected void setFirstNode(@Nullable final Node<E> first) {
  110. this.first = first;
  111. }
  112. /**
  113. * Gets last.
  114. *
  115. * @param index the index
  116. * @return the last
  117. */
  118. @Nullable
  119. protected final E getLast(final int index) {
  120. int i = size() - 1;
  121. for (Node<E> node = getLastNode(); node != null; node = node.getPrev()) {
  122. if (i == index) return node.getItem();
  123. i--;
  124. }
  125. return null;
  126. }
  127. @Nullable
  128. @Override
  129. public final Node<E> getLastNode() {
  130. return last;
  131. }
  132. /**
  133. * Sets last node.
  134. *
  135. * @param last the last node.
  136. */
  137. protected void setLastNode(@Nullable final Node<E> last) {
  138. this.last = last;
  139. }
  140. /**
  141. * Get a new node.
  142. *
  143. * @param prev the prev node.
  144. * @param item the item.
  145. * @param next the next node.
  146. * @return the new node.
  147. */
  148. @NotNull
  149. protected Node<E> getNewNode(@Nullable final Node<E> prev, @NotNull final E item, @Nullable final Node<E> next) {
  150. final Node<E> node = getPool().take(Node::new);
  151. node.setItem(item);
  152. node.setNext(next);
  153. node.setPrev(prev);
  154. return node;
  155. }
  156. /**
  157. * Gets pool.
  158. *
  159. * @return the pool.
  160. */
  161. @NotNull
  162. protected ReusablePool<Node<E>> getPool() {
  163. return pool;
  164. }
  165. /**
  166. * Insert after.
  167. *
  168. * @param node the node
  169. * @param item the item
  170. */
  171. protected final void insertAfter(@NotNull final Node<E> node, final E item) {
  172. final Node<E> next = node.getNext();
  173. final Node<E> newNode = getNewNode(node, item, next);
  174. if (next == null) {
  175. setLastNode(newNode);
  176. } else {
  177. next.setPrev(newNode);
  178. }
  179. node.setNext(newNode);
  180. }
  181. /**
  182. * Insert before.
  183. *
  184. * @param node the node
  185. * @param item the item
  186. */
  187. protected final void insertBefore(@NotNull final Node<E> node, final E item) {
  188. final Node<E> prev = node.getPrev();
  189. final Node<E> newNode = getNewNode(prev, item, node);
  190. if (prev == null) {
  191. setFirstNode(newNode);
  192. } else {
  193. prev.setNext(newNode);
  194. }
  195. node.setPrev(newNode);
  196. }
  197. @NotNull
  198. @Override
  199. public Iterator<E> iterator() {
  200. return new IteratorImpl<>(this, IteratorImpl.NEXT);
  201. }
  202. /**
  203. * Link first.
  204. *
  205. * @param item the item
  206. */
  207. protected final void linkFirst(@NotNull final E item) {
  208. Objects.requireNonNull(item);
  209. final Node<E> first = getFirstNode();
  210. final Node<E> newNode = getNewNode(null, item, first);
  211. setFirstNode(newNode);
  212. if (first == null) {
  213. setLastNode(newNode);
  214. } else {
  215. first.setPrev(newNode);
  216. }
  217. size++;
  218. }
  219. /**
  220. * Link last.
  221. *
  222. * @param item the item
  223. */
  224. protected final void linkLast(@NotNull final E item) {
  225. Objects.requireNonNull(item);
  226. final Node<E> last = getLastNode();
  227. final Node<E> newNode = getNewNode(last, item, null);
  228. setLastNode(newNode);
  229. if (last == null) {
  230. setFirstNode(newNode);
  231. } else {
  232. last.setNext(newNode);
  233. }
  234. size++;
  235. }
  236. @Override
  237. public E poll() {
  238. final Node<E> first = getFirstNode();
  239. return first == null ? null : unlinkFirst(first);
  240. }
  241. @Override
  242. public E pollFirst() {
  243. final Node<E> first = getFirstNode();
  244. return first == null ? null : unlinkFirst(first);
  245. }
  246. @Override
  247. public E pollLast() {
  248. final Node<E> last = getLastNode();
  249. return last == null ? null : unlinkLast(last);
  250. }
  251. @Override
  252. public E removeFirst() {
  253. final Node<E> first = getFirstNode();
  254. if (first == null) {
  255. throw new NoSuchElementException();
  256. }
  257. return unlinkFirst(first);
  258. }
  259. @Override
  260. public E removeLast() {
  261. final Node<E> last = getLastNode();
  262. if (last == null) {
  263. throw new NoSuchElementException();
  264. }
  265. return unlinkLast(last);
  266. }
  267. @Override
  268. public int size() {
  269. return size;
  270. }
  271. @Override
  272. public E take() {
  273. return removeFirst();
  274. }
  275. @NotNull
  276. @Override
  277. public Object[] toArray() {
  278. final Object[] array = (Object[]) java.lang.reflect.Array.newInstance(getType(), size());
  279. int index = 0;
  280. for (Node<E> node = getFirstNode(); node != null; node = node.getNext()) {
  281. array[index++] = node.getItem();
  282. }
  283. return array;
  284. }
  285. @NotNull
  286. @Override
  287. @SuppressWarnings("unchecked")
  288. public <T> T[] toArray(@NotNull T[] array) {
  289. final int size = size();
  290. if (array.length < size) {
  291. array = (T[]) java.lang.reflect.Array.newInstance(array.getClass().getComponentType(), size);
  292. }
  293. int i = 0;
  294. final Object[] result = array;
  295. for (Node<E> node = getFirstNode(); node != null; node = node.getNext()) {
  296. result[i++] = node.getItem();
  297. }
  298. return array;
  299. }
  300. @Override
  301. public String toString() {
  302. return super.toString() + "\n " + pool;
  303. }
  304. @Override
  305. public final E unlink(@NotNull final Node<E> node) {
  306. final E element = node.getItem();
  307. final Node<E> next = node.getNext();
  308. final Node<E> prev = node.getPrev();
  309. if (prev == null) {
  310. setFirstNode(next);
  311. } else {
  312. prev.setNext(next);
  313. }
  314. if (next == null) {
  315. setLastNode(prev);
  316. } else {
  317. next.setPrev(prev);
  318. }
  319. size--;
  320. getPool().put(node);
  321. return element;
  322. }
  323. /**
  324. * Unlink first e.
  325. *
  326. * @param node the node
  327. * @return the e
  328. */
  329. protected final E unlinkFirst(@NotNull final Node<E> node) {
  330. final E element = node.getItem();
  331. final Node<E> next = node.getNext();
  332. setFirstNode(next);
  333. if (next == null) {
  334. setLastNode(null);
  335. } else {
  336. next.setPrev(null);
  337. }
  338. size--;
  339. getPool().put(node);
  340. return element;
  341. }
  342. /**
  343. * Unlink last e.
  344. *
  345. * @param node the node
  346. * @return the e
  347. */
  348. protected final E unlinkLast(@NotNull final Node<E> node) {
  349. final E element = node.getItem();
  350. final Node<E> prev = node.getPrev();
  351. setLastNode(prev);
  352. if (prev == null) {
  353. setFirstNode(null);
  354. } else {
  355. prev.setNext(null);
  356. }
  357. size--;
  358. getPool().put(node);
  359. return element;
  360. }
  361. }