一.前言
这几周作业的难度有所提升。主要表现在耗在每个题上的时间有所增加。要求的增加,类的设计更复杂,知识点的涉及也更为广泛。
二.设计与分析
期中考试的三道题分别是点与线,点线面问题重构,点线面问题再重构。考察知识点分别是类,继承与多态,容器类。这在题目上已经很明确指出了。期中考试相对较简单,因为三题类图已全部给出。只要老老实实照着写,及格是没有问题的。此处注意构造方法,并且属性为私有。第二题新增类Plane和抽象类Element,并要求Element为三个类的父类。使用关键词extends。例如class Line extends Element{},类Line继承类Element,Line为Element的子类。因为Element中display为抽象方法,所以在子类中重载,使用关键词 @Override 。第三题在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList<Element>
类型的对象。泛型在我理解能力中算是比较难的部分,花了不少时间才磨出来丁点。这题涉及到的泛型内容不多,更要注意的是越界问题,所以在动键盘前先在草稿纸上设计好。
练习
学习通上链表类练习分为两个阶段,第一次是实现单向链表,具体类和结构如上。在这里被泛型问题困扰了好久,好在看了老师的test后了解了。第二次练习是基于第一次上的迭代,要求实现双向链表,同时题目要求末尾新增了几个方法,小心漏掉。这次练习要比上一次更小心,因为多了个前驱指针,稍有不慎就会瞎指一气。如下是我的部分代码。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
DoubleLinkedList<String> list = new DoubleLinkedList<>();
list.add("aaaaaa");
list.add("bbbbbb");
list.add("cccccc");
list.add("dddddd");
list.printList();
list.add(3,"333333");
list.printList();
list.remove(2);
list.printList();
System.out.println("finish");
}
}
class Node<E> {
private E data;//数据域,类型为泛型E
private Node<E> next;//后继引用(指针)
private Node<E> previous;//前驱引用(指针)
public Node() {
}
public Node(E data, Node<E> next) {
super();
this.data = data;
this.next = next;
}
public void set(E data) {
this.data=data;
}
public E get() {
return this.data;
}
public void setN(Node<E> next) {
this.next = next;
}
public Node<E> getN(){
return this.next;
}
public void setPre(Node<E> previous) {
this.previous = previous;
}
public Node<E> getPre(){
return this.previous;
}
}
interface DoubleLinkedListImpl<E> {
public boolean isEmpty();//
public int size();//
public E get(int index);//
public void remove(int index);//
public void add(int index,E theElement);//
public void add(E element);//
public void printList();//
public E getFirst();
public E getLast();
public void remove();
}
class DoubleLinkedList<E> implements DoubleLinkedListImpl<E>{//我的
private Node<E> curr;
private Node<E> tail;
private Node<E> head;
private int size = 0;
public DoubleLinkedList() {
super();
head = new Node<E>();
this.head.setN(null);
this.head.setPre(null);
curr = tail = null;
this.size =0;
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public int size() {
return size;
}
@Override
public E get(int index) {
if (size==0)
return null;
else if(index<1||index>size)
return null;
curr = head;
for(int i=0;i<index;i++) {
curr = curr.getN();
}
return curr.get();
}
@Override
public void remove(int index) {//删除
if (size==0)
return;
else if(index<1||index>size) {
return;
}
if(index==1) {
head = head.getN();
head.setPre(null);
} else if(index == size) {
tail = tail.getPre();
tail.setN(null);
} else {
curr = head;
for(int i=1;i<index;i++) {
curr = curr.getN();
}
curr.getPre().setN( curr.getN() );
curr.getN().setPre(curr.getPre());
}
size--;
}
@Override
public void add(int index, E theElement) {//插入
if( index<1 || index>this.size+1 )
return ;
Node<E> curr = new Node<>();
curr.set(theElement);
curr.setN(null);
curr.setPre(null);
if(size == 0) {
head=curr;
tail=curr=head;
//
tail.setN( null );
} else if(index==1){
curr.setN(head);
head.setPre(curr);
head = head.getPre();
head.setPre(null);
} else if(index == size+1) {
curr.setPre(tail);
tail.setN(curr);
tail = tail.getN();
tail.setN(null);
} else {
Node<E> tourist = head;
for(int i =1;i<index;i++) {
tourist = tourist.getN();
}//
tourist.getPre().setN(curr);
curr.setPre(tourist.getPre());
tourist.setPre(curr);
curr.setN(tourist);
}
size++;
}
@Override
public void add(E element) {//尾部添加
add(this.size+1,element);
}
@Override
public void printList() {
curr = head;
for(int i = 0; i<size;i++) {
curr.get();
System.out.println(curr.get());
curr=( curr.getN() );
}
}
@Override
public E getFirst() {
return head.get();
}
@Override
public E getLast() {
return tail.get();
}
@Override
public void remove() {
this.remove(size);
}
}
图形类我就不多讲了。70分的题一分都没拿到。
三.踩坑心得
都在前面了
四.改进建议
链表练习中,虽然实现了大部分功能和双向链表结构,但是前驱指针并没有应用。
五.总结
最开心的是学到了正则表达式,终于可以在输入上轻松一点了,没学之前处理输入信息处理得要疯。还有就是链表练习,让我回忆起了以前学C的快乐()时光。泛型和多态也渐渐熟练了,至少做到了不再什么都要百度。最需要学习的是图形类。