使用链表
之前给出的链表严格来讲不能够使用,而且意义也不大,因为它所能操作的数据类型只有String,毕竟String保留的数据比较少,所以可以采用自定义类进行链表操作
由于链表中要保存的对象需要保存实现contains(),remove()等功能,所以在类中可提供对象比较方法支持
定义一个保存图书信息的类
class Book{ private String title; private double price; public Book(String title , double price){ this.title = title; this.price = price; } public String getInfo(){ return "图书名称: "+this.title + " 图书价格: " + this.price; } public boolean compare(Book book){ if(this == book){ return true; } if(book == null){ return false; } if(book.title.equals(this.title) && book.price == this.price){ return true; } return false; } }
修改链表实现
class Link{ // 链表类,外部只能看这一个类 // 定义在内部,主要为Link类服务 private class Node{ // 定义的节点类 private Book data; // 保存数据 private Node next; // 引用关系 public Node(Book data){ this.data = data; } public void AddNode(Node newNode){ if(this.next == null){ // 当前的下一个节点为空 this.next = newNode; }else{ // 向后继续保存 this.next.AddNode(newNode); } } public void printNode(){ // 打印Node信息 System.out.println(this.data); if( this.next != null){ this.next.printNode(); } } // 第一次调用(Link): this = Link.root // 第二次调用 (Node) : this = Link.root.next public boolean containsNode(Book data){ if (data.compare(this.data)){ // 当前节点数据为要查询数据 return true; //后面不再查询了 }else{ //当前节点数据不满足查询要求 if (this.next != null){ // 有后续节点 return this.next.containsNode(data); }else{ // 没有后续节点了 return false; // 没得查了 } } } public Book getNode(int index){ // 使用当前的foot内容与要查询的索引进行比较 // 随后将foot的内容自增,目的是为了下次查询方便 if (Link.this.foot++ == index){ // 如果等于,为查询的索引 return this.data; // 返回当前节点数据 }else{ // 现在应该继续向后查询 return this.next.getNode(index); } } public void setNode(int index,Book data){ // 使用当前的foot内容与要修改的索引进行比较 // 随后将foot的内容自增,目的是为了下次修改方便 if(Link.this.foot++ == index){ // 如果等于,为要修改的索引 this.data = data; // 重新赋值 }else{ //继续向后查找要修改的索引 this.next.setNode(index,data); } } // 第一次调用:(Link) pervious = Link.root、this=Link.root.next // 第二次调用:(Node) pervious = this.root.next this=this.root.next.next // 要传递上一个节点以及要删除的数据 public void removeNode(Node previous,Book data){ if (data.compare(this.data)){ // 当前节点为要删除节点 previous.next = this.next; // 空出当前节点 }else{ //应该向后继续查询 this.next.removeNode(this,data); } } // 第一次调用:(Link) this = Link.root // 第二次调用:(Node) this = Link.root.next public void toArrayNode(){ Link.this.retArray[Link.this.foot ++] = this.data; if (this.next != null){ // 有后续元素 this.next.toArrayNode(); } } // ===================以上为内部类============================ } private Node root; // 根结点 private int count = 0; // 保存元素的个数 private int foot = 0; private Book [] retArray; // 返回的数组 public Book get (int index){ if (index > this.count){ // 超过了查询的范围 return null; } this.foot = 0; // 表示从前向后查询 return this.root.getNode(index); // 查询过程交给Node类处理 } public void add(Book data){ // 假设不允许有null if (data == null){ return ; } Node newNode = new Node(data); // 要保存的数据 if (this.root == null){ // 如果当前没有根节点,则设置为根节点 this.root = newNode; // 保存根节点 }else{ // 存在根节点,则到下一节点找保存数据 this.root.AddNode(newNode); } this.count ++; // 每一次保存完成后数量加一 } public int size(){ // 取得保存的数据量 return this.count; } public boolean isEmpty(){ //判断链表是否为空 return this.root == null; } public boolean contains(Book data){ // 现在没有要查询的数据,要节点也不保存数据 if ( data == null || this.root == null ) { return false; //没有查询结果 } return this.root.containsNode(data); } public void set(int index,Book data){ if(index > this.count){ return ; //结束方法调用 } this.foot = 0; // 重新设置foot属性的内容 this.root.setNode(index,data); //交给Node类设置数据内容 } public void remove(Book data){ if(this.contains(data)){ // 一定要保证数据存在 // 要删除数据是否是根节点数据 // root是内部类的对象,此处直接访问了内部类的私有操作 if (data.compare(this.root.data)){ // 为要删除节点 this.root = this.root.next; // 突出当前根节点 }else{ // 不是根元素 // 此时根元素已经判断过了,从第二个元素开始判断 this.root.next.removeNode(this.root,data); } this.count --; } } public Book [] toArray(){ if (this.root == null){ return null; } this.foot = 0; // 需要脚标控制 this.retArray = new Book[this.count]; //根据保存内容开辟数组 this.root.toArrayNode(); //交给Node类处理 return this.retArray; } public void print(){ // 打印所有Node信息 this.root.printNode(); } }
编译通过
实现测试

class Book{ private String title; private double price; public Book(String title , double price){ this.title = title; this.price = price; } public String getInfo(){ return "图书名称: "+this.title + " 图书价格: " + this.price; } public boolean compare(Book book){ if(this == book){ return true; } if(book == null){ return false; } if(book.title.equals(this.title) && book.price == this.price){ return true; } return false; } } class Link{ // 链表类,外部只能看这一个类 // 定义在内部,主要为Link类服务 private class Node{ // 定义的节点类 private Book data; // 保存数据 private Node next; // 引用关系 public Node(Book data){ this.data = data; } public void AddNode(Node newNode){ if(this.next == null){ // 当前的下一个节点为空 this.next = newNode; }else{ // 向后继续保存 this.next.AddNode(newNode); } } public void printNode(){ // 打印Node信息 System.out.println(this.data); if( this.next != null){ this.next.printNode(); } } // 第一次调用(Link): this = Link.root // 第二次调用 (Node) : this = Link.root.next public boolean containsNode(Book data){ if (data.compare(this.data)){ // 当前节点数据为要查询数据 return true; //后面不再查询了 }else{ //当前节点数据不满足查询要求 if (this.next != null){ // 有后续节点 return this.next.containsNode(data); }else{ // 没有后续节点了 return false; // 没得查了 } } } public Book getNode(int index){ // 使用当前的foot内容与要查询的索引进行比较 // 随后将foot的内容自增,目的是为了下次查询方便 if (Link.this.foot++ == index){ // 如果等于,为查询的索引 return this.data; // 返回当前节点数据 }else{ // 现在应该继续向后查询 return this.next.getNode(index); } } public void setNode(int index,Book data){ // 使用当前的foot内容与要修改的索引进行比较 // 随后将foot的内容自增,目的是为了下次修改方便 if(Link.this.foot++ == index){ // 如果等于,为要修改的索引 this.data = data; // 重新赋值 }else{ //继续向后查找要修改的索引 this.next.setNode(index,data); } } // 第一次调用:(Link) pervious = Link.root、this=Link.root.next // 第二次调用:(Node) pervious = this.root.next this=this.root.next.next // 要传递上一个节点以及要删除的数据 public void removeNode(Node previous,Book data){ if (data.compare(this.data)){ // 当前节点为要删除节点 previous.next = this.next; // 空出当前节点 }else{ //应该向后继续查询 this.next.removeNode(this,data); } } // 第一次调用:(Link) this = Link.root // 第二次调用:(Node) this = Link.root.next public void toArrayNode(){ Link.this.retArray[Link.this.foot ++] = this.data; if (this.next != null){ // 有后续元素 this.next.toArrayNode(); } } // ===================以上为内部类============================ } private Node root; // 根结点 private int count = 0; // 保存元素的个数 private int foot = 0; private Book [] retArray; // 返回的数组 public Book get (int index){ if (index > this.count){ // 超过了查询的范围 return null; } this.foot = 0; // 表示从前向后查询 return this.root.getNode(index); // 查询过程交给Node类处理 } public void add(Book data){ // 假设不允许有null if (data == null){ return ; } Node newNode = new Node(data); // 要保存的数据 if (this.root == null){ // 如果当前没有根节点,则设置为根节点 this.root = newNode; // 保存根节点 }else{ // 存在根节点,则到下一节点找保存数据 this.root.AddNode(newNode); } this.count ++; // 每一次保存完成后数量加一 } public int size(){ // 取得保存的数据量 return this.count; } public boolean isEmpty(){ //判断链表是否为空 return this.root == null; } public boolean contains(Book data){ // 现在没有要查询的数据,要节点也不保存数据 if ( data == null || this.root == null ) { return false; //没有查询结果 } return this.root.containsNode(data); } public void set(int index,Book data){ if(index > this.count){ return ; //结束方法调用 } this.foot = 0; // 重新设置foot属性的内容 this.root.setNode(index,data); //交给Node类设置数据内容 } public void remove(Book data){ if(this.contains(data)){ // 一定要保证数据存在 // 要删除数据是否是根节点数据 // root是内部类的对象,此处直接访问了内部类的私有操作 if (data.compare(this.root.data)){ // 为要删除节点 this.root = this.root.next; // 突出当前根节点 }else{ // 不是根元素 // 此时根元素已经判断过了,从第二个元素开始判断 this.root.next.removeNode(this.root,data); } this.count --; } } public Book [] toArray(){ if (this.root == null){ return null; } this.foot = 0; // 需要脚标控制 this.retArray = new Book[this.count]; //根据保存内容开辟数组 this.root.toArrayNode(); //交给Node类处理 return this.retArray; } public void print(){ // 打印所有Node信息 this.root.printNode(); } } public class LinkDemo{ public static void main(String args[]){ Link all = new Link(); all.add(new Book("java开发",69.8)); all.add(new Book("jsp开发",79.8)); all.add(new Book("oracle开发",89.8)); System.out.println("链表长度:"+all.size()); all.contains(new Book("java开发",69.8)); all.remove(new Book("oracle开发",89.8)); Book [] books = all.toArray(); for (int i=0; i<books.length; i++){ System.out.println(books[i].getInfo()); } } }
测试结果
虽然以上的代码麻烦,(如果不让写链表,只使用方法),那么发现程序没有了长度的限制。链表在内存保存的,如果存放的太多了,程序就会变慢
链表最好的使用就是横向替代对象数组