设计思路:
- 创建一个LinkImpl类负责给用户提供数据,负责Node节点的动态挂载。
- 定义一个接口Link(标准),来提供一个链表应该具有的方法。
- 在LinkImpl类内部封装一个类Node保存真实的数据(方便访问彼此的私有属性)
- 创建一个工厂类(把LinkImpl类的实例化交给工厂,让用户去创建对象)
- Test(测试类供用户使用,只关心数据)
代码实现
interface ILink {
boolean add(Object data);
int contains(Object data);
boolean remove(Object data);
Object set(int index,Object newData);
Object get(int index);
void clear();
Object[] toArray();
int size();
void printLink();
}
class LinkImpl implements ILink {
private Node head;
private Node last;
private int size;
private class Node {
private Node prev;
private Object data;
private Node next;
public Node(Node prev, Object data, Node next) {
this.prev = prev;
this.data = data;
this.next = next;
}
}
@Override
public boolean add(Object data) {
Node temp = this.last;
Node newNode = new Node(temp, data,null);
this.last = newNode;
if (this.head == null) {
this.head = newNode;
}else {
temp.next = newNode;
}
this.size++;
return true;
}
@Override
public int contains(Object data) {
if (data == null) {
int i = 0;
for (Node temp=head; temp!=null; temp=temp.next) {
if (temp.data == null) {
return i;
}
i++;
}
}else {
int i = 0;
for (Node temp=head; temp!=null; temp=temp.next) {
if (data.equals(temp.data)) {
return i;
}
i++;
}
}
return -1;
}
@Override
public boolean remove(Object data) {
if (data == null) {
for (Node temp=head; temp!=null; temp=temp.next) {
if (temp.data == null) {
unLink(temp);
return true;
}
}
}else {
for (Node temp=head; temp!=null; temp=temp.next) {
if (data.equals(temp.data)) {
unLink(temp);
return true;
}
}
}
return false;
}
@Override
public Object set(int index, Object newData) {
if (!isLinkIndex(index)) {
return null;
}
Node node = node(index);
Object elementData = newData;
node.data = newData;
return elementData;
}
@Override
public Object get(int index) {
if (!isLinkIndex(index)) {
return null;
}
return node(index).data;
}
@Override
public void clear() {
for (Node temp=head; temp!=null; ) {
Node node = temp.next;
temp.data = null;
temp.prev = temp.next = null;
temp = node;
this.size--;
}
}
@Override
public Object[] toArray() {
Object[] result = new Object[this.size];
int i = 0;
for (Node temp=head; temp!=null; temp=temp.next) {
result[i++] = temp.data;
}
return result;
}
@Override
public int size() {
return this.size;
}
@Override
public void printLink() {
Object[] data = this.toArray();
for (Object temp: data) {
System.out.print(temp+"--->");
}
System.out.println();
}
public boolean isLinkIndex(int index) {
return index>=0 && index<this.size;
}
public Node node(int index) {
if (index < (size>>1)) {
Node temp = this.head;
for (int i=0; i<index; i++) {
temp = temp.next;
}
return temp;
}else {
Node temp = this.last;
for (int i=size-1; i>index; i--) {
temp = temp.prev;
}
return temp;
}
}
public Object unLink(Node x) {
Object elementData = x.data;
Node prev = x.prev;
Node next = x.next;
if (prev == null) {
this.head = next;
}else {
prev.next = next;
x.prev = null;
}
if (next == null) {
this.last = prev;
}else {
prev.next = next;
next.prev = prev;
x.next = null;
}
x.data = null;
this.size--;
return elementData;
}
}
class Factory {
private Factory(){}
public static ILink getILinkInstance() {
return new LinkImpl();
}
}
public class Test {
public static void main(String[] args) {
ILink1 link = Factory.getILinkInstance();
link.add("火车头");
link.add("车厢1");
link.add("车厢2");
link.add("车厢3");
link.add(null);
link.add("火车尾");
link.printLink();
System.out.println("size:"+link.size());
System.out.println(link.contains(null));
System.out.println(link.contains(3));
System.out.println(link.get(3));
link.set(0,"bit");
System.out.println(link.remove("车厢2"));
link.printLink();
link.clear();
System.out.println(link.size());
}
}