[Java ] 有关LinkedList<T> contains方法的疑惑和对源码的分析

目录

背景 

解决方法及原因


背景 

本来是写一个简单的类Circle, 实现可以“按照半径排序”“按照半径查找”

但在用到contains方法的时候, 出现了一些状况

代码如下:


import java.util.*;
 
class Circle implements Comparable<Circle>{
    double radius;
 
    Circle(double r){
        this.radius = r;
    }
 
    Circle() {
    }
 
    public double Get() {
        return radius;
    }
 
    public void Set(double radius) {
        this.radius = radius;
    }
    public double calculateArea(){
        return 3.14*radius*radius;
    }
    
    public boolean equals(Circle c2){

    	if(this.radius == c2.radius){
    		return true;
    	}
    	return false;
    }
    
    public int compareTo(Circle c2){
    	if(this.radius > c2.radius) return 1;
    	else if(this.radius > c2.radius) return -1;
    	else return 0;
    }
}
 
 
public class demo {
 
 
	public static void main(String[] args) {
		
		
		// TODO Auto-generated method stub
		Circle[] c = new Circle[5];
		c[0] = new Circle(2.0);
		c[1] = new Circle(1.0);
		c[2] = new Circle(4.0);
		c[3] = new Circle(1.0);
		c[4] = new Circle(9.0);
		
		
		LinkedList<Circle> cc = new LinkedList<Circle>();
		
		//利用LinkedList的add方法将多个Circle对象加入到LinkedList对象管理中
		for(Circle c1:c){
			cc.add(c1);
		}
		Iterator<Circle> it = cc.iterator();
		while(it.hasNext()){
			
			System.out.println(it.next().radius);
		}
		
		//查找指定半径的Circle对象
		//测试一
		if(cc.contains(new Circle(4.0))){
			System.out.println("存在半径为4.0的圆");
		}else{
			System.out.println("不存在半径为4.0的圆");
		}
		
		//测试二
		if(c[2].equals(new Circle(4.0))){
			System.out.println("存在半径为4.0的圆");
		}else{
			System.out.println("不存在半径为4.0的圆");
		}
		
		
		//按照半径对Circle对象进行排序
		
		Collections.sort(cc);
		System.out.println("排序后:");
		it = cc.iterator();
		while(it.hasNext()){
			
			System.out.println(it.next().radius);
		}
		
		//输出半径最大的Circle对象
	}
 
}

运行结果:

2.0
1.0
4.0
1.0
9.0
不存在半径为4.0的圆
存在半径为4.0的圆
排序后:
1.0
1.0
2.0
4.0
9.0

???测试一并没有如我们预期一般找到半径为4.0的圆

解决方法及原因

只需把euqals函数的参数类型改为Object即可

    public boolean equals(Object c2){
    	Circle c1=(Circle)c2;
    	if(this.radius == c1.radius){
    		return true;
    	}
    	return false;
    }

查看LinkedList.class文件,有关contains函数的原型是这样的

    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }

    public int indexOf(Object o) {
        int index = 0;
        if (o==null) {
            for (Entry e = header.next; e != header; e = e.next) {
                if (e.element==null)
                    return index;
                index++;
            }
        } else {
            for (Entry e = header.next; e != header; e = e.next) {
                if (o.equals(e.element))
                    return index;
                index++;
            }
        }
        return -1;
    }

所以我们测试一中真正调用的equals方法并不是自己写的(参数类型为Circle),而是 JDK 中LinkedList原生equals方法, 只有改一下参数类型才行

而测试二中我们单刀直入, 点名调用函参为Circle的equals, 自然结果是我们想要的

原文地址:https://www.cnblogs.com/Knight02/p/15799064.html