阿里最新面试必备项之Java的String类,持续更新中!

Java架构没有996
• 阅读 1950

最新腾讯面试必备项之Java的String类,持续更新中!

1.1 String的特性

  • String类:代表字符串。Java程序中的所有字符串字面值(如“abc”)都作为此类的实例实现。

  • String是一个final类,代表不可变的字符序列。

  • String字符串是常量,用双引号引起来表示。他们的值在创建之后不能更改。

  • String对象的找字符内容是存储在一个字符数组value[]中的。(jdk新版本已改为使用byte类型的数组value[]存放)

阿里最新面试必备项之Java的String类,持续更新中!

1.2 String字面量赋值的内存理解

字面量赋值是直接在常量池中赋值的

Demo:

package com.broky.commonClass;

import org.junit.jupiter.api.Test;

/**
 * String 的使用
 *
 * @author 13roky
 * @date 2021-04-24 10:34
 */
public class StringTest {
    /*
        String:字符串,使用一对""来表示.
        1.String类是被声明为final的,不可被继承.
        2.String实现了Serializable接口:标识字符串是支持序列化的. (io流)
                实现了Comparable接口:可以比较大小.
        3.String内部定义了final char[] value用于存储字符串数字. final表示数组和其元素不能被修改。(为了节省jvm的内存空间jdk9已经改为byte[]类型数组)
        4.String:代表不可变的字符序列。简称:不可变性。
                体现:1.当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value进行赋值.(因为原有的value是final的)
                    2.当对现有的字符串进行连接操作时,需要重新指定内存区域赋值,不能使用原有的value赋值.
                    3.当调用String的replace()方法修改字符或字符串时,也必须重新指定内存区域赋值,不能使用原有的value赋值.
        5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值生命在字符串常量池中.
        6.字符串常量池中是不会存储相同内容的字符串的.
     */
    @Test
    public void test01(){
        //字面量的定义方式, 在内存中用的是同一个内存地址
        String s1 = "abc";
        String s2 = "abc";
        //==比较的是地址值,为true说明s1和s2在内存中指向的是同一个位置
        System.out.println(s1 == s2);//true

        s1 = "hello";

        System.out.println(s1);//hello
        System.out.println(s2);//abc

        System.out.println("================================================");

        String s3 = "abc";
        s3 += "def";
        System.out.println(s3);//abcdef
        System.out.println(s2);//abc

        System.out.println("================================================");

        String s4 = "adb";
        String s5 = s4.replace('a','m');

        System.out.println(s4);//abc
        System.out.println(s5);//mbc
    }
}

图解:

由于字符串常量池中是不会存储相同内容的字符串的,所以在字符串常量池中s1和s2指向同一个内存地址。【获取资料】

阿里最新面试必备项之Java的String类,持续更新中! 由于String内部定义了final char[] value用于存储字符串数字,final表示数组和其元素不能被修改,其也就有了不可变的字符序列的性质。所以改变s1取值为hello后,并不会改变字符串常量池中的对应位置的值,而是会新开辟一个内存地址存放hello值,并且s1指向新的内存地址。 阿里最新面试必备项之Java的String类,持续更新中! 以下图解类似。 阿里最新面试必备项之Java的String类,持续更新中!

1.3 String new方式赋值的内存理解

Demo:

package com.broky.commonClass;

import org.junit.jupiter.api.Test;

/**
 * String 的使用
 *
 * @author 13roky
 * @date 2021-04-24 10:34
 */
public class StringTest {
    /*
    String实例化方式测试:
    方式一: 通过字面量定义的方式
    方式二: 通过new + 构造器的方式

    面试题:String s = new String("abc);方式创建对象,在内存中创建了几个对象?
            两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据"abc"
     */
    @Test
    public void test2() {
        //通过字面量定义的方式:此时的s1和s2的数据javaEE生命在方法区中的字符串常量池中.
        String s1 = "javaEE";
        String s2 = "javaEE";
        //通过new + 构造器的方式:此时的s3和s4保存的地址值是数据在堆空间中开辟空间后对应的地址值.
        String s3 = new String("javaEE");
        String s4 = new String("javaEE");

        System.out.println(s1 == s2);//true
        System.out.println(s1 == s3);//false
        System.out.println(s1 == s4);//false
        System.out.println(s3 == s4);//false
        System.out.println(s3.equals(s4));//true

        System.out.println("=================================================");

        Person p1 = new Person("Tom",12);
        Person p2 = new Person("Tom",12);

        System.out.println(p1.name.equals(p2.name));//true
        System.out.println(p1.name == p2.name);//true
    }
}//加入Java开发交流君样:756584822一起吹水聊天

class Person{
    public String name;
    public int age;

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
}
//加入Java开发交流君样:756584822一起吹水聊天

图解:

new的结构是存在于堆中的,比如String s3 = new String("javaEE");

阿里最新面试必备项之Java的String类,持续更新中!

1.4 String 拼接字面量和变量的方式赋值

Demo:

package com.broky.commonClass;

import org.junit.jupiter.api.Test;

/**
 * String 的使用
 *
 * @author 13roky
 * @date 2021-04-24 10:34
 */
public class StringTest {
    /*
    1.常量与常量的拼接结果在常量池。且常量池中不会存在享同内容的常量。
    2.只要其中有一个是变量,结果就在堆中。
    3.如果拼接的结果调用intern()方法,返回值就会在常量池中。
     */
    @Test
    public void test03() {
        String s1 = "javaEE";
        String s2 = "hadoop";
        String s3 = "javaEEhadoop";
        String s4 = "javaEE" + "hadoop";//引号中的为字面量,这里是字面量的拼接
        String s5 = s1 + "hadoop";
        String s6 = "javaEE" + s2;
        String s7 = s1 + s2;
        final String s8 = "hadoop";
        String s9 = "javaEE" + s8;

        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false
        System.out.println(s3 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s6);//false
        System.out.println(s5 == s7);//false
        System.out.println(s6 == s7);//false
        System.out.println(s3 == s9);//true

        String s10 = s5.intern();//返回值得到的s8使用的常量值中已经存在的”javaEEhadoop“(s5.intern返回的时常量池中对应的内存地址)
        System.out.println(s3 == s10);//true
    }    
}//加入Java开发交流君样:756584822一起吹水聊天

图解:

  • 常量与常量的拼接,结果直接保存在常量池中。如String s4 = "javaEE" + "hadoop";,如果常量池中存在“javaEEhadoop”,那么s4直接指向其地址。
  • 只要拼接赋值时,其中有一个是变量,那么结果就会存在于堆中,如String s5 = s1 + "hadoop";,栈中的变量名s5指向堆中对应的地址0x0001,堆中的地址又指向常量池的地址0x1214。
  • s5指向的是堆中的内存地址0x0001,但是方法s5.intern返回的直接是常量池中的地址。所以String s10 = s5.intern();这行代码会让s10直接指向常量池对应的内存地址。 阿里最新面试必备项之Java的String类,持续更新中!
    package com.broky.commonClass.exer;
    

import java.util.Arrays;

/**

  • @author 13roky

  • @date 2021-04-26 7:27

  • / public class StringValueChangeEx { String str = new String("good"); char[] ch = {'t','e','s','t'};

    public void change(String str,char ch[]){

      str = "test ok";
      ch[0] = 'b';

    } //加入Java开发交流君样:756584822一起吹水聊天 public static void main(String[] args) {

      StringValueChangeEx test01 = new StringValueChangeEx();
      test01.change(test01.str, test01.ch);
      //这里涉及字符串的拼接,所以会用toString方法,而char中的toString返回的是哈希值,所以要用arrays类
      System.out.println(test01.str + " and " + Arrays.toString(test01.ch));   //good and [C@2f4d3709
      System.out.println(test01.str); //good
      System.out.println(test01.ch);  //test

    } }

1.5 String类常用方法

  • int Length():返回字符的长度:return value.Length
  • char charAt(int index):返回某索引处的字return vaLue[index]
  • booLean isEmpty():判断是否是空字符牢:return value. Length == 0`
  • String toLowercase():使用默认语言环境,将 String中的所有字符转换为小写
  • String toUppercase():使用默认语言环境,将 String中的所有字符转换为大写
  • String trim():返回字符的副本,忽略前导空白和尾部空白
  • boolean equals(Object obj):比较字符的内容是否相同
  • booLean equalsIgnoreCase(String anotherString):与equls方法类似,忽略大小写
  • String concat(string str):将指定字符牢连接到此字符的结尾。等价于用"+"
  • int compare To(String anotherstring):比较两个字符的大小
  • String substring(int beginIndex):返回一个新的字符,它是此字符的从 beginIndex开始截取到最后一个子字符串.
  • String substring(int beginIndex, int endindex):返回一个新字符串,它是此字符从beginIndex开始截取到endIndex(不包含)的一个子字符串.

Demo:

package com.broky.commonClass;

import org.junit.jupiter.api.Test;

import java.util.Locale;

/**
 * @author 13roky
 * @date 2021-04-26 21:47
 */
public class CommonMethod {
    /*
    int Length():返回字符的长度: return value.Length
    char charAt( nt index):返回某索引处的字return vaLue[index]
    booLean isEmpty():判断是否是空字符牢: return value. Length == 0
    String toLowercase():使用默认语言环境,将 String中的所有字符转换为小写
    String toUppercase():使用默认语言环境,将 String中的所有字符转换为大写
    String trim():返园字符的副本,忽略前导空白和尾部空白
    boolean equals(Object obj):比较字符的内容是否相同
    booLean equalsIgnoreCase(String anotherString):与equls方法类似,忽略大小写
    String concat(string str):将指定字符牢连接到此字符的结尾。等价于用"+"
    int compare To(String anotherstring):比较两个字符的大小
    String substring(int beginIndex):返回一个新的字符,它是此字符的从 beginIndex开始截取到最后一个子字符串.
    String substring(int beginIndex, int endindex):返回一个新字符串,它是此字符从beginIndex开始截取到endIndex(不包含)的一个子字符串.
     */
    @Test
    public void test01(){
        String s1 ="HelloWorld";
        System.out.println(s1.length());
        System.out.println(s1.charAt(0));
        System.out.println(s1.charAt(9));
        System.out.println(s1.isEmpty());

        String s2 = s1.toLowerCase();
        System.out.println(s1);
        System.out.println(s2);
//加入Java开发交流君样:756584822一起吹水聊天
        String s3 = "    he  llo    world    ";
        String s4 = s3.trim();
        System.out.println(s3);
        System.out.println(s4);
    }

    @Test
    public void test02(){
        String s1 = "HelloWorld";
        String s2 = "helloworld";
        System.out.println(s1.equals(s2));
        System.out.println(s1.equalsIgnoreCase(s2));

        String s3 = "abc";
        String s4 = "def".concat(s3);
        System.out.println(s4);

        String s5 = "abc";
        String s6 = new String("abd");
        System.out.println(s5.compareTo(s6));

        String s7 = "13roky学Java";
        String s8 = s7.substring(2,6);
        System.out.println(s7);
        System.out.println(s8);
    }
}
  • boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
  • boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
  • boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定的前缀开始
  • boolean contains(CharSequence s):当且仅当此字符串包含指定的char值序列时,返回true
  • int indexOf(String str): 返回指定子字符串在此字符串中第一次出现处的索引
  • int indexOf(String str,int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引处开始
  • int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
  • int lastIndexOf(String str,int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索(从右往左搜索)indexOf和lastindexOf方法如果未找到,返回结果都是-1

Demo:

package com.broky.commonClass;

import jdk.jfr.DataAmount;
import org.junit.jupiter.api.Test;

import java.util.Locale;

/**
 * @author 13roky
 * @date 2021-04-26 21:47
 */
public class CommonMethod {
    /*
    boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
    boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
    boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定的前缀开始

    boolean contains(CharSequence s):当且仅当此字符串包含指定的char值序列时,返回true
    int indexOf(String str): 返回指定子字符串在此字符串中第一次出现处的索引
    int indexOf(String str,int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引处开始
    int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
    int lastIndexOf(String str,int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索(从右往左搜索)
    indexOf和lastindexOf方法如果未找到,返回结果都是-1
    */
    @Test
    public void test03(){
        String str1 = "helloworld";
        boolean b1 = str1.endsWith("rld");
        System.out.println(b1);

        boolean b2 = str1.startsWith("He");
        System.out.println(b2);

        boolean b3 =str1.startsWith("ll",2);
        System.out.println(b3);

        String str2 = "wo";
        System.out.println(str1.contains(str2));

        System.out.println(str1.indexOf("lol"));
        System.out.println(str1.indexOf("l"));
        System.out.println(str1.indexOf("lo", 5));

        String str3 = "hellorworld";
        System.out.println(str3.lastIndexOf("or"));
        System.out.println(str3.lastIndexOf("or",6));
    }//加入Java开发交流君样:756584822一起吹水聊天
    //什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
    //情况一:存在唯一的一个str.
    //情况二:不存在str
}

替换:【获取资料】 String replace(char oldChar,char newChar):返回一个新的字符串,它是通过用newChar替换oldChar String replace(CharSequence target,CharSequence replacement):使用字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串. String replaceAll(String regex,String replacement):使用给定的replacement替换此字符串多有匹配给定的正则表达式的子字符串 String replaceFirst(String regex,String replacement):使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串. 匹配: boolean matches(String regex):告知此字符串是否匹配给定得正则表达式 切片: String[] split(String regex):根据给定的正则表达式的匹配拆分此字符串 String[] split(String regex,int limit):根据匹配给定的正则表达式来分此字符串,最多不超过limit个,如果超出,剩下的全部都放到最后一个元素

package com.broky.commonClass;

import jdk.jfr.DataAmount;
import org.junit.jupiter.api.Test;

import java.util.Locale;

/**
 * @author 13roky
 * @date 2021-04-26 21:47
 */
public class CommonMethod {
    /*
    替换//加入Java开发交流君样:756584822一起吹水聊天
    String replace(char oldChar,char newChar):返回一个新的字符串,它是通过用newChar替换oldChar
    String replace(CharSequence target,CharSequence replacement):使用字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串.
    String replaceAll(String regex,String replacement):使用给定的replacement替换此字符串多有匹配给定的正则表达式的子字符串
    String replaceFirst(String regex,String replacement):使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串.
    匹配:
    boolean matches(String regex):告知此字符串是否匹配给定得正则表达式
    切片:
    String[] split(String regex):根据给定的正则表达式的匹配拆分此字符串
    String[] split(String regex,int limit):根据匹配给定的正则表达式来分此字符串,最多不超过limit个,如果超出,剩下的全部都放到最后一个元素
     */
    @Test
    public void test04(){
        String str1 = "13roky学Java";
        String str2 = str1.replace('学','写');

        System.out.println(str1);
        System.out.println(str2);

        String str3 = str1.replace("13roky", "geek");
        System.out.println(str3);

        System.out.println("=====================================================");
        String str = "123klnjklsdnafdmc123pojasvapos";
        String string = str.replace("\\d+",",").replaceAll("^,|,$","|");
        System.out.println(string);

        str = "12345";
        //加入Java开发交流君样:756584822一起吹水聊天
        //判断str字符串中是否全部有数字组成,即有1-n个数字组成
        boolean matches = str.matches("\\d+");
        System.out.println(matches);
        String tel = "0571-4534289";
        //判断一个电话是否是杭州的
        boolean result = tel.matches("0571-\\d{7,8}");
        System.out.println(result);

        System.out.println("================================================");
        str = "hello|world|java";
        String[] strs = str.split("\\|");

        for (int i = 0; i < strs.length; i++) {
            System.out.println(strs[i]);
        }
        System.out.println();
        str2 = "hello.world.java";
        String[] strs2 = str2.split("\\|");
        for (int i = 0; i < strs2.length; i++) {
            System.out.println(strs2[i]);
        }
    }
}

1.6 String与其它类型的转换

demo:

package com.broky.commonClass;

import org.junit.jupiter.api.Test;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * String类与其他结构之间的转换
 * String 与 char[] 之间的转换
 * String 与 byte[] 之间的转换
 *
 * @author 13roky
 * @date 2021-05-02 19:33
 */
public class StringChange {
    /*
    复习:String与其他数据类型,包装类之间的转换
    String --> 基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)
    基本数据类型、包装类 ——》String:调用String重载的valueOf(xxx) 或者直接拼接“”
     */
    @Test
    public void test(){
        String str = "123";
        //int num = (int) str;   只有子父类的关系才可以使用强制类型转换

        int num = Integer.parseInt(str);

        String str2 = String.valueOf(num);
        String str3 = num + "";
    }

    /*
    //加入Java开发交流君样:756584822一起吹水聊天
    String 与 char[] 之间的转换

    String --> char[] :String类中的toCharArray()方法
    char[] --> String :String的构造器
     */
    @Test
    public void test02(){
        String str = "abcde";

        char[] c1 = str.toCharArray();

        for (int i = 0; i < c1.length; i++) {
            System.out.println(c1[i]);
        }

        char[] c2 = new char[]{'f','s','c','a'};

        String str2 = new String(c2);
        System.out.println(str2);
    }

    /*
    String 与 byte[] 之间的转换
    编码:String --> byte[] :调用String的getBytes()
    解码:

    转化的时候会涉及编码和解码
    编码:字符串 --> 字节 (看得懂转换为看不懂的二进制数据)
    解码 字节 --> 字符串 (看不懂的二进制数据转换为看得懂)

     */
    @Test
    public void test03() throws UnsupportedEncodingException {
        String str = "abc123此方";
        // 使用ide默认的编码集进行转换
        byte[]  b1 = str.getBytes();
        // 字节byte类型 采用ASCLL编码 由于ASCLL中没有中文编码,所以中文会转为默认的编码如(UTF-8,UTF-8中一个汉字占三位)然后再转为ASCLL
        System.out.println(Arrays.toString(b1));
        // 使用 gbk 字符集进行编码,需要处理异常
        byte[] b2 = str.getBytes("gbk");

        System.out.println(Arrays.toString(b2));
        System.out.println("=======================================");
        // 使用ide默认的编码集进行解码
        String str2 = new String(b1);
        System.out.println(str2);
        // 出现乱码。原因:编码及和解码集不一致倒置的
        String str3 = new String(b2);
        System.out.println(str3);

        // 指定编码集
        String str4 = new String(b2, "gbk");
        System.out.println(str4);
    }
}

1.7 常见算法题目

  1. 模拟一个trim方法,去除字符串两端的空格。
  2. 将一个字符串进行反转。将字符串中间指定部分进行反转。比如“abcdefg”反转为“abfedcg”。
  3. 获取一个字符串在另一个字符串中出现的次数。
  4. 获取两个字符串中最大的相同字符串。
  5. 将字符串中字符进行自然顺序排序。Arrays.sort()

最后,祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。

可以的话请给我一个三连支持一下我哟??????【获取资料】

阿里最新面试必备项之Java的String类,持续更新中!

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Peter20 Peter20
3年前
mysql中like用法
like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\
Easter79 Easter79
3年前
String ,StringBuffer ,StringBuilder 三者的理解
1.String,StringBuffer,StringBuilder三者执行效率的问题StringBuilderStringBufferStringString是字符常量,是不可变的.如果拿String来操作字符串,一旦操作的字符串的值改变了,就会在内存中创建多一个空间来保存新的字符串,这样的话String的效率就比较低下了.
Stella981 Stella981
3年前
BATJ的常见java面试题
JAVA基础1.JAVA中的几种基本数据类型是什么,各自占用多少字节。2.String类能被继承吗,为什么。不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。3.String,Stringbuffer,StringBuilder的区别。String字符串常量StringBuffer
Wesley13 Wesley13
3年前
JAVA常用类_String
String:一、定义1.字符串,声明为final的,不可被继。2.实现了Serializable接口:表示字符串是支持序列化的。  实现了Comparable接口:表示String可以比较大小二、特性1.String的不可变性    1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值
Stella981 Stella981
3年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
3年前
Java学习:字符串概述与特点
字符串概述与特点java.lang.String类代表字符串API当中说:Java程序中的所有字符串字面值(如“abc“)都作为此类的实例实现。其实就是说:程序当中所用的双引号字符串,都是String类的对象。(就算没有new,也照样是。)字符串的特点1.字符串的内容永远不可改变。【重点】
Wesley13 Wesley13
3年前
unity将 -u4E00 这种 编码 转汉字 方法
 unity中直接使用 JsonMapper.ToJson(对象),取到的字符串,里面汉字可能是\\u4E00类似这种其实也不用转,服务器会通过类似fastjson发序列化的方式,将json转对象,获取对象的值就是中文但是有时服务器要求将传参中字符串中类似\\u4E00这种转汉字,就需要下面 publ