Java字符串

字符串

字符类型(char)是Java中的基本数据类型之一,字符是用单引号引住的单个符号。字符串(String)是用双引号引住的任意个字符,字符串其实就是字符组成的序列。字符串在开发中可以用来表示标题,名称,地址等。

1.字符串对象与字面量
String 变量名 = "初始值";
String 变量名 = new String("初始值");
  • 第一种形式使用双引号引住的字符串叫做字面量

  • 第二种使用new运算符声明的字符串叫做字符串对象。【第二种形式并不常用,推荐使用第一种形式。】

2.API

字符串内部使用byte数组(JDK8之前是char数组)来保存字符串的内容,数组中的每一位存一个字符,byte数组的长度也就是字符串的长度。

返回类型方法名称作用
booleanequals(String)比较两个字符串是否相等
booleanequalsIgnoreCase(String)忽略大小写比较两个字符串是否相等
intlength()获取字符串的长度
charcharAt(int)获取字符串中的一个字符
intindexOf(String)判断传入字符串在原字符串中第一次出现的位置
intlastIndexOf(String)判断传入字符串在原字符串中最后一次出现的位置
booleanstartsWith(String)判断原字符串是否以传入字符串开头
booleanendsWith(String)判断原字符串是否以传入字符串结尾
intcompareTo(String)判断两个字符串的大小
StringtoLowerCase()获取小写字符串
StringtoUpperCase()获取大写字符串
Stringsubstring(int)截取字符串,从传入参数位置开始截取到末尾
Stringsubstring(int, int)截取字符串,从参数1位置开始截取到参数2位置
Stringtrim()去掉字符串首尾的空格
String[]split(String)将原字符串按照传入参数分割为字符串数组
Stringreplace(String, String)将字符串中指定的内容替换成另外的内容
2.1字符串连接

字符串可以进行加法运算,作用是将两个字符串连接在一起,也可以将字符串与基本类型变量做加法运算,系统会先将基本类型转换为字符串型后进行连接操作。在Java中将两个字符串连接在一起可以使用加号连接,也可以使用 concat() 方法连接。

stringString str1="绿蚁新醅酒,";
String str2="红泥小火炉。";
System.out.println(str1.concat(str2));//绿蚁新醅酒,红泥小火炉。
2.2字符串比较

字符串也可以进行是否相等的比较,但不能直接使用 == 运算符,而是要使用equals() 方法进行比较。忽略大小写的比较 equalsIgnoreCase() 方法

在Java中,equals()和==都是用于比较两个对象的操作,但它们有着不同的含义和使用场景。

(1)==操作符用于比较两个对象的引用是否指向同一内存地址。如果两个对象的引用指向相同的内存地址,则它们是相等的。

(2)另一方面,equals()方法用于比较两个对象的值是否相等。默认情况下,equals()方法比较两个对象的引用是否相等,但可以通过重写该方法来实现自定义的相等比较逻辑。

(3)需要注意的是,对于基本类型的比较(如int、double等),==操作符比较的是它们的值,而不是引用

String str = "name";
String str2 = "name";
String str3 = "string";
System.out.println(str.equals(str2));//true
System.out.println(str.equals(str3));//false
2.3字符串的长度

String类的 length() 方法可以获取字符串是由多少个字符构成的。

在数组中length属于数组的属性,而在字符串中length()是字符串的方法,注意进行区分

String str = "name";
System.out.println(str.length());
2.4字符串查找
  1. indexOf() 判断传入字符串在原字符串中第一次出现的位置
  2. lasetIndexOf() 判断传入字符串在原字符串中最后一次出现的位置
  3. startsWith() 判断原字符串中是否以传入字符串开头
  4. endsWith() 判断原字符串中是否以传入字符串结尾
public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入QQ邮箱");
        String a = sc.next();
    }
    public static boolean verifyEmail(String email) {
        // 必须包含“@”和“.”;“@”必须在“.”的前面;“@”只能出现一次;不能以“@”开头;不能 以“.”结尾。
        if (email.indexOf("@") >= 0 && email.indexOf(".") >= 0
            // 必须包含“@”和“.”
                && email.indexOf('@') < email.indexOf('.')  
            // “@”必须在“.”的前面
                && email.indexOf('@') == email.lastIndexOf('@') 
            // “@”只能出现一次
                && !email.startsWith("@") // 不能以“@”开头
                && !email.endsWith(".")) {  // 不能 以“.”结尾
            return true;
        }
        return false;
    }
chartAt()//方法用于返回指定索引处的字符
String s = "晚来天欲雪,能饮一杯无?";
char result = s.charAt(6);//索引下标为6的字符串
System.out.println(result);
compareTo()//判断两个字符串的大小
String str2 = "name";
String str3 = "string";
System.out.println(str2.compareTo(str3));//-5
  • 去除空格
  1. trim :去除两端空格
  2. strip :去除两端空格
  3. stripIndent :去除每一行的两端空格 去除前置最少得空格数量后面全部去掉
  4. stripLeading :去除前置空格
  5. stripTrailing :去除后置空格
String str = "  Malus spectabilis  "
System.out.println(str);
System.out.println(str.length());
//trim去除两端的空格
String strTrim = str.trim();
System.out.println("trim");
System.out.println(strTrim);
System.out.println(strTrim.length());
// strip 去除两端空格
String strStrip = str.strip();
System.out.println("strip");
System.out.println(strStrip);
System.out.println(strStrip.length());//17
// stripIndent 去除每一行的两端空格 去除前置最少得空格数量后面全部去掉
String strStripIndent = str.stripIndent();
System.out.println("stripIndent");
System.out.println(strStripIndent);
System.out.println(strStripIndent.length());
// stripLeading 去除前置空格
String strStripLeading = str.stripLeading();
System.out.println("stripLeading");
System.out.println(strStripLeading);
System.out.println(strStripLeading.length());
// stripTrailing 去除后置空格
String strStripTrailing = str.stripTrailing();
System.out.println("stripTrailing");
System.out.println(strStripTrailing);
System.out.println(strStripTrailing.length());
System.out.println("=========");
String string = " nihao \n test \n hello ";
System.out.println(string);
System.out.println(string.length());
String string2 = string.stripIndent();
System.out.println("======");
System.out.println(string2);
System.out.println(string2.length());
String string3 = string.stripTrailing();
System.out.println(string3);
System.out.println(string3.length());
String string4 = string.stripLeading();
System.out.println(string4);
System.out.println(string4.length());
String string5 = string.trim();
System.out.println(string5);
System.out.println(string5.length());
String string6 = string.strip();
System.out.println(string6);
System.out.println(string6.length());

image-20230827201238064

2.6字符串内容替换

String类的 replace() 方法用于将字符串中指定的内容替换成其他内容。

replace(char oldChar, char newChar)
//replace() 方法通过用 newChar 字符替换字符串中出现的所有 searchChar 字符,并返回替换后的新字符串。
public String replace(char searchChar, char newChar) 
//searchChar -- 原字符。
//newChar -- 新字符。
//返回值
//替换后生成的新字符串。
replace(CharSequence target,CharSequence replacement )
//该方法替换此字符串相匹配的文字目标序列与指定的文字替换序列中的每个子字符串。替换所得格式从字符串开头到结尾:
//target -- 这是要被替换字符的值的序列。
//replacement -- 这是char值的替换序列。
2.7字符串截取

String类的 subString(int,int) 方法用于字符串内容的截取,第一个参数是从第几位开始截取,第二个参数是截取到第几位,如果没有给定第二个参数,默认截取到最后一位。

public class SubStr {
public static void main(String[] args) {
    // 现有如下文本:“Java语言是面向对象的,Java语言是健壮的,Java语言是安全的,Java是高性能的,Java语言是跨平台的”。
    // 请编写程序,统计该文本中"Java"一词出现的次数。
    String str = "Java语言是面向对象的,Java语言是健壮的,Java语言是安全的,Java是高性能的,Java语言是跨平台的";
//        System.out.println(countJava(str, "Java"));
    // 将字符串拆分成字符数组
    char[] chars = str.toCharArray();
    String[] split = str.split("");
    System.out.println(Arrays.toString(chars));
    System.out.println(Arrays.toString(split));
    System.out.println(str.indexOf("Java"));
    System.out.println(countJava(str, "Java"));
    }
    public static int countJava(String str, String target) {
        int count = 0;
        int index = str.indexOf(target); // 第一次出现的下标
        while (index >= 0) {
            count++;
            str = str.substring(index + target.length());
            index = str.indexOf(target);
        }
        return count;
    }
转义字符说明
\\输出\
\t制表位
\n换行
2.8字符串格式化

String类的 format() 方法用于创建格式化的字符串以及连接多个字符串对象。format方法定义是 format(Stringformat, Object… args); 第一个参数是被格式化的字符串,第二个参数是替换格式符的字符串,第二个参数中的…表示方法可变参数,即参数的个数根据格式符的个数来确定。字符串格式化就是使用第二个可变参数中的值按照顺序替换第一个参数中的格式符。format方法的格式符定义如下:

格式符说明示例
%s字符串类型"开发喵"
%c字符类型'm'
%b布尔类型true
%d整数类型(十进制)100
%x整数类型(十六进制)FF
%o整数类型(八进制)77
%f浮点类型99.9
public static void main(String[] args) {
String str = String.format("见过,%s及%s", "晁天王", "众位头领");
System.out.println(str);
str = String.format("字母a的大写是:%c", 'A');
System.out.println(str);
str = String.format("3 > 7的结果是:%b", 3 > 7);
System.out.println(str);
str = String.format("100的一半是:%d", 100 / 2);
System.out.println(str);
// 使用printf()方法代替format方法来格式化字符串
System.out.printf("50元的书打8.5折扣是:%f 元", 50 * 0.85);
}

getBytes()

getBytes(String charsetName): 使用指定的字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
getBytes(): 使用平台的默认字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
语法
public byte[] getBytes(String charsetName) throws UnsupportedEncodingExceptionpublic byte[] getBytes()
//charsetName -- 支持的字符集名称。
//返回byte数组
 String Str1 = new String("runoob");

        try {
            byte[] Str2 = Str1.getBytes();
            System.out.println("返回值:" + Str2);//[B@404b9385

            Str2 = Str1.getBytes("UTF-8");
            System.out.println("返回值:" + Str2);//[B@6d311334

            Str2 = Str1.getBytes("ISO-8859-1");
            System.out.println("返回值:" + Str2);//[B@682a0b20
        } catch (UnsupportedEncodingException e) {
            System.out.println("不支持的字符集");
        }
    }
2.9字符串是否为空
  • isBlank() : 字符串中没有有效字符,结果为true

  • isEmpty() :只要字符串的长度是0,结果就是true

  • replaceAll 和 replaceFirst

  • replaceAll :替换所有满足pattern的内容为新内容

  • replaceFirst : 替换第一次满足pattern的内容为新内容

  • contains :字符串中是否有子串

String str = "kaifamiao1234开发喵123";
String pattern = "\\d{4}";
String replace = str.replace('a', 'A');
System.out.println(replace);
// replaceAll 替换所有满足pattern的内容为新内容
String kfm = str.replaceAll(pattern, "a");
// replaceFirst 替换第一次满足pattern的内容为新内容
String replaceFirst = str.replaceFirst(pattern, "a");
System.out.println(kfm);
System.out.println(replaceFirst);
// contains 字符串中是否有子串
System.out.println(str.contains("kfm"));
正则表达式

正则表达式(Regular Expression,简称Regex或RegExp)是一种字符串处理的工具,它用于匹配、查找、替换和提取文本中的模式。

正则表达式由一些特殊字符和普通字符组成,可以表示一类字符串的通用规律。例如,正则表达式\d{3}-\d{4}可以匹配形如"123-4567"的字符串,其中\d表示数字字符,{3}表示连续匹配三次,-表示匹配一个横线,\d{4}表示连续匹配四次数字字符。以下是一些常用的正则表达式规则:

普通字符

普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。例如:

字符描述
[abc]匹配 [...] 中的所有字符,例如 [aeiou] 匹配字符串 “google runoob taobao” 中所有的 e o u a 字母。
[^ABC]匹配除了 [...] 中字符的所有字符,例如 [^aeiou] 匹配字符串 “google runoob taobao” 中除了 e o u a 字母的所有字母。
[^a-z]匹配除了 [...] 以外的字符
[A-Z] [a-z][A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母。
.匹配任意单个字符,但不包括换行符,相等于 [^\n\r]
[\s\S]匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行。
\w匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
特殊字符

所谓特殊字符,就是一些有特殊含义的字符,许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符:

字符描述
$匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性, 则 $ 也匹配 \n\r 。要匹配 $ 字符本身,请使用 \$
( )标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( )
*匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *
+匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +
.匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 .
[标记一个中括号表达式的开始。要匹配 [ ,请使用 [
?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?
\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n''\n' 匹配换行符。序列 \\ 匹配 \,而 '(' 则匹配 "("
^匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^
{标记限定符表达式的开始。要匹配 { ,请使用 {
``

非打印字符

字符描述
\cx匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Za-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f匹配一个换页符。等价于 \x0c\cL
\n匹配一个换行符。等价于 \x0a\cJ
\r匹配一个回车符。等价于 \x0d\cM
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v] 。注意 Unicode 正则表达式会匹配全角空格符。
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
\t匹配一个制表符。等价于 \x09\cI
\v匹配一个垂直制表符。等价于 \x0b\cK

请注意,正则表达式中的特殊字符需要通过在它们前面加上反斜杠 \ 来转义。这些特殊字符在正则表达式中具有特殊的含义,因此需要特别处理。

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m}共6种。

量词含义
*匹配零个或多个字符 a,例如,ab* 能匹配 “a” 以及 “abb”。* 等价于 {0,}
+匹配前面的子表达式一次或多次。例如,zo+ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}
?匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 “do”、“does”、“doxy” 中的 “do” 和 “does”。? 等价于 {0,1}
{n}n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 “Bob” 中的 o,但是能匹配 “food” 中的两个 o
{n,}n 是一个非负整数。至少匹配 n 次。例如,o{2,} 不能匹配 “Bob” 中的 o,但能匹配 “foooood” 中的所有 oo{1,} 等价于 o+o{0,} 则等价于 o*
{n,m}mn 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 “fooooood” 中的前三个 oo{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。
定位符

定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

正则表达式的定位符有:

边界含义
^匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n\r 之后的位置匹配。
$匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n\r 之前的位置匹配。
\b匹配一个单词边界,即字与空格间的位置。
\B非单词边界匹配。

以上是一些常用的正则表达式规则,可以通过它们来匹配、查找、替换和提取文本中的模式。需要根据具体需求选择合适的规则并进行组合。

1.限定符出现在范围表达式之后,* 和 + 限定符都是贪婪的,因为它们会尽可能多的匹配⽂字,只有在它们的后⾯加上⼀个 ? 就可以实现⾮贪婪或最⼩匹配。

2.不能将限定符与定位符⼀起使⽤。由于在紧靠换⾏或者单词边界的前⾯或后⾯能有⼀个以上位置,因此不允许诸如 ^* 之类的表达式。若要匹配⼀⾏⽂本开始处⽂本,请在正则表达式的开始使⽤ ^ 字符。不要将 ^ 的这种⽤法与中括号表达式内的⽤法混淆。

3.⽤圆括号 () 将所有选择项括起来,相邻的选择项之间⽤ | 分隔。() 表⽰捕获分组,() 会把每个分组⾥的匹配的值保存起来, 多个匹配值可以通过数字 n 来查看(n 是⼀个数字,表⽰第 n 个捕获组的内容)。

4.^ 和 [^指定字符串] 之间的区别:^ 指的是匹配字符串开始的位置; [^指定字符串] 指的是除指定字符串以外的其他字符串

在Java中,正则表达式的处理需要使用Java的正则表达式API,主要包括Pattern和Matcher两个类。Pattern类表示正则表达式的编译结果,Matcher类则用于在字符串中查找和匹配模式。以下是Java中常用的正则表达式方法:

Pattern.compile(String regex)
//该方法用于将正则表达式编译成一个Pattern对象,其中regex是一个字符串类型的正则表达式。
public static void main(String[] args) {
String regex = "\\d+"; // 匹配数字
Pattern pattern = Pattern.compile(regex); // 将正则表达式编译成模式
String text = "hello 123 world";
Matcher matcher = pattern.matcher(text); // 创建匹配器对象
while (matcher.find()) {
// 输出匹配结果
System.out.println(text + "匹配结果是:" + matcher.group());
}
matcher.matches()//该方法用于判断给定字符串是否与正则表达式匹配,返回一个布尔值
public static void main(String[] args) {
String regex = "\\d+"; // 匹配数字
Pattern pattern = Pattern.compile(regex); // 将正则表达式编译成模式
String text = "123456";
Matcher matcher = pattern.matcher(text); // 创建匹配器对象
boolean isMatched = matcher.matches(); // 尝试将整个输入序列与该模式匹配
System.out.println(isMatched); // 输出匹配结果,true
matcher.find()
//该方法用于在给定字符串中查找匹配正则表达式的子序列,并返回一个布尔值。如果找到,则可以使用group()方法获取匹配的子序列。
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d\\d\\d");
Matcher m = p.matcher("a123b");
System.out.println(m.find()); // 输出结果true
}
matcher.replaceAll(String replacement)
//该方法用于在给定字符串中替换匹配正则表达式的子序列,其中replacement是一个字符串类型的替换字符串。
public static void main(String[] args) {
// 匹配数字
String regex = "\\d+";
// 将正则表达式编译成模式
Pattern pattern = Pattern.compile(regex);
String text = "hello 123 world 456";
// 创建匹配器对象
Matcher matcher = pattern.matcher(text);
// 将匹配的子序列替换为"###"
String replacedText = matcher.replaceAll("###");
// 输出替换后的结果字符串 hello ### world ###
System.out.println(replacedText);
字符串处理

包装类介绍

在Java中,基本数据类型(如int、double、boolean等)与对象类型是两个不同的概念。为了使基本数据类型也具备面向对象的特性,Java提供了包装类(Wrapper Class)。

包装类是一种特殊的类,用于将基本数据类型封装成对象。Java中提供了8种包装类,分别对应8种基本数据类型,它们分别是

基本类型包装类
booleanjava.lang.Boolean
bytejava.lang.Byte
shortjava.lang.Short
intjava.lang.Integer
longjava.lang.Long
floatjava.lang.Float
doublejava.lang.Double
charjava.lang.Character

包装类提供了许多有用的方法,例如将字符串转换为对应的基本数据类型,将基本数据类型转换为字符串,比较两个包装对象的大小等等。此外,包装类也可以作为一种数据类型,在泛型编程、反射等方面具有重要的作用。

包装类常量

包装类中都有两个常量:MAX_VALUE、MIN_VALUE,分别表示最大值和最小值。

public static void main(String[] args) {
// 通过访问包装类的常量,来获取最大值和最小值
System.out.println("int的最大值:" + Integer.MAX_VALUE); // 2147483647
System.out.println("int的最小值:" + Integer.MIN_VALUE); // -2147483648
System.out.println("byte的最大值:" + Byte.MAX_VALUE); // 127
System.out.println("byte的最小值:" + Byte.MIN_VALUE); // -128
System.out.println("double的最大值:" + Double.MAX_VALUE); // 1.7976931348623157E308
System.out.println("double的最小值:" + Double.MIN_VALUE); // 4.9E-324
}

装箱/拆箱

Java中的拆箱和装箱是指基本数据类型和对应的包装类之间的转换。Java中的包装类提供了一些方法来完成拆箱和装箱的操作,这些方法包括:

装箱:将基本数据类型转换为对应的包装类对象,可以使用包装类的构造方法或静态方法valueOf()来完成。

拆箱:将包装类对象转换为对应的基本数据类型,可以使用包装类提供的xxxValue()方法来完成。

public static void main(String[] args) {
// 装箱:将int类型转换为Integer类型
int i = 100;
Integer integerObj = new Integer(i);
Integer integerObj2 = Integer.valueOf(i);
// 拆箱:将Integer类型转换为int类型
Integer integerObj3 = new Integer(200);
int j = integerObj3.intValue();
int k = integerObj3; // 自动拆箱
}

通过包装类的构造方法和valueOf()方法将int类型的变量i装箱为Integer类型的对象。然后通过Integer对象的intValue()方法将其拆箱为int类型。除此之外,在JDK 5及以上版本中,还支持自动拆箱和装箱的操作,即在需要使用基本数据类型的地方,可以直接使用对应的包装类对象,或者在需要使用包装类对象的地方,也可以直接使用基本数据类型的变量。

自动拆箱/自动装箱(JDK5新特性)

当基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱:

  • 进⾏ = 赋值操作(装箱或拆箱)

  • 进⾏+,-,*,/混合运算 (拆箱)

  • 进⾏>,<,==⽐较运算(拆箱)

  • 调⽤equals进⾏⽐较(装箱)

  • ArrayList,HashMap等集合类添加基础类型数据时(装箱)

public static void main(String[] args) {
int a = 100;
Integer b = 100;
System.out.println(a == b); // true
Integer c = 100;
Integer d = 100;
System.out.println(c == d); // true
Integer num1 = new Integer(100);
Integer num2 = new Integer(100);
    System.out.println(num1 == num2); // false
c = 200;
d = 200;
System.out.println(c == d); // false
}
// 基础类型a与包装类b进行==比较,这时b会拆箱,直接比较值
// 包装类型c和d进行比较的时候比较的是地址
//在Integer类的 valueOf() 方法中
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

这里的实现并不是简单的new Integer,而是用IntegerCache做一个cache,cache的range是可以配置的,默认Integer cache 的下限是-128,上限默认127,可以配置,所以到这里就清楚了,我们上面当赋值100给Integer时,刚好在这个range内,所以cache中取对应的Integer并返回,所以二次返回的是同一个对象,所以比较是相等的,当赋值200给Integer时,不在cache 的范围内,所以会new Integer并返回,当然比较的结果是不相等的。

Integer方法
方法名作用
static Integer decode(String nm)将字符串转换为 Integer 对象。
static int compare(int x, int y)比较两个整数是否相等。相等返回 0;前大后小返回 1;后大前小返回 -1。
static int signum(int i)符号函数;负数返回 -1;正数返回 1;0 返回 0。
static String toBinaryString(int i)将整数转换为二进制表示的字符串。
static String toHexString(int i)将整数转换为十六进制表示的字符串。
static String toOctalString(int i)将整数转换为八进制表示的字符串。
static int parseInt(String s)将字符串转换为整数。
static Integer valueOf(String s)将字符串转换为 Integer 对象。
String toString()Integer 转换为字符串。
boolean equals(Object obj)判断两个 Integer 是否相等。

Character方法

方法名作用
char charValue()Character 转换为 char
int compareTo(Character anotherCharacter)判断两个 Character 是否相等。相等返回 0;前大后小返回 1;后大前小返回 -1。
boolean equals(Object obj)判断两个 Character 是否相等。
String toString()Character 转换为字符串。
static boolean isDigit(char ch)判断字符是否为数字。
static boolean isLetter(char ch)判断字符是否为字母。
static boolean isLetterOrDigit(char ch)判断字符是否为字母或数字。
static boolean isLowerCase(char ch)判断字符是否为小写字母。
static boolean isUpperCase(char ch)判断字符是否为大写字母。
static boolean isSpaceChar(char ch)判断字符是否为空格。
static Character valueOf(char c)char 转换为 Character
public static void main(String[] args) {
Character c = 'a';
char res1 = c.charValue();
System.out.println(res1); // a
Character a = 'a';
Character b = 'b';
System.out.println(a.compareTo(b));
System.out.println(a.equals(b));
System.out.println(Character.isDigit('1'));
System.out.println(Character.isLetter('a'));
System.out.println(Character.isLetterOrDigit('1'));
System.out.println(Character.isLetterOrDigit('a'));
System.out.println(Character.isLowerCase('a'));
System.out.println(Character.isUpperCase('A'));
System.out.println(Character.isSpaceChar(' '));
System.out.println(c.toString());
    System.out.println(Character.valueOf('c'));
}

String类型转换成基本类型

将字符串类型转换为基本类型,需要使用基本类型的包装类。 String 的 valueOf() 将基本数据类型转换成字符串

  • 基本类型中除了char类型以外,其它7种基本类型使⽤各⾃的包装类调⽤parseXxx()⽅法将String类型转换为基本类型。

  • char类型的转换可以通过String类的charAt(index)⽅法完成。

基本类型转换为String类型

String类型的数据参与算术运算时,需要将String类型转换为基本类型,基本类型的数据在界面上显示时需要将数据转换成String类型后输出在界面上。

八种基本类型的数据转换成String类型有两种方法。

  • 通过“+”将基本类型与String类型连接,将基本类型转换成String类型。

  • 通过String.valueOf(基本类型数据)⽅法将基本类型转换成String类型

public static void main(String[] args) {
String employeeName = "喵星人";
String isMarried = "false"; // 是否已婚
String gender = "M"; // 性别
String baseSalary = "7000"; // 基本工资
String basicBonus = "300"; // 基础奖金
String basicBonusScore = "0.85"; // 基础奖金考核得分
String performanceBonus = "400"; // 考核奖金
String performanceBonusScore = "0.9"; // 考核奖金得分
String attendanceAllowance = "100"; // 全勤补助
boolean isMarriedBoolean = Boolean.parseBoolean(isMarried);
char genderChar = gender.charAt(0);
int baseSalaryInt = Integer.parseInt(baseSalary);
short basicBonusShort = Short.parseShort(basicBonus);
float basicBonusScoreFloat = Float.parseFloat(basicBonusScore);
long performanceBonusLong = Long.parseLong(performanceBonus);
double performanceBonusScoreDouble = Double.parseDouble(performanceBonusScore);
byte attendanceAllowanceByte = Byte.parseByte(attendanceAllowance);
// 计算总收入
double totalIncome = baseSalaryInt + basicBonusShort * basicBonusScoreFloat +
performanceBonusLong * performanceBonusScoreDouble +
attendanceAllowanceByte;
System.out.println(employeeName + ",性别(" + genderChar + ")" +
",婚否(" + isMarriedBoolean + "),总工资=" + totalIncome);
}

Math类

Math类是Java中的一个内置类,位于java.lang包中。它提供了许多用于执行数学运算的静态方法和常量。Math类中的方法都是以静态方式调用,无需创建Math类的实例。以下是Math类的一些常用方法和常量:

方法描述
Math.abs(x)返回参数 x 的绝对值。
Math.sqrt(x)返回参数 x 的平方根。
Math.pow(x, y)返回 xy 次幂。
Math.max(x, y)返回 xy 中较大的值。
Math.min(x, y)返回 xy 中较小的值。
Math.ceil(x)返回大于或等于参数 x 的最小整数。
Math.floor(x)返回小于或等于参数 x 的最大整数。
Math.round(x)返回参数 x 的四舍五入值。
Math.random()返回一个 0 到 1 之间的随机浮点数。
  • Math.PI :表⽰π(圆周率)的近似值。

  • Math.E :表⽰⾃然对数的底数e的近似值。

Math类的方法都是静态的,可以直接通过类名调用,无需创建Math类的实例.

String的注意事项

在Java中,字符串是不可变的,这意味着一旦创建了一个字符串对象,它的内容就不能被修改。当你对一个字符串进行操作时(比如连接、替换、截取等),实际上是创建了一个新的字符串对象,而原始的字符串对象保持不变。

这种不可变性有以下几个关键特点:

(1)字符串对象是不可修改的: 一旦创建了一个字符串对象,就无法更改它的内容。例如,如果你有一个字符串“hello”,你无法直接修改内存里面存储的值“help”,而是在内存中重新产生一个新的字符串对象来表示“help”。

(2)线程安全: 由于字符串是不可变的,多个线程可以同时访问和共享相同的字符串对象,而不会出现并发修改的问题。这使得字符串在多线程环境中更安全。

(3)字符串池: Java中的字符串常量池(String Pool)是字符串不可变性的一个体现。当你创建一个字符串常量时,JVM会首先检查字符串常量池是否已经存在相同内容的字符串,如果存在,则直接返回对这个已存在字符串的引用,而不会重新创建一个新的对象。这样可以节省内存空间并提高性能。

(4)安全性: 字符串不可变性确保字符串对象在被传递给其他方法时,不会被修改,从而避免了在传递参数时意外修改字符串内容的情况。字符串不可变性的一个常见实例是使用字符串连接操作符(“+”)来拼接字符串。

字符串字⾯量和new出来字符串的区别

  • 只要是以 “…” ⽅式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储⼀份

  • 但通过 new ⽅式创建字符串对象,每new⼀次都会产⽣⼀个新的对象放在堆内存中

image-20230827214112732

public static void main(String[] args) {
String name = "开发喵";
name += "程序员";
name += "喵喵";
System.out.println(name);
}

只要是以 “” 方式写出的字符串对象,会在堆内存中的字符串常量池中存储。

执行第一句话时,会在堆内存的常量池中,创建一个字符串对象 “开发喵” ,然后把 “开发喵” 的地址赋值给String name当执行第二句话时,又会再堆内存的常量池中创建一个字符串 “程序员” ,和 “开发喵” 拼接,拼接之后还会产生一个新的字符串对象 ”开发喵程序员“ ,然后将新产生的 “开发喵程序员” 对象的地址赋值给 String name 变量。

此时你会发现,之前创建的字符串对象 “开发喵” 内容确实是没有改变的。所以说String的对象是不可变的。

字符串变量

StringBuffer类

StringBuffer类是Java中一个可变的字符串类,它提供了对字符串进行修改的方法。与String类不同,StringBuffer类的对象可以修改,添加和删除它们包含的字符序列。

StringBuffer类是线程安全的,因此它的所有方法都是同步的。这意味着当一个线程访问一个StringBuffer对象时,其他线程必须等待,直到该线程完成其操作。这使得StringBuffer类在多线程环境中非常有用。

StringBuffer类有多个构造方法,可以根据不同的需求选择合适的构造方法来创建对象。以下是StringBuffer类的常见构造方法:

(1) StringBuffer(): 创建一个空的StringBuffer对象,初始容量为默认值(16个字符)。

(2) StringBuffer(int capacity): 创建一个空的StringBuffer对象,并指定初始容量。初始容量是指内部字符缓冲区的初始大小,用于存储字符串内容。

(3) StringBuffer(String str): 创建一个包含指定字符串的StringBuffer对象。初始容量将被设置为字符串的长度加上默认的容量增量(默认为16)。

(4) StringBuffer(CharSequence seq): 创建一个包含指定字符序列的StringBuffer对象。CharSequence是一个接口,可以是String、StringBuilder或其他实现CharSequence接口的类的实例。

public static void main(String[] args) {
// 创建一个空的StringBuffer对象
StringBuffer sb1 = new StringBuffer();
// 创建一个初始容量为20的StringBuffer对象
StringBuffer sb2 = new StringBuffer(20);
// 创建一个包含字符串"Hello"的StringBuffer对象
StringBuffer sb3 = new StringBuffer("Hello");
// 创建一个包含StringBuilder对象内容的StringBuffer对象
StringBuffer sb4 = new StringBuffer(new StringBuilder("World"));
}
方法名作用
append()将一个字符串或字符添加到 StringBuffer 的末尾。
insert()将一个字符串或字符插入到 StringBuffer 的指定位置。
delete()StringBuffer 中删除指定位置的字符。
reverse()StringBuffer 中的字符序列反转。
length()返回 StringBuffer 中字符序列的长度。
toString()返回 StringBuffer 对象转换为普通的字符串。
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();
System.out.println(result); // Hello World
}

sb4 = new StringBuffer(new StringBuilder(“World”));
}


| 方法名       | 作用                                                 |
| ------------ | ---------------------------------------------------- |
| `append()`   | 将一个字符串或字符添加到 `StringBuffer` 的末尾。     |
| `insert()`   | 将一个字符串或字符插入到 `StringBuffer` 的指定位置。 |
| `delete()`   | 从 `StringBuffer` 中删除指定位置的字符。             |
| `reverse()`  | 将 `StringBuffer` 中的字符序列反转。                 |
| `length()`   | 返回 `StringBuffer` 中字符序列的长度。               |
| `toString()` | 返回 `StringBuffer` 对象转换为普通的字符串。         |

```java
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();
System.out.println(result); // Hello World
}