• Java 程序设计报告[对接java的迭代器接口]


    1:程序的功能设计与分析

            -:将实现deque与stack

            -:采用继承与内部类来提高程序的拓展性、安全性、简洁性

            -:对接到java.util.iterator中的iterator接口与iterable接口

    2:程序的特点分析

            -:观察到队列、栈都可以用链表进行模拟,故在设计一个链表为底层类,设计队列的接口和栈的接口,并且链表继承这两个接口,从而实现写一次代码多次使用

            -:采用泛型,用于提高重新的拓展性

    3:类图

    4:为什么这么设计:

            -:为什么设计这两个内部类?

            首先要观察到list内部有两个内部类listNode与listIterator,其访问性前为static public后为private。设计前者为内部类的目的是提高代码的安全性,因为每种数据结构的节点定义都不同,所以将特定的数据结构与特定的节点绑定到一起有助于程序的可读性,且static public的内部类创建出来的实例并不会与外部类有耦合,这也进一步确保了程序的安全性。设计后者为内部类的原因是利用内部类与外部类的耦合实现多继承,因为listIterator与list并不是一个is-a的关系,所以本人不必考虑用list与iterator继承,以此来实现iterator的接口,用内部类来实现接口有助于外部类摆脱这种没必要的耦合,当然,我们并不希望外界能够访问到这一内部类,其外部与之交互的方法仅仅设置为iterator()函数,所以设计为private

            -:为什么使用接口来实现deque和stack?

            因为deque和stack都可以用list来实现相应的需求,所以我们考虑用接口来封装list,使之完成对应的需求,在java的标准库容器中,这样的设计也是非常常见的,对于map这种关联性的容器,我们可以封装平衡树和hash表来实现对应的需求,而且我们可以根据程序环境的不同来更改底层实现,可以拥有更好的灵活性;

            -:deque与deque_ifc的关系为什么是组合关系而非继承关系?

            在设计模式中,我们提倡在程序设计时要在组合和继承时选择其中一个的时,优先考虑组合关系,只有当子类必须要向上向上转型为父类的时候,才考虑用继承;

    5:其他一些需要考虑的地方

            -:固然使用接口封装一个容器来实现另外一种容器这种方法很高效,但这种高效仅仅限制于代码实现,在空间上,并不是特别友好,因为在一个容器实现另外一直容器时,我一定会获得一些没必要的负担,即一些功能我们用不上,但因为只是对容器的封装,我们没法对这种负担进行优化,不同容器之间的节点就是一个典型的有负担的部分;

            这个时候有一个代替的方案,及对有负担的部分考虑用建筑者模式,这种设计多种模块替代有负担的部分,但这种模式可能会引发一些“不知情的错误”,比如我想用stack,但我将节点设置且deque容器的节点,这回导致一些方法运行错误;

    6:源码实现:

    1. import java.util.Iterator;
    2. interface deque_ifc {
    3. public void pushBack(T data);
    4. public void pushFront(T data);
    5. public void popBack();
    6. public void popFront();
    7. public T getFront();
    8. public T getBack();
    9. public int size();
    10. public Iterator iterator();
    11. }
    12. interface stack_ifc{
    13. public void pushFront(T data);
    14. public T getFront();
    15. public void popFront();
    16. public int size();
    17. public Iterator iterator();
    18. }
    19. class deque implements Iterable{
    20. private deque_ifc contain;
    21. public deque(deque_ifc ifc){
    22. this.contain=ifc;
    23. }
    24. public void setContain(deque_ifc contain){
    25. this.contain=contain;
    26. }
    27. public void pushBack(T data){
    28. this.contain.pushBack(data);
    29. }
    30. public void pushFront(T data){
    31. this.contain.pushFront(data);
    32. }
    33. public void popBack(){
    34. this.contain.popBack();
    35. }
    36. public void popFront(){
    37. this.contain.popFront();
    38. }
    39. public T getFront(){
    40. return this.contain.getFront();
    41. }
    42. public T getBack(){
    43. return this.contain.getBack();
    44. }
    45. public int size(){
    46. return this.contain.size();
    47. }
    48. public Iterator iterator(){
    49. return this.contain.iterator();
    50. }
    51. }
    52. class stack implements Iterable{
    53. private stack_ifc contain;
    54. public stack(stack_ifc ifc){
    55. this.contain = ifc;
    56. }
    57. public Iterator iterator(){
    58. return this.contain.iterator();
    59. }
    60. public void pop(){
    61. this.contain.popFront();
    62. }
    63. public void push(T data){
    64. this.contain.pushFront(data);
    65. }
    66. public int size(){
    67. return this.contain.size();
    68. }
    69. }
    70. public class list implements deque_ifc,Iterable,stack_ifc{
    71. static public class listNode{
    72. private T data;
    73. private listNode next;
    74. private listNode front;
    75. public void setNext(listNode next){
    76. this.next=next;
    77. }
    78. public listNode getNext(){
    79. return this.next;
    80. }
    81. public void setData(T newData){
    82. this.data=newData;
    83. }
    84. public T getData(){
    85. return data;
    86. }
    87. public listNode(T data){
    88. this.data=data;
    89. }
    90. public listNode(){}
    91. }
    92. private class listIterator implements Iterator{//
    93. private listNode iteratorPointer;
    94. listIterator(){
    95. iteratorPointer=head;
    96. }
    97. @Override
    98. public boolean hasNext() {
    99. return iteratorPointer.next != tail && iteratorPointer != null;
    100. }
    101. @Override
    102. public T next() {
    103. iteratorPointer=iteratorPointer.next;
    104. return iteratorPointer.data;
    105. }
    106. }
    107. public void pushFront(T data){
    108. listNode newNode=new listNode(data);
    109. listNode first = head.next;
    110. head.next = newNode;
    111. newNode.front = head;
    112. first.front = newNode;
    113. newNode.next = first;
    114. size++;
    115. }
    116. public void pushBack(T data){
    117. listNode newNode = new listNode(data);
    118. listNode back = tail.front;
    119. tail.front=newNode;
    120. newNode.next=tail;
    121. back.next=newNode;
    122. newNode.front=newNode;
    123. size++;
    124. }
    125. public void popBack() {
    126. listNode node = tail.front.front;
    127. tail.front = node;
    128. node.next = tail;
    129. size--;
    130. }
    131. public void popFront() {
    132. listNode node = head.next.next;
    133. head.next = node;
    134. node.front = head;
    135. size--;
    136. }
    137. public Iterator iterator(){
    138. return new listIterator();
    139. }
    140. public listNode begin() {
    141. return head.next;
    142. }
    143. public listNode end() {
    144. return tail;
    145. }
    146. public int size() {
    147. return size;
    148. }
    149. @Override
    150. public T getFront() {
    151. if(size!=0) return head.next.data;
    152. return null;
    153. }
    154. @Override
    155. public T getBack() {
    156. if(size!=0) return tail.front.data;
    157. return null;
    158. }
    159. list() {
    160. head = new listNode();
    161. tail = new listNode();
    162. head.next = tail;
    163. tail.front = head;
    164. }
    165. private listNode head, tail;
    166. private int size;
    167. @FunctionalInterface
    168. private interface noPara{
    169. void test();
    170. }
    171. static public void main(String[] None){
    172. deque que = new deque(new list());
    173. for (int i = 0; i < 10; i++) {
    174. que.pushBack(i);
    175. }
    176. System.out.println("deque iterator");
    177. for (Iterator t = que.iterator(); t.hasNext();) {
    178. Integer data = t.next();
    179. System.out.printf("%d ", data);
    180. }
    181. System.out.println();
    182. System.out.println("deque iterable");
    183. for (Integer t : que) {
    184. System.out.printf("%d ", t);
    185. }
    186. System.out.println();
    187. stack stack_int = new stack(new list());
    188. for (int i = 0; i < 10; i++) {
    189. stack_int.push(i);
    190. }
    191. System.out.println("stack iterator");
    192. for (Iterator t = stack_int.iterator(); t.hasNext();) {
    193. Integer data = t.next();
    194. System.out.printf("%d ", data);
    195. }
    196. System.out.println();
    197. System.out.println("stack iterator");
    198. for (Integer t : stack_int) {
    199. System.out.printf("%d ", t);
    200. }
    201. }
    202. }

  • 相关阅读:
    【Java】类和接口的区别
    【进程概念④】:进程地址空间(虚拟内存与物理内存)
    Elasticsearch 8.9 Bulk批量给索引增加数据源码
    led台灯如何挑选?2022双十一什么样的台灯对眼睛好
    142.如何个性化推荐系统设计-2
    python基础---文件基本操作(20)
    零钱兑换问题
    在vue3中通过vue-i18n实现国际化多语言切换
    electron-vite:轻松保护你的 Electron 源代码
    macOS Sonoma 桌面小工具活学活用!
  • 原文地址:https://blog.csdn.net/weixin_62953519/article/details/127651567