• 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}

     

     

     

     

     

     

  • 相关阅读:
    Android学习笔记八:String.Split("regex")相关
    Android转载六:Intent.ACTION
    Android学习笔记七:调用打电话、发短信等
    Android转载五:TextView换行问题
    常用正则表达式
    Android转载四:(布局)ImageView scaleType属性测试
    java并发容器类
    java并发编程-基础
    设计模式入门
    kafka模块概述
  • 原文地址:https://www.cnblogs.com/mike-mei/p/7818713.html
Copyright © 2020-2023  润新知