java String 类和类方法详解

怀旧网,博客网站地址:怀旧网,博客详情:java String 类和类方法详解

String的简介

String:字符串,使用一对“”引起来表示

String声明为final的,不可以被继承

字符串的字符使用Unicode进行编码,一个字符(不区分字母还是汉字)占两个字节

String实现了Serializable接口:表示字符串是支持序列化的,说明可以在网络上传输。

实现了Comparable接口:表示String可以比较大小

String类内部定义了final char[] value用于存储字符串数据

一定要注意:value是一个final类型,不可以修改:即value不能指向新的地址,但是单个字符内容是可以变化的。

String代表不可变的字符序列,简称:不可变性

体现:

1.当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value进行赋值。

2.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。

3.当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。

通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中

字符串常量池中是不会存储相同内容的字符串的

String 底层存储方式

底层的存储方式是一个字符数组

底层定义的的变量为:private final char value[];

例如:“abc” ==> ['a', 'b', 'c']; 在底层存储为:==> [97, 98, 99]

存储的内容为对应的编码的编码值(因为必须转换为编码值才可以通过二进制的方式存储在计算机里面)

在相互转换的时候,存储时需要编码,取出是需要解码,如下:

public class Test1{
    public static void main(String[] args){
        char value = 'a';
        // 编码
        System.out.println(value+" 编码 ==> "+(int) value);
        int value1 = 97;
        //解码
        System.out.println(value1+" 解码 ==> "+(char) value1);
    }
}

输出结果如下:
    a 编码 ==> 97
    97 解码 ==> a

常用的构造器

public String(); 空构造
String value = new String(); 输出:''
    
public String(byte[] bytes); 把字节数组转成字符串
String value = new String(new byte[]{97, 98, 99}); 输出:'abc'

public String(byte[] bytes, int index, int length); 把字节数组的一部分转成字符串
String value = new String(new byte[]{97, 98, 99}, 1, 2); 输出:'bc'

public String(char[] value); 把字符数组转成字符串
String value = new String(new char[]{'a', 'b', 'c'}); 输出:'abc'

public String(char[] value, int index, int count); 把字符数组的一部分转成字符串
String value = new String(new char[]{'a', 'b', 'c'}, 1, 2); 输出:'bc'
    
public String(String original); 把字符串常量值转成字符串
String value = new String("abc"); 输出:'abc'

// 在每个构造器最后面都可以加上一个String类型编码集来制定字符串的编码解码方式

分析字符串不同创建方式的地址值比较

// 通过字面量定义的方式: 此时数据abc声明在方法区中的字符串常量池中
String s1="abc";
String s2="abc";
// 通过new+构造器的方式: 此时s3,s4保存的地址值,是数据在堆空间中开辟以后对应的地址值
String s3 = new String("abc");
String s4 = new String("abc");

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(s3equals.equals(s4));//true

// 常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
// 只要其中有一个结果是变量,结果就在堆中
// 如果拼接的结果调用intern()方法,返回值就在常量池中
// 加上代码便于理解:
String s1 = "a";
String s2 = "b";
String ss = "ab";

String s3 = "a"+"b";
String s4 = s1 + "b";
String s5 = "a" + s2;
String s6 = s1 + s2;

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

String s7 = s4.intern();
System.out.println(ss==s7); // true


String a = "abc";
String b = "abc";

//String重写了equals方法 ,比较的是具体的值,所以为true
System.out.println(a.equals(b)); //true
//a 首先看常量池有没有abc
//b 首先看常量池有没有abc 有,就将b直接指向abc
//所以地址值是一样的
System.out.println(a == b); //true

String a = "a";
String b = new String("a");
System.out.println(a.equals(b)); //true
System.out.println(a == b); //false
System.out.println(a == b.intern()); //true
System.out.println(b == b.intern()); //false

//当调用intern()方法时,如果池已经包含一个等于此String对象的字符串(用equals(Object)方法确定)
//则返回池中的字符串.否则,将此String对象添加到池中,并返回此String对象的引用
//解读:b.intern() 方法最终返回的是常量池的地址(对象)

String s1 = "aa"; //s1 指向常量池的ly
String s2 = "bb"; //s2 指向常量池的java
String s3 = new String("bb"); //指向堆中的对象 
String s4 = "bb"; //s4 指向常量池的java

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

案例分析

public static void main(String[] args) {
    Person p1 = new Person();
    p1.name = "a";
    Person p2 = new Person();
    p2.name = "a";

    System.out.println(p1.name.equals(p2.name)); //比较的内容 true
    System.out.println(p1.name == p2.name); //true
    //"lyedu"返回的地址:就是在常量池中的地址
    //p1.name 指向的也是常量池中的"lyedu" 对应的地址
    System.out.println(p1.name == "a"); //true
}

class Person {
    public String name;
}

String a = "hello" + "abc"; //等价于==>String a = "helloabc";

字符串的常用方法

String str="123456abc";
1.equals(String str)方法,比较两个字符串的值是否一致,返回值为boolean类型
    System.out.println(str.equals("123abcd")); // false
    System.out.println(str.equals("123456abc")); // true

2.length()方法,返回字符串的长度
   System.out.println(str.length()); // 9

3.charAt(int index)从字符中取出指定索引的值
   System.out.println(str.charAt(1)); // 2

4.indexOf(String str)方法,查找对应字符在字符串中的索引位置,如果没有则返回-1,常与3配合使用,
   System.out.println(str.indexOf("3")); // 2

5.lastIndexOf(String str)方法,查找对应字符最后在字符串中出现的索引位置,如果没有则返回-1
   System.out.println(str.indexOf("3")); // 2

6.toCharArray()方法,将字符串变成一个数组
  char[] chars = str.toCharArray();
  for (int i=0;i<chars.length;i++){
      System.out.println(chars[i]);
  } // 输出结果为一个字符一行的打印

7.toUpperCase()将字符串全部转换为大写
  String sr="Signal-strength";
  String s = sr.toUpperCase();
  System.out.println(s); // SIGNAL-STRENGTH

8.toLowerCase()将字符串全部转换为小写
  String sr="Signal-strength";
  String s = sr.toLowerCase();
  System.out.println(s); // signal-strength

9.split("字符"),根据给定的正则表达式来拆分字符串,形成一个String数组
  String str="123_456";
  String[] s = str.split("_");
  for (String s1:s){
      System.out.print(s1+"  "); // 123  456
  }

10.trim()方法,去除字符串左右两端的空白,该方法只能去除左右,中间的没办法
  String str=" 1 23_456 ";
  System.out.println(str); //  1 23_456 
  System.out.println(str.trim()); // 1 23_456

11.substring(int beginIndex,int endIndex)截取字符串
String str="123_456";
// 不包含3
System.out.println(str.substring(0,3)); // 123
// 从第3个位置截取
System.out.println(str.substring(2)); // 3_456

12.equalsIgnoreCase(String str),忽略字符串大小比较字符串的值,
  String str="absC";
  String str1="absc";
  System.out.println(str.equalsIgnoreCase(str1)); // true

13.concat(String str),将str的字符串的内容添加到字符串的后面,效果等同于+
 String str="absC";
 String str1="absc";
 System.out.println(str.concat(str1)); // absCabsc
    等同于
 String str="absC"+"absc";

14.replace(char oldChar,char newChar),该方法用字符newChar替换掉当前字符串中所有的oldChar。
String str="absCac";
System.out.println(str.replace("a","c")); // cbsCcc

15.replaceFirst(String regex,String replacement),该方法用字符replacement替换掉当前字符串中第一个匹配regex。
String str="absCac";
System.out.println(str.replaceFirst("a","c")); // cbsCac

16.replaceAll(String regex,String replacement),该方法用replacement替换掉当前字符串中第一个匹配regex。
String str="absCac";
System.out.println(str.replace("a","c")); // cbsCcc

17.startsWith(String prefix),比较该字符串是否以prefix子字符串开始的
String str="absCac";
System.out.println(str.startsWith("ab")); // true

18.endsWith(String prefix),比较该字符串是否以prefix结尾的
String str="absCac";
System.out.println(str.endsWith("ab")); // false

19.valueOf(Type type)用于将基本数据类型转换为String类型,补充一点,type不能为null,不然会报空指针异常
String s = String.valueOf(21);
System.out.println(s); // 21

20.getBytes(),将该字符串转换为字节数组
String str="123421421";
byte[] bytes = str.getBytes();

21.String.format()方法,字符串类型格式话
     format(String format,Object obj),新字符串使用本地语言环境,制定字符串格式和参数生成格式的新字符串
     format(Locale locale,String format,Object obj),使用指定语言环境,制定字符串格式和参数生成格式的新字符串
    显示不同转换符实现不同数据类型转换
转换符说明示例
%s字符串类型"hello word"
%c字符类型'a'
%b布尔类型true
%d整数类型(十进制)23
%x整数类型(十六进制)AF
%o整数类型(八进制)77
%f浮点类型13.14
%a十六进制浮点类型AF.21AE
%e指数类型3.24e+5
%g通用浮点型(f和e类型中较短的)
%h散列码
%%百分比类型%
%n换行符
%tx日期与时间类型(x代表不同日期与时间转换符)
例:
//字符串类型
System.out.println(String.format("hello %s","word"));//hello word
//字符类型
System.out.println(String.format("hello,%s",'t'));//hello,t
//布尔类型
System.out.println(String.format("is,%b",true));//is,true
//整数类型(十进制)
System.out.println(String.format("%d is 4",4));//4 is 4
//整数类型(十六进制)
System.out.println(String.format("%x is 16",15));//f is 16
//整数类型(八进制)
System.out.println(String.format("%o is 8",8));//10 is 8
//浮点类型
System.out.println(String.format("%f is 12.34",12.34));//12.340000 is 12.34
//十六进制浮点类型
System.out.println(String.format("%a is 21.34",21.34));//0x1.5570a3d70a3d7p4 is 21.34
//指数类型
System.out.println(String.format("100的指数表示:%e",100*0.85));//100的指数表示:8.500000e+01
//通用浮点型(f和e类型中较短的)
System.out.println(String.format("10的指数和浮点数结果的长度较短的是:%g",100*0.85));//10的指数和浮点数结果的长度较短的是:85.0000
//散列码
System.out.println(String.format("字母B的散列码是:%h",'B'));//字母B的散列码是:42
//日期与时间类型(x代表不同日期与时间转换符)
System.out.println(String.format("今天是:%tc",new Date()));//今天是:星期一 十一月 15 13:57:54 CST 2021

搭配转换符的标志,如图所示。
标 志说 明示 例结 果
+为正数或者负数添加符号("%+d",15)+15
左对齐("%-5d",15)15
0数字前面补0("%04d", 99)0099
空格在整数之前添加指定数量的空格("% 4d", 99)99
,以“,”对数字分组("%,f", 9999.99)9,999.990000
(使用括号包含负数("%(f", -99.99)(99.990000)
#如果是浮点数则包含小数点,如果是16进制或8进制则添加0x或0("%#x", 99) ("%#o", 99)0x63 0143
<格式化前一个转换符所描述的参数("%f和%<3.2f", 99.45)99.450000和99.45
$被格式化的参数索引("%1$d,%2$s", 99,"abc")99,abc
例
String str=null;
//$使用
str=String.format("格式参数$的使用:%1$d,%2$s", 99,"abc"); 
System.out.println(str); // 格式参数$的使用:99,abc
//+使用
System.out.printf("显示正负数的符号:%+d与%d%n", 99,-99); // 显示正负数的符号:+99与-99
//补O使用
System.out.printf("最牛的编号是:%03d%n", 7); // 最牛的编号是:007
//空格使用
System.out.printf("Tab键的效果是:% 8d%n", 7); // Tab键的效果是:       7
//.使用
System.out.printf("整数分组的效果是:%,d%n", 9989997); // 整数分组的效果是:9,989,997
//空格和小数点后面个数

其中日期的x如下所示意思,为c是为全部时间信息
转 换 符说 明示 例
c包括全部日期和时间信息星期六 十月 27 14:21:20 CST 2007
F“年-月-日”格式2007-10-27
D“月/日/年”格式10/27/07
r“HH:MM:SS PM”格式(12时制)02:25:51 下午
T“HH:MM:SS”格式(24时制)14:28:16
R“HH:MM”格式(24时制)14:2
例如:
Date date=new Date();
//c的使用
System.out.printf("全部日期和时间信息:%tc%n",date); // 全部日期和时间信息:星期一 十一月 15 14:04:38 CST 2021
//f的使用
System.out.printf("年-月-日格式:%tF%n",date); // 年-月-日格式:2021-11-15
//d的使用
System.out.printf("月/日/年格式:%tD%n",date); // 月/日/年格式:11/15/21
//r的使用
System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date); // HH:MM:SS PM格式(12时制):02:04:38 下午
//t的使用
System.out.printf("HH:MM:SS格式(24时制):%tT%n",date); // HH:MM:SS格式(24时制):14:04:38
//R的使用
System.out.printf("HH:MM格式(24时制):%tR",date); // HH:MM格式(24时制):14:04

和日期格式转换符相比,时间格式的转换符要更多、更精确。它可以将时间格式化成时、分、秒甚至时毫秒等单位。格式化时间字符串的转换符如图所示:
转 换 符说 明示 例
H2位数字24时制的小时(不足2位前面补0)15
I2位数字12时制的小时(不足2位前面补0)03
k2位数字24时制的小时(前面不补0)15
l2位数字12时制的小时(前面不补0)3
M2位数字的分钟(不足2位前面补0)03
S2位数字的秒(不足2位前面补0)09
L3位数字的毫秒(不足3位前面补0)015
N9位数字的毫秒数(不足9位前面补0)562000000
p小写字母的上午或下午标记中:下午 英:pm
z相对于GMT的RFC822时区的偏移量+0800
Z时区缩写字符串CST
s1970-1-1 00:00:00 到现在所经过的秒数1193468128
Q1970-1-1 00:00:00 到现在所经过的毫秒数1193468128984
例如:
Date date = new Date();
//H的使用
System.out.printf("2位数字24时制的小时(不足2位前面补0):%tH%n", date); // 2位数字24时制的小时(不足2位前面补0):15
//I的使用
System.out.printf("2位数字12时制的小时(不足2位前面补0):%tI%n", date); // 2位数字12时制的小时(不足2位前面补0):03
//k的使用
System.out.printf("2位数字24时制的小时(前面不补0):%tk%n", date); // 2位数字24时制的小时(前面不补0):15
//l的使用
System.out.printf("2位数字12时制的小时(前面不补0):%tl%n", date); // 2位数字12时制的小时(前面不补0):3
//M的使用
System.out.printf("2位数字的分钟(不足2位前面补0):%tM%n", date); // 2位数字的分钟(不足2位前面补0):21
//S的使用
System.out.printf("2位数字的秒(不足2位前面补0):%tS%n", date); // 2位数字的秒(不足2位前面补0):13
//L的使用
System.out.printf("3位数字的毫秒(不足3位前面补0):%tL%n", date); // 3位数字的毫秒(不足3位前面补0):612
//N的使用
System.out.printf("9位数字的毫秒数(不足9位前面补0):%tN%n", date); // 9位数字的毫秒数(不足9位前面补0):612000000
//p的使用
String str = String.format(Locale.US, "小写字母的上午或下午标记(英):%tp", date); // 小写字母的上午或下午标记(英):pm
System.out.println(str);
System.out.printf("小写字母的上午或下午标记(中):%tp%n", date); // 小写字母的上午或下午标记(中):下午
//z的使用
System.out.printf("相对于GMT的RFC822时区的偏移量:%tz%n", date); // 相对于GMT的RFC822时区的偏移量:+0800
//Z的使用
System.out.printf("时区缩写字符串:%tZ%n", date); // 时区缩写字符串:CST
//s的使用
System.out.printf("1970-1-1 00:00:00 到现在所经过的秒数:%ts%n", date); // 1970-1-1 00:00:00 到现在所经过的秒数:1636960873
//Q的使用
System.out.printf("1970-1-1 00:00:00 到现在所经过的毫秒数:%tQ%n", date); // 1970-1-1 00:00:00 到现在所经过的毫秒数:1636960873612
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值