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)给一个字符串赋值,此时的字符串值声明在字符串常量池中
字符串常量池中是不会存储相同内容的字符串的
底层的存储方式是一个字符数组
底层定义的的变量为: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
和日期格式转换符相比,时间格式的转换符要更多、更精确。它可以将时间格式化成时、分、秒甚至时毫秒等单位。格式化时间字符串的转换符如图所示:
转 换 符 | 说 明 | 示 例 |
---|---|---|
H | 2位数字24时制的小时(不足2位前面补0) | 15 |
I | 2位数字12时制的小时(不足2位前面补0) | 03 |
k | 2位数字24时制的小时(前面不补0) | 15 |
l | 2位数字12时制的小时(前面不补0) | 3 |
M | 2位数字的分钟(不足2位前面补0) | 03 |
S | 2位数字的秒(不足2位前面补0) | 09 |
L | 3位数字的毫秒(不足3位前面补0) | 015 |
N | 9位数字的毫秒数(不足9位前面补0) | 562000000 |
p | 小写字母的上午或下午标记 | 中:下午 英:pm |
z | 相对于GMT的RFC822时区的偏移量 | +0800 |
Z | 时区缩写字符串 | CST |
s | 1970-1-1 00:00:00 到现在所经过的秒数 | 1193468128 |
Q | 1970-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
评论
登录后才可以进行评论哦!