一、问题描述
写了个实现单链表的代码,其中有一条按值删除,测试单链表插入int 1-1000,删除方法接受的参数是Object类型,但是发现删除的时候,只能删除到127。到128就石沉大海了。
下面是单链表结点数据类型:
public class SingleListNode {
private Object element;
private SingleListNode next;
public SingleListNode(Object it,SingleListNode nextval) {element = it;next = nextval;}
public SingleListNode(SingleListNode nextval) {next=nextval;}
public Object getElement() {return element;}
public void setElement(Object it) {this.element = it;}
public SingleListNode getNext() {return next;}
public void setNext(SingleListNode nextval) {this.next = nextval;}
}
?单链表数据类型,里面有插入和删除的功能:
public class SLList implements LinkedList {
private SingleListNode head;
public SingleListNode getHead() {
return head;
}
public void setHead(SingleListNode hd) {
this.head = hd;
}
public SLList() {
head=new SingleListNode(null);
}
public void inserttoHead(Object item) {
// 将头结点的子节点设置为新节点的子节点
// 将新节点作为头结点的子节点
head.setNext(new SingleListNode(item,head.getNext()));
}
public void removebyValue(Object item) {
// System.out.println(item);
/**
* 用一个游标来记录当前节点的父节点
*/
if(isEmpty()==true)return;
SingleListNode curNode = head.getNext();
SingleListNode curNode_father = head;
if((int)item>127)System.out.println(curNode.getElement());
/**
* 当传入的item是int,且>127时,如128,我们发现即使curNode.getElement()的值是128那也不会被判定为相等
*
*/
while((curNode!=null)&&(curNode.getElement()!=item)) {
if((int)item>127) {System.out.println(curNode.getElement());}
curNode_father = curNode;
curNode = curNode.getNext();
}
if((curNode!=null)&&(curNode.getElement()==item)) {
curNode_father.setNext(curNode.getNext());
System.out.println(item);
}
}
}
测试代码:
public static void main(String[] args) {
// TODO Auto-generated method stub
SLList sll = new SLList();
SingleListNode head = sll.getHead();
SingleListNode curNode = sll.getHead();
long startnsTime = System.nanoTime();//精确到微秒
for(int i=1000;i>0;i--) {
sll.inserttoHead(i);
}
long endTime = System.currentTimeMillis();
long endnsTime = System.nanoTime();//精确到纳秒
System.out.println("插入到头1~1001时间:"+(endTime-startTime)+"ms\t"+(endnsTime- startnsTime)+"ns");
int i=0;
long startTime_removebyvalue_allfromhead = System.nanoTime();
while((i++)<1001) {
sll.removebyValue(i);// 1-10
}
long endTime_removebyvalue_allfromhead = System.nanoTime();
System.out.println("按值从头删除:"+(endTime_removebyvalue_allfromhead-startTime_removebyvalue_allfromhead)+"ns");
}
运行过程中发现只能删除到127,从128开始无法删除,经过测试,是从删除代码的这段命令开始变化:
curNode.getElement()!=item
就是超过127的int值不能与被赋予同样int值的Object再等值了。
二、问题解析
int是一种基本数据类型,是原语。不会作为对象来处理。
public class test {
public static void main(String[] args) {
Object it = new Object(); // Object类型
int i=127; // int 基本数据类型
it=i; // 看下赋值后类型变化
System.out.println("it类型:"+it.getClass().getName()+"\tit的值:"+it); // 结果是:it类型:java.lang.Integer
// 然后来测试下是否相等
// 已知it已经是Integer类型
if(it==(Object)i) {
System.out.println("it类型:"+it.getClass().getName()+"\t(Object)i类型:"+((Object)i).getClass().getName());
}
if((int)it==i) {
System.out.println(i);
}
}
}
当 i 的值是127 输出:
it类型:java.lang.Integer it的值:127
it类型:java.lang.Integer (Object)i类型:java.lang.Integer
127
当 i 的值是128 输出:
it类型:java.lang.Integer it的值:128
128
结果分析:
1. 类型解析
int 赋值给 Object,Object会被转换成Integer类型。基本数据类型是不能直接赋值给对象类型的。int是基本数据类型,有两种方式,可以使两者相等:
- int类型转换成Integer类型,但其实是被转换成int的包装类java.lang.Integer。在赋值之后it会被修改为Integer类型;
it==(Object)i - Integer转换成it类型,但其实是Integer拆箱成int类型。
(int)it==i
也就是说在【问题描述】的单链表中,在测试时插入的时候,是int类型值传进单链表,而单链表的接口是Object类型,也就是插入后是作为Integer类型存储。
然后在按值删除的时候,传入的还是int类型,接口是Object类型,也就是传入后是成为了Integer类型。
2. 包装局限
可以发现,当 i 取值128时,?it==(Object)i 为false,这就要考虑到一个问题
|