java的String:==和equals()区别

项目场景:

做MIT软件构造实验:Problem Set 2: Poetic Walks,实现Graph的implement

CMU实验网站


问题描述:

问题是这样的,我定义了如下的一个类Edge,

class Edge<L> {
    
    // TODO fields
    private final L sou;
    private final L tar;
    private final Integer wei;
    // Abstraction function:
    //   sou is the source, tar is the target, wei is the weight on the directed edge from source to target
    // Representation invariant:
    //   true
    // Safety from rep exposure:
    //   the fields are all private final
    
    // TODO constructor
    public Edge(L source,L target,Integer weight) {
    	sou=source;
    	tar=target;
    	wei=weight;
    	checkRep();
    }
    // TODO checkRep
    public void checkRep() {
   
    	assert wei>0;
    	assert sou!=null;
    	assert tar!=null;
    
    }
    
    // TODO methods
    //防御式拷贝
    public L getSource() {
    	checkRep();
    	return sou;
    }
   
    public L getTarget() {
    	checkRep();
    	return tar;
    }
    public Integer getWeight() {
    	checkRep();
    	return wei;
    }
  
    // TODO toString()
    public String toString() {
    	checkRep();
    	return this.sou+"->"+this.tar+" weight:"+this.wei+"\n";
    }
    
}

现在我定义了一个List,里面的元素都是Edge,但是我想要比较两个Edge的source是否是一样的,发现如果直接用==,得到的结果永远是false,只有用equals方法才可以正确比较。

	//first version always false
	if(edges.get(i).getSource()==source)
	//second version wright answer
	if(edges.get(i).getSource().equals(source) )

而且最玄学的是,我在test里面跑的时候没有问题,但是将Graph作接口引入到了poem代码里面的时候这个问题才发现。

现在想想,这是因为我Junit测试的时候,输入的L都是常字符串,就是"a","b"这种直接赋值的,这种好像是= =里面可以正常判断的。部分测试代码如下。

  @Test
    public void testSourcesAndTarget() {
    	Graph<String> g=emptyInstance();
    	String a="a";
    	String b="b";
    	String c="c";
    	g.add(a);
    	g.add(b);
    	g.add(c);
    	g.set(a, b, 1);
    	g.set(a, c, 1);
    	g.set(c, b, 1);
    	Map<String, Integer> res=g.targets(a);
    	assertEquals(true,1==res.get(b));
    	assertEquals(true,1==res.get(c));
    	Map<String, Integer> res1=g.sources(b);
    	assertEquals(true,1==res1.get(a));
    	assertEquals(true,1==res1.get(c));
    	
    }

原因分析:

后来我在想,为什么会发生这种事情呢?
经过调查,我发现,由于我在poem里面应用的是String代替L。
String可以用= =和equals()方法比较,==是比较两个字符串的首地址,equals()方法是比较两个字符串的内容。所以对于两个不同的Edge里面的String类型的source,当然用= =方法比较不出来的了。所以,以后比较String相等,保险起见,还是都用equals()吧

简单的测试用例(来源


 String s1,s2,s3 = "abc", s4 ="abc" ;
		        s1 = new String("abc");
		        s2 = new String("abc");
		        System.out.println("s1==s2:"+(s1==s2));//false
		        System.out.println("s1==s3:"+(s1==s3));//false
		        System.out.println("s3==s4:"+(s3==s4));//true
		        System.out.println("s1.equals(s2):"+(s1.equals(s2)));//true
		        System.out.println("s1.equals(s3):"+(s1.equals(s3)));//true
		        System.out.println("s3.equals(s4):"+(s3.equals(s4)));//true

拓展

注意:对于s3和s4来说,有一点不一样要引起注意,由于s3和s4是两个字符,串常量所生成的变量,其中所存放的内存地址是相等的,所以s3==s4是true(即使没有s3=s4这样一个赋值语句)

另外对于int等基本类型比较,只能用==,没有equals()方法

对于基本类型的包装类型,比如Boolean、Character、Byte、Shot、Integer、Long、Float、Double等的引用变量,==是比较地址的,而equals是比较内容的(equals()被重写了)。

对于object函数,equals()也是比较首地址,可以在object函数里面重写equals方法,来达到比较的目的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值