LinkedList和ArrayList的设计

同时设计LinkedList和ArrayList

  • LinkedList不需要构造函数
  • ArrayList需要,后者需要一个容量的初始化。

image.png

接口List设计

只用来声明对外接口,不能声明

  1. package com.wztlink1013.ds.linkedlist;
  2. /**
  3. * fun:实现ArrayList和LinkedList的接口
  4. *
  5. */
  6. public interface List<E> {
  7. static final int ELEMENT_NOT_FOUND = -1;
  8. /**
  9. * 元素的数量[抽象类中实现]
  10. * @return
  11. */
  12. int size();
  13. /**
  14. * 是否为空[抽象类中实现]
  15. * @return
  16. */
  17. boolean isEmpty();
  18. /**
  19. * 是否包含某个元素[抽象类中实现]
  20. * @param element
  21. * @return
  22. */
  23. boolean contains(E element);
  24. /**
  25. * 添加元素到尾部[抽象类中实现]
  26. * @param element
  27. */
  28. void add(E element);
  29. /**
  30. * 清除所有元素[实现类中实现]
  31. */
  32. void clear();
  33. /**
  34. * 获取index位置的元素[实现类中实现]
  35. * @param index
  36. * @return
  37. */
  38. E get(int index);
  39. /**
  40. * 设置index位置的元素[实现类中实现]
  41. * @param index
  42. * @param element
  43. * @return 原来的元素ֵ
  44. */
  45. E set(int index, E element);
  46. /**
  47. * 在index位置插入一个元素[实现类中实现]
  48. * @param index
  49. * @param element
  50. */
  51. void add(int index, E element);
  52. /**
  53. * 删除index位置的元素[实现类中实现]
  54. * @param index
  55. * @return
  56. */
  57. E remove(int index);
  58. /**
  59. * 查看元素的索引[实现类中实现]
  60. * @param element
  61. * @return
  62. */
  63. int indexOf(E element);
  64. }

抽象类AbstractList设计

放ArrayList和LinkedList的公共代码

  • 实现List接口类的共同代码
  • ArrayList和LinkedList都用得到但是不对外公开的代码

声明抽象类abstract,就意味着可以不用全部实现接口List里面的所有方法

  1. package com.wztlink1013.ds.linkedlist;
  2. /**
  3. * fun:放ArrayList和LinkedList公共代码的抽象类(父类)
  4. *
  5. */
  6. public abstract class AbstractList<E> implements List<E> {
  7. protected int size;
  8. /**
  9. * 元素的数量
  10. * @return
  11. */
  12. public int size() {
  13. return size;
  14. }
  15. /**
  16. * 是否为空
  17. * @return
  18. */
  19. public boolean isEmpty() {
  20. return size == 0;
  21. }
  22. /**
  23. * 是否包含某个元素
  24. * @param element
  25. * @return
  26. */
  27. public boolean contains(E element) {
  28. return indexOf(element) != ELEMENT_NOT_FOUND;
  29. }
  30. /**
  31. * 添加元素到尾部
  32. * @param element
  33. */
  34. public void add(E element) {
  35. add(size, element);
  36. }
  37. /**
  38. * 下面三个是ArrayList和LinkedList两个实现类中的公共代码
  39. * */
  40. protected void outOfBounds(int index) {
  41. throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
  42. }
  43. protected void rangeCheck(int index) {
  44. if (index < 0 || index >= size) {
  45. outOfBounds(index);
  46. }
  47. }
  48. protected void rangeCheckForAdd(int index) {
  49. if (index < 0 || index > size) {
  50. outOfBounds(index);
  51. }
  52. }
  53. }

ArrayList设计

  1. package com.wztlink1013.ds.linkedlist;
  2. /**
  3. *fun:实现动态数组
  4. */
  5. @SuppressWarnings("unchecked")
  6. public class ArrayList<E> extends AbstractList<E> {
  7. private E[] elements;
  8. private static final int DEFAULT_CAPACITY = 10;
  9. public ArrayList(int capaticy) {
  10. capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
  11. elements = (E[]) new Object[capaticy];
  12. }
  13. public ArrayList() {
  14. this(DEFAULT_CAPACITY);
  15. }
  16. @Override
  17. public void clear() {
  18. for (int i = 0; i < size; i++) {
  19. elements[i] = null;
  20. }
  21. size = 0;
  22. }
  23. @Override
  24. public E get(int index) {
  25. rangeCheck(index);
  26. return elements[index];
  27. }
  28. @Override
  29. public E set(int index, E element) {
  30. rangeCheck(index);
  31. E old = elements[index];
  32. elements[index] = element;
  33. return old;
  34. }
  35. @Override
  36. public void add(int index, E element) {
  37. rangeCheckForAdd(index);
  38. ensureCapacity(size + 1);
  39. for (int i = size; i > index; i--) {
  40. elements[i] = elements[i - 1];
  41. }
  42. elements[index] = element;
  43. size++;
  44. }
  45. @Override
  46. public E remove(int index) {
  47. rangeCheck(index);
  48. E old = elements[index];
  49. for (int i = index + 1; i < size; i++) {
  50. elements[i - 1] = elements[i];
  51. }
  52. elements[--size] = null;
  53. return old;
  54. }
  55. @Override
  56. public int indexOf(E element) {
  57. if (element == null) { // 1
  58. for (int i = 0; i < size; i++) {
  59. if (elements[i] == null) return i;
  60. }
  61. } else {
  62. for (int i = 0; i < size; i++) {
  63. if (element.equals(elements[i])) return i; // n
  64. }
  65. }
  66. return ELEMENT_NOT_FOUND;
  67. }
  68. /**
  69. * 保证要有capacity的容量
  70. * @param capacity
  71. */
  72. private void ensureCapacity(int capacity) {
  73. int oldCapacity = elements.length;
  74. if (oldCapacity >= capacity) return;
  75. // 新容量为旧容量的1.5倍
  76. int newCapacity = oldCapacity + (oldCapacity >> 1);
  77. E[] newElements = (E[]) new Object[newCapacity];
  78. for (int i = 0; i < size; i++) {
  79. newElements[i] = elements[i];
  80. }
  81. elements = newElements;
  82. System.out.println(oldCapacity + "扩容为" + newCapacity);
  83. }
  84. @Override
  85. public String toString() {
  86. // size=3, [99, 88, 77]
  87. StringBuilder string = new StringBuilder();
  88. string.append("size=").append(size).append(", [");
  89. for (int i = 0; i < size; i++) {
  90. if (i != 0) {
  91. string.append(", ");
  92. }
  93. string.append(elements[i]);
  94. }
  95. string.append("]");
  96. return string.toString();
  97. }
  98. /**
  99. * 新添加功能
  100. */
  101. public int search(E element){
  102. for (int i = 0;i<size;i++){
  103. if (element == elements[i]){
  104. return i;
  105. }
  106. }
  107. return ELEMENT_NOT_FOUND;
  108. }
  109. }

LinkedList设计

  1. package com.wztlink1013.ds.linkedlist;
  2. /**
  3. *fun:链表的实现
  4. */
  5. @SuppressWarnings("unchecked")
  6. public class LinkedList<E> extends AbstractList<E> {
  7. private Node<E> first;
  8. private Node<E> last;
  9. private static class Node<E> {
  10. E element;
  11. Node<E> prev;
  12. Node<E> next;
  13. public Node(E element, Node<E> next) {
  14. this.element = element;
  15. this.next = next;
  16. }
  17. }
  18. @Override
  19. public void clear() {
  20. size = 0;
  21. first = null;
  22. last = null;
  23. }
  24. @Override
  25. public E get(int index) {
  26. return node(index).element;
  27. }
  28. @Override
  29. public E set(int index, E element) {
  30. Node<E> node = node(index);
  31. E old = node.element;
  32. node.element = element;
  33. return old;
  34. }
  35. @Override
  36. public void add(int index, E element) {
  37. if (index == 0){
  38. first = new Node<>(element, first);
  39. } else {
  40. Node<E> prev = node(index - 1);
  41. prev.next = new Node<>(element, prev.next);
  42. }
  43. size++;
  44. }
  45. @Override
  46. public E remove(int index) {
  47. // Node<E> node = first;
  48. // if (index == 0) {
  49. // first = first.next;
  50. // } else {
  51. // Node<E> prev = node(index -1);
  52. // node = prev.next;
  53. // prev.next = node.next;
  54. // }
  55. rangeCheck(index);
  56. Node<E> node = node(index);
  57. Node<E> prev = node.prev;
  58. Node<E> next = node.next;
  59. if (prev == null) { // index == 0
  60. first = next;
  61. } else {
  62. prev.next = next;
  63. }
  64. if (next == null) { // index == size - 1
  65. last = prev;
  66. } else {
  67. next.prev = prev;
  68. }
  69. size--;
  70. return node.element;
  71. }
  72. @Override
  73. public int indexOf(E element) {
  74. if (element == null) {
  75. Node<E> node = first;
  76. for (int i = 0; i < size; i++) {
  77. if (node.element == null) return i;
  78. node = node.next;
  79. }
  80. } else {
  81. Node<E> node = first;
  82. for (int i = 0; i < size; i++) {
  83. if (element.equals(node.element)) return i;
  84. node = node.next;
  85. }
  86. }
  87. return ELEMENT_NOT_FOUND;
  88. }
  89. /**
  90. * 获取index位置对应的节点对象
  91. * @param index
  92. * @return
  93. */
  94. private Node<E> node(int index) {
  95. rangeCheck(index);
  96. if (index < (size >> 1)) {
  97. Node<E> node = first;
  98. for (int i = 0; i < index; i++) {
  99. node = node.next;
  100. }
  101. return node;
  102. } else {
  103. Node<E> node = last;
  104. for (int i = size - 1; i > index; i--) {
  105. node = node.prev;
  106. }
  107. return node;
  108. }
  109. }
  110. @Override
  111. public String toString() {
  112. StringBuilder string = new StringBuilder();
  113. string.append("size=").append(size).append(", [");
  114. Node<E> node = first;
  115. for (int i = 0; i < size; i++) {
  116. if (i != 0) {
  117. string.append(", ");
  118. }
  119. string.append(node);
  120. node = node.next;
  121. }
  122. string.append("]");
  123. return string.toString();
  124. }
  125. }