7.数据内容查询
在一个集合里面往往会保存大量的数据,有时需要判断某个数据是否存在,这是就可以利用迭代的方法进行对象比较(equals()方法)来完成判断。
(1)【ILink】在ILink接口中定义数据查询方法。
/**
* 查询指定内容是否存在,要求查询对象所在类覆写equals()方法
* @param data要查找的数据
* @return 数据存在返回true,否则返回false
*/
public boolean contains(E data);
(2)【LinkImpl.Node】节点递归处理以及数据判断在Node类中完成,定义以下方法。
/**
* 判断指定数据是否存在
* @param data要查找的数据
* @return 数据存在返回true,否则返回false
*/
public boolean containsNode(E data){
if (this.data.equals(data)){ //对象比较
return true; //数据存在
}else {
if (this.next==null){ //没有后续节点
return false; //没有找到数据
}else { //后续节点判断
return this.next.containsNode(data);
}
}
}
(3)【LinkImpl】在LinkImpl子类中覆写contains()方法。
@Override
public boolean contains(E data){
if (data==null){
return false; //没有数据返回false
}
return this.root.containsNode(data); //交由Node类判断
}
(4)【测试类】编写测试类测试数据查找
public class Main {
public static void main(String args[]) {
ILink<String> link = new LinkImpl<String>();
link.add("浩汉");
link.add("浩渺");
link.add("JOE");
System.out.println(link.contains("浩汉"));
System.out.println(link.contains("世界"));
}
}
程序执行结果:
true("link.contains("浩汉")"代码执行结果)
false("link.contains("世界")"代码执行结果)
在调用contains()方法时,利用的时equals()方法实现对象比较处理。如果现在在链表中保存的是自定义类对象,则对象一定要覆写equals()方法。
8.删除链表结构
链表作为动态数组除了可以任意地进行长度的扩充之外,还可以实现指定数据的删除操作,由于链表是一个Node对象的集合,所以在删除数据时需要考虑以下两种情况。
情况1:要删除的对象是根节点。
由于根节点在链表类(LinkImpl)中保存的是成员属性,一旦要删除的是根节点内容,则可以将第二个节点(根节点.next)作为根节点,操作如图。
情况1:要删除的是子节点。
所有的子节点的控制全部都是由Node类实现的,所以此时可以直接在Node类中修改要删除节点的引用,修改原则为删除节点上一节点.next=删除节点.next,操作如图。
(1)【ILink】在ILink接口中增加一个数据删除方法。
/**
* 删除指定内容的数据,需要利用equals()方法进行比较
* @param data 要删除的数据
*/
public void remove(E data);
(2)【LinkImpl.Node】在Node类中追加节点的删除操作。
/**
* 删除指定数据对应的节点内容
* @param previous 要删除节点的上一个节点
* @param data 要删除的数据
*/
public void removeNode(Node previous,E data){
if (this.data.equals(data)){ //数据内容比较
previous.next=this.next; //【删除】空出当前节点
}else { //数据内容不匹配
if (this.next!=null){ //有后续节点
this.next.removeNode(this,data);//向后继续删除
}
}
}
(3)【LinkImpl】在LinkImpl子类中实现节点的删除。
@Override
public void remove(E data){
if (this.contains(data)){ //判断数据是否存在
if (this.root.data.equals(data)){ //根节点为要删除节点
this.root=this.root.next; //修改根节点引用
}else { //交由Node类负责删除
this.root.next.removeNode(this.root,data);
}
this.count--; //元素数量减少
}
}
LinkImpl子类需要进行根节点的存储,所以对于根节点的数据删除将有LinkImpl子类完成,而对于子节点的删除将交由Node.removeNode()方法处理。需要注意的是,元素一旦成功删除后,需要对count成员属性进行修改。
9.情况链表数据
链表中所有的数据都是依据根节点进行的引用保存,如果想要进行链表数据的整体删除,直接删除掉根节点的数据即可。
(1)【ILink】在ILink接口中追加清空链表方法。
/**
* 清空链表中的所有元素
*/
public void clean();
(2)【LinkImpl】在LinkImpl子类中覆写clean()方法。
@Override
public void clean(){
this.root=null; //断开根节点引用
this.count=; //元素个数清零
}
所有链表中的数据都是被根元素引用的,当根元素设置为null后,所有保存的元素都将成为垃圾并等待内存释放。