zoukankan      html  css  js  c++  java
  • string常见面试题

    package justTest;

    /**
    * Author:YeJianPeng<br/>
    * Date:2020/05/05<br/>
    * Time:8:58<br/>
    */
    public class stringTest {
    public static void main(String[] args) {
    System.out.println("*************************************************************");
    System.out.println("string类属于"+(new String()).getClass().getPackage().getName()+"包");
    /*
    == 可以比较基本数据类型,也可以比较引用数据类型,基本数据类型比较的是值,引用数据类型比较的是内存地址
    equals 比较的是引用数据类型
    1.如果没有重写object的equals方法,那么和==比较引用类型时一样,都是比较内存地址
    2.重写equals后,改方法比较的是值
    ^^new这个关键字,毫无疑问会在堆中分配内存
    ^^单独(注意是单独)使用引号来创建字符串的方式,字符串都是常量,在编译期已经确定存储在常量池中了。
    常量池:就是放常量的地方,他存在堆内存中,他有啥锤子用?
    每当代码创建字符串常量时,JVM会首先检查字符串常量池。
    如果字符串已经存在池中,就返回池中的实例引用。
    如果字符串不在池中,就会实例化一个字符串并放到池中。
    很显然就是存在常量池中的字符不需要再创建了,这就节省了时间和空间等资源,而且常量池中资源不会被gc。
    */
    System.out.println("*************************************************************");
    String a1 = "asd";
    String a2 = "asd";
    String a3 = new String("asd");
    System.out.println(a1==a2);//true
    System.out.println(a1.equals(a2));//true
    System.out.println(a1==a3);//false
    System.out.println(a3.equals(a2));//true
    /*
    * string 是字符串,字符串属于常量,存在常量池中,
    * “asd”在a1已经创建于常量池中,a2引用的也是常量池中的asd,所以a1==a2
    * String类重写了equals方法,比较的是属性值,所以也是true
    * String a3 = new String("asd");
    * 首先在常量池中创建对象asd,如果有就不创建了啊
    * new的时候在堆内存中创建一个asd的副本,同时将这快内存的地址赋值给a3
    * 这个时候 常量池中有一个对象,堆内存中也有一个对象
    * a3指向的其实是堆内存对象的内存地址。
    * */
    System.out.println("*************************************************************");
    String b1 ="ab";
    String b2 ="abc";
    String b3 = b1+"c";
    System.out.println(b2==b3);//false
    System.out.println(b2.equals(b3));//true
    /*
    *这个就很神奇了
    * 毫无疑问b1,b2在常量池中
    * 但是b3就不是了,这属于字符串 串联,b1+"c"的时候会先在堆中创建StringBuilder对象,
    * 然后使用StringBuilder的append方法拼接成‘abc’,
    * 拼接完事再调用StringBuilder的toString()方法,就是下面这货
    * return new String(value, 0, count);
    * 很明显,它又在堆中new了一个string,b3的值指向的是这个string的内存地址
    * */
    System.out.println("*************************************************************");
    String c1 ="abc";
    final String c2 ="ab";
    String c3 =c2 +"c";
    String c4 ="c";
    String c5 =c2 +c4;
    System.out.println(c1==c3);//true
    System.out.println(c1.equals(c3));//true
    System.out.println(c1==c5);//false
    /*
    *因为c2有final修饰
    *c2 +"c"在编译期间就会优化成 “ab”+“c”
    *而c2 +c4只能优化为“ab”+c4,还是会创建StringBuilder然后append然后再toString
    *跟上面String b3 = b1+"c"一样了
    * */

    System.out.println("*************************************************************");
    String d1="abc";
    String d2="abc";
    String d3="abcde";
    System.out.println(d1.compareTo(d2));
    System.out.println(d1.compareTo(d3));
    System.out.println(d3.compareTo(d1));
    /*
    *compareTo
    *返回值是整型,它是先比较对应字符的大小(ASCII码顺序)
    *返回的是第一个不相同字母的ASCII差值,都相等返回0
    * equalsIgnoreCase跟compareTo类似,只是都转换为大写然后比较
    * */
    System.out.println("*************************************************************");
    String bStr ="strToByte";
    byte[] bytes = bStr.getBytes();//转为byte了
    String bStr2 = new String(bytes);//又转回来了
    System.out.println(bStr2);
    String [] sArr = bStr.split("t");//转为string数组

    System.out.println("*************************************************************");
    String e1 = new StringBuilder("九十九").append("大洋").toString();
    System.out.println(e1.intern() == e1);
    /*
    *intern()
    * 这个已懵圈,也不知道实战中有啥用0.0
    * JDK 1.7后,intern方法会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,如果在常量池找不到对应的字符串,
    * 则不会再将字符串拷贝到常量池(JDK1.6会),而只是在常量池中生成一个对原字符串的引用。
    * 简单的说,就是往常量池放的东西变了:原来在常量池中找不到时,复制一个副本放到常量池,1.7后则是将在堆上的地址引用复制到常量池。
    * JDK 1.7后 ,常量池被从方法区中移出来到了堆中。
    * */
    System.out.println("*************************************************************");
    String str = "aBcde";
    System.out.println(str.toLowerCase());
    System.out.println(str.toUpperCase());
    System.out.println(str.isEmpty());
    System.out.println(str.endsWith("de"));
    System.out.println(str.startsWith("aB"));//true
    System.out.println(str.startsWith("ab"));//false看来是区分大小写的
    System.out.println(str.startsWith("aBcdeeee"));//false很显然
    /*
    * 就这吧,以后再加点,true啊false没意思
    * */



    }
    }
  • 相关阅读:
    在Ubuntu 20.04 LTS Focal Fossa上安装Deluge
    如何使用命令行快速检查Linux系统的版本
    如何在Debian 10上安装NVM
    如何在CentOS 8上安装Apache ActiveMQ
    如何在Linux中引导时列出启动服务?
    如何检查Linux Mint 20磁盘错误的方法
    如何在Firewalld中打开特定IP地址的端口?
    如何在CentOS 8服务器安装oVirt开源虚拟化管理系统
    如何在Centos 8服务器上安装LogAnalyzer?
    如何在Debian中使用apt从命令行安装程序
  • 原文地址:https://www.cnblogs.com/52czm/p/12835050.html
Copyright © 2011-2022 走看看