zoukankan      html  css  js  c++  java
  • equals和==的区别 (Java基础)

    1. == 是一个运算符。
    2.Equals则是string对象的方法,可以.(点)出来。
      
      我们比较无非就是这两种 1、基本数据类型比较 2、引用对象比较
      1、基本数据类型比较
      ==和Equals都比较两个值是否相等。相等为true 否则为false;
      
      2、引用对象比较
      ==和Equals都是比较栈内存中的地址是否相等 。相等为true 否则为false;
      
      需注意几点:
      1、string是一个特殊的引用类型。对于两个字符串的比较,不管是 == 和 Equals 这两者比较的都是字符串是否相同;
      2、当你创建两个string对象时,内存中的地址是不相同的,你可以赋相同的值。
      所以字符串的内容相同。引用地址不一定相同,(相同内容的对象地址不一定相同),但反过来却是肯定的;
      3、基本数据类型比较(string 除外) == 和 Equals 两者都是比较值;

    在谈论equals和==的区别前,我们先简单介绍一下JVM中内存分配的问题。

    JVM中 内存分为栈内存和堆内存。二者有什么区别呢?

    当我们创建一个对象(new Object)时,就会调用它的构造函数来开辟空间,将对象数据存储到堆内存中,与此同时在栈内存中生成对应的引用,当我们在后续代码中调用的时候用的都是栈内存中的引用,还需注意的一点,基本数据类型是存储在栈内存中。有了一定的了解 我们来看Equals和==的区别。

     

     

    首先equals和== 最大的区别是一个是方法一个是运算符,在Java中,二者比较的都是物理地址 而不是值得比较。

    我们举个例子这样比较直观。

    Student student1 = new Student();

    Student student2 = new Student();

    System.out.println(student1.equals(student2));

    System.out.println(student1 == student2);

    不论是用的是哪一种方法 最终的结果显示的都是false,大家不妨可以试一下。为什么呢?就是因为他们比较的不是对象中字段的值或者说本身对象的值,而比较的是物理地址。

    我们再来举一个例子。

    String a = new String("a");

    String b = new String("a");

    System.out.println(a == b);

    System.out.println(a.equals(b));

    当我们创建2个String对象是 我们会发现 执行的结果是 false true。为什么这次euqals返回的值编程了true?因为此时equals方法不单单是比较物理地址 同时也比较了值,

    String中 equals方法被重写 当物理地址不同时,会进一步比较值,代码如下:

    if(object instanceof String){}

    那么问题来了 当我调用

    System.out.println(student1.toString().equals(student2.toString()));时,结果又是怎样的?

    结果却返回了false.为什么呢?这就牵扯到了hashcode的问题。

    那么为了保证两个对象比较值相等有什么办法么?想必大家都试过重写equals方法,而最终的结果都不如人意。为什么?因为单单重写equals方法并不能改变hashcode值,在java中 首先比较的就是hashcode。那么如何结果这个问题?

    大家可以尝试 右键->source->generate hashcode() and equals() 来实现。

     

     

     

    public class EqualTest { 
    public static void main(String[] args) { 

        //对于基本类型的变量。"==""equal"的区别 
        int t1=57; 
        int t2=67; 
        int t3=124; 
        int t4=124; 
         
        //“==”对于基本数据类型,判断两个变量的值是否相等。 
        Boolean result1=(t1==t2); 
        Boolean result2=((t1+t2)==t3); 
        Boolean result3=(t3==t4); 
         
        System.out.println("/n/n-----t1==t2"+result1+"/n-----(t1+t2)=t3"+result2+"/n-----t3=t4"+result3); 
        //“equal”不能用于基本数据类型。只能用于类变量。对于基本数据类型要用其包装类。 
        Integer i1=new Integer(t1); 
        Integer i2=new Integer(t2); 
        Integer i3=new Integer(t3); 
        Integer i4=new Integer(t4); 
         
         
        Boolean ri1=i1.equals(i2); 
        Boolean ri2=i3.equals(i1+i2); 
        Boolean ri3=i3.equals(i4); 
         
        System.out.println("/n/n-----i1.equals(i2)"+ri1+"/n-----i3.equals(i1+i2)"+ri2+"/n-----i3.equals(i4)"+ri3); 
       
        //对于对象变量,"==""equal"的区别 

        String st1="wasiker "; 
        String st2="is super man"; 
        String st3="wasiker is super man"; 
        String st4="wasiker is super man"; 
         
        Boolean b1=(st1==st2); 
        Boolean b2=(st1+st2)==st3; 
        Boolean b3=(st3==st4); 
         
        System.out.println("/n/n-----st1==st2"+b1+"/n-----(st1+st2)==st3"+b2+"/n-----st3==st4"+b3); 

    //因为对象变量的存储的是对象在内存中的路径,即内存地址。所以用“==”比较时,即使 
    //对象的值相等,但是他们的内存地址不同,所以==的结果为false。故“==”用于比较两 
    //个变量的值是否相等,而不是变量引用的对象是否相等 

        Boolean r1=st1.equals(st2); 
        Boolean r2=(st1+st2).equals(st3); 
        Boolean r3=st3.equals(st4); 
         
        System.out.println("/n/n-----st1.equals(st2)"+r1+"/n-----(st1+st2).equals(st3)"+r2+"/n-----st3.equals(st4)"+r3); 

    //equal用于比较两个对象是否相同。 
    } 

    运行结果为: 
    -----t1==t2false 
    -----(t1+t2)=t3true 
    -----t3=t4true 

    -----i1.equals(i2)false 
    -----i3.equals(i1+i2)true 
    -----i3.equals(i4)true 

    -----st1==st2false 
    -----(st1+st2)==st3false 
    -----st3==st4true 

    -----st1.equals(st2)false 
    -----(st1+st2).equals(st3)true 
    -----st3.equals(st4)true 

    总之: 
    “==”比较的是值【变量()内存中存放的对象的()内存地址 
    equal用于比较两个对象的值是否相同【不是比地址】 

    【特别注意】Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals“==不同,所以,当自己创建类时,自动继承了Objectequals方法,要想实现不同的等于比较,必须重写equals方法。

    "==""equal"运行速度快,因为"=="只是比较引用.

    在谈论equals和==的区别前,我们先简单介绍一下JVM中内存分配的问题。

    JVM中 内存分为栈内存和堆内存。二者有什么区别呢?

    当我们创建一个对象(new Object)时,就会调用它的构造函数来开辟空间,将对象数据存储到堆内存中,与此同时在栈内存中生成对应的引用,当我们在后续代码中调用的时候用的都是栈内存中的引用,还需注意的一点,基本数据类型是存储在栈内存中。有了一定的了解 我们来看Equals和==的区别。

     

     

    首先equals和== 最大的区别是一个是方法一个是运算符,在Java中,二者比较的都是物理地址 而不是值得比较。

    我们举个例子这样比较直观。

    Student student1 = new Student();

    Student student2 = new Student();

    System.out.println(student1.equals(student2));

    System.out.println(student1 == student2);

    不论是用的是哪一种方法 最终的结果显示的都是false,大家不妨可以试一下。为什么呢?就是因为他们比较的不是对象中字段的值或者说本身对象的值,而比较的是物理地址。

    我们再来举一个例子。

    String a = new String("a");

    String b = new String("a");

    System.out.println(a == b);

    System.out.println(a.equals(b));

    当我们创建2个String对象是 我们会发现 执行的结果是 false true。为什么这次euqals返回的值编程了true?因为此时equals方法不单单是比较物理地址 同时也比较了值,

    String中 equals方法被重写 当物理地址不同时,会进一步比较值,代码如下:

    if(object instanceof String){}

    那么问题来了 当我调用

    System.out.println(student1.toString().equals(student2.toString()));时,结果又是怎样的?

    结果却返回了false.为什么呢?这就牵扯到了hashcode的问题。

    那么为了保证两个对象比较值相等有什么办法么?想必大家都试过重写equals方法,而最终的结果都不如人意。为什么?因为单单重写equals方法并不能改变hashcode值,在java中 首先比较的就是hashcode。那么如何结果这个问题?

    大家可以尝试 右键->source->generate hashcode() and equals() 来实现。

     

     

     

    public class EqualTest { 
    public static void main(String[] args) { 

        //对于基本类型的变量。"==""equal"的区别 
        int t1=57; 
        int t2=67; 
        int t3=124; 
        int t4=124; 
         
        //“==”对于基本数据类型,判断两个变量的值是否相等。 
        Boolean result1=(t1==t2); 
        Boolean result2=((t1+t2)==t3); 
        Boolean result3=(t3==t4); 
         
        System.out.println("/n/n-----t1==t2"+result1+"/n-----(t1+t2)=t3"+result2+"/n-----t3=t4"+result3); 
        //“equal”不能用于基本数据类型。只能用于类变量。对于基本数据类型要用其包装类。 
        Integer i1=new Integer(t1); 
        Integer i2=new Integer(t2); 
        Integer i3=new Integer(t3); 
        Integer i4=new Integer(t4); 
         
         
        Boolean ri1=i1.equals(i2); 
        Boolean ri2=i3.equals(i1+i2); 
        Boolean ri3=i3.equals(i4); 
         
        System.out.println("/n/n-----i1.equals(i2)"+ri1+"/n-----i3.equals(i1+i2)"+ri2+"/n-----i3.equals(i4)"+ri3); 
       
        //对于对象变量,"==""equal"的区别 

        String st1="wasiker "; 
        String st2="is super man"; 
        String st3="wasiker is super man"; 
        String st4="wasiker is super man"; 
         
        Boolean b1=(st1==st2); 
        Boolean b2=(st1+st2)==st3; 
        Boolean b3=(st3==st4); 
         
        System.out.println("/n/n-----st1==st2"+b1+"/n-----(st1+st2)==st3"+b2+"/n-----st3==st4"+b3); 

    //因为对象变量的存储的是对象在内存中的路径,即内存地址。所以用“==”比较时,即使 
    //对象的值相等,但是他们的内存地址不同,所以==的结果为false。故“==”用于比较两 
    //个变量的值是否相等,而不是变量引用的对象是否相等 

        Boolean r1=st1.equals(st2); 
        Boolean r2=(st1+st2).equals(st3); 
        Boolean r3=st3.equals(st4); 
         
        System.out.println("/n/n-----st1.equals(st2)"+r1+"/n-----(st1+st2).equals(st3)"+r2+"/n-----st3.equals(st4)"+r3); 

    //equal用于比较两个对象是否相同。 
    } 

    运行结果为: 
    -----t1==t2false 
    -----(t1+t2)=t3true 
    -----t3=t4true 

    -----i1.equals(i2)false 
    -----i3.equals(i1+i2)true 
    -----i3.equals(i4)true 

    -----st1==st2false 
    -----(st1+st2)==st3false 
    -----st3==st4true 

    -----st1.equals(st2)false 
    -----(st1+st2).equals(st3)true 
    -----st3.equals(st4)true 

    总之: 
    “==”比较的是值【变量()内存中存放的对象的()内存地址 
    equal用于比较两个对象的值是否相同【不是比地址】 

    【特别注意】Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals“==不同,所以,当自己创建类时,自动继承了Objectequals方法,要想实现不同的等于比较,必须重写equals方法。

    "==""equal"运行速度快,因为"=="只是比较引用.

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    服务器层3

    1. entity类  实体类3

    2. DAO4

    *(2)Mapper映射器的要求:4

    3. service层  (开始写注解扫描@6

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    服务器层

    1. entity类  实体类

    1. 数据库复制字段

    /*

     * 类属性名和属性数据类型

     * 与数据库cn_user字段名及数据类型

     * 保持一致

     */

     

     

    String 类型     后面为分号

    2. get set 方法  tostring(可以控制台输出)

     

     

    2. DAO     

    1. interface UserDao 接口    mapper映射

    public User findByName(String name);

    其中User  调用 entity层的user实体类

     

     

    2. Mapper映射器

    *(2)Mapper映射器的要求:

    a. 接口方法的名称与映射文件中的sql的id要一样。
    b. 方法的参数类型要与映射文件当中的parameterType 一致。
    c. 方法的返回类型要与映射文件当中的resultType一致。
    此外,映射文件的namespace必须等于Mapper映射器的 全限定名。

     

    <?xml version="1.0" encoding="UTF-8" ?>  

    <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      

     "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

     

     <mapper namespace="cn.tedu.cloud_note.dao.UserDao">

             <select parameterType="string" resultType="cn.tedu.cloud_note.entity.User">

                    select * from cn_user where cn_user_name={#name};

             </select>

     

     

     

     

     </mapper>

     

     

     

     

    单元测试dao

    @Test   //1.要写 test

     

    public void TestUserDao(){  

     

        ApplicationContext ctx=new ClassPathXmlApplicationContext("conf/spring-myBatis.xml");

    // 2.applicationContest   扫描   config配置文件

            UserDao dao=ctx.getBean("userDao",UserDao.class);

    //3.getBean   UserDao.class   要大写

    User user=dao.findByName("demo");

    //4.调用DAO层 检测数据库

    System.out.println(user);

     

    3. service层  (开始写注解扫描@)

    1.附加的  cn.tedu.cloud_note.util

    1.1创建类    实体类 NoteResult<T>  注意<T>

    private int status;

    private String msg;

    private T data;

    cn.tedu.cloud_note.util

     

    public class NoteResult<T> implements Serializable

    状态   123数字表示

    消息

    数据

    Get  set  tostring方法

     

     

      

    1.2创建NoteUtil

    1.2.1UUID生成主键

    1.2.2MD5加密处理

     

    package cn.tedu.cloud_note.util;

     

    import java.security.MessageDigest;

    import java.util.UUID;

    import org.apache.commons.codec.binary.Base64;

     

    public class NoteUtil {

        //利用UUID生成主键

    //UUID(Universally Unique Identifier)全局唯一标识符,

    //是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。

    public static String create(){

    UUID uuid=UUID.randomUUID();

    String id=uuid.toString();

    return id.replace("-", "");

    }

    //md5加密

    public static String md5(String src){

    try {

    MessageDigest md=MessageDigest.getInstance("MD5");

    //MD5加密处理

    byte[] output

    =md.digest(src.getBytes());

    //Base64处理

    String ret=Base64.encodeBase64String(output);

    return ret;

    } catch (Exception e) {

    throw new NoteException("密码加密失败",e);

    }

     

    }

    }

     

    1.3  创建 NoteException     来抛异常

        package cn.tedu.cloud_note.util;

     

    public class NoteException extends  RuntimeException {

    //注意是RuntimeException   不是 Exception  (出现报错 直接点开创建会开始这个

    //spring事务管理时,

    //只有遇到RuntimeException时才回滚

    public NoteException(String msg,Throwable t){

    super(msg,t);

    }

    }

    2. 

    2.1接口 interface 

    public interface UserService {

           public NoteResult<User> checkLogin(String name ,String password);

                             

    }

    传入参数   String name   String password

    2.2UserService  

    public class UserServiceImpl

    implements UserService

    2.2.1  

    @Service("userService") //扫描的Spring容器

     

    2.2.2 获取资源Resource

    @Resource

    private UserDao userDao;

     

    2.2.3   方法里面写

      //接收结果数据

    NoteResult<User> result=new NoteResult<User>();

    2.2.4    处理业务   排除用户名和密码都错误的状态   

           //按参数name查询数据库

    User user=userDao.findByName(name);

     

      //检测用户名

    if(user==null){    //报错  name==null  改成 user

    result.setStatus(1);

    result.setMsg("用户名不存在");

    return result;

    }

    //检测密码

    String md5Password=NoteUtil.md5(password);

    if (!user.getCn_user_password().equals(md5Password)) {

    result.setStatus(2);

    result.setMsg("密码错误");

    return result;

    }

    //用户名和密码都正确

    result.setStatus(0);

    result.setMsg("登录成功");

    result.setData(user);

    return result;

    }

     

     

    Service单元测试

     

    package test.service;

     

    import org.junit.Before;

    import org.junit.Test;

    import org.springframework.context.ApplicationContext;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import cn.tedu.cloud_note.entity.User;

    import cn.tedu.cloud_note.service.UserService;

    import cn.tedu.cloud_note.util.NoteResult;

     

    public class TestUserService {

    UserService service;

    @Before

    public void init(){

    String[] conf={"conf/spring-mybatis.xml",

           "conf/spring-mvc.xml",

           };

    ApplicationContext ctx

    =new ClassPathXmlApplicationContext(

    conf);

    service

    =ctx.getBean("userService",UserService.class);

    }

     //NoteResult <User>  调用noteresult实体类  entity.User实体类

    @Test  //用例-1:预期结果:用户名不存在

    public void test1(){

    NoteResult<User> result

    =service.checkLogin("你好", "123");

    System.out.println(

    service.getClass().getName());

    System.out.println(result);

    //System.out.println(result.getStatus());

    //System.out.println(result.getMsg());

    //System.out.println(result.getData());

    }

    }

     

     

     

    4. controller层

    Controller层是service层和页面的对接

    1.调用 service  资源  resource

    2.页面上 匹配请求  requestmapping(请求地址)

    写方法 调用service层然后return

    NoteResult result

    =userService.checkLogin(name, password);

     

     

    类里面要调用,方法里面也要调用

    方法用的与service是一样的

     

    @Controller

    public class UserLoginController {

    @Resource

    UserService service;

     

    @RequestMapping("/user/login.do")  //页面请求

    @ResponseBody//调用json

    public NoteResult<User> execute(String name,String password){

    System.out.println(name+"+"+password);

    NoteResult<User> result=service.checkLogin(name, password);//调用service

    return result;

     

    }

     

     

     

    controller测试

     http://localhost:8080/cloud_note3/user/login.do

     

    出现 {"status":1,"msg":"用户名不存在","data":null}

     

     

     

     

     

     

  • 相关阅读:
    LeetCode 515. 在每个树行中找最大值(Find Largest Value in Each Tree Row)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 1022. 从根到叶的二进制数之和(Sum of Root To Leaf Binary Numbers)
    LeetCode 897. 递增顺序查找树(Increasing Order Search Tree)
    LeetCode 617. 合并二叉树(Merge Two Binary Trees)
    LeetCode 206. 反转链表(Reverse Linked List) 16
    LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)
    LeetCode 110. 平衡二叉树(Balanced Binary Tree) 15
    LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14
  • 原文地址:https://www.cnblogs.com/mike-mei/p/7818713.html
Copyright © 2011-2022 走看看