Java String
世界尽头与你 人气:01.String类
字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。
String对象实现了Serializable接口,说明String对象可以串行化(在网络中进行传输),同时实现了Comparable接口,说明String对象可以进行比较
String是个final类,这代表它是不可被继承的
String的本质依然是char数组(或者byte数组,要看JDK的版本),通过源码我们可以轻松的得知:
// JDK1.9及之后的版本,String的字符串内容保存在一个叫做value的byte数组中 @Stable private final byte[] value; // 注意这里的value数组是一个final类型,这代表它是不可以被修改的,这里指的是value的地址不能发生修改,而并非value数组里的值
jdk1.8及以前String使用的是char数组,jdk1.9及以后使用的是byte数组。
因为开发人员发现人们使用的字符串值是拉丁字符居多而之前使用的char数组每一个char占用两个字节而拉丁字符只需要一个字节就可以存储,剩下的一个字节就浪费了,造成内存的浪费,gc的更加频繁。因此在jdk9中将String底层的实现改为了byte数组。
2.String对象创建的两种方式
// 直接赋值 String name = "dahe"; System.out.println(name); // 调用构造器赋值 String wodeshijie = new String("wodeshijie"); System.out.println(wodeshijie);
两种对象创建方式的区别:
直接赋值:现在常量池中看是否存在该字符串,存在则直接指向,不存在则创建后指向
new的方式:先在堆中新建一个对象空间,通过value数组在常量池中寻找该字符串,有的话就将地址返回给value,没有的话就先创建再将地址返回给value
经典面试题A:
会创建一个对象,编译器会对该代码进行优化,a存储的字符串等价于helloabc
经典面试题B:(该代码块创建几个对象)
// 面试题 String a = "hello"; String b = "world"; String c = a + b;
会创建三个对象,a对象和b对象,c对象的创建其实是在堆中,堆中的地址指向字符串常量池的一个helloworld对象常量相加看的是池,变量相加是在堆中!
3.String常用方法
直接上代码演示:
/** * String练习 */ public class StringTest { public static void main(String[] args) { // 直接赋值 String name = "dahe"; System.out.println(name); // 调用构造器赋值 String wodeshijie = new String("wodeshijie"); System.out.println(wodeshijie); // String类的常用方法 String a = "imustctf"; String b = "Imustctf"; // 判断两字符串的值是否相等(区分大小写) System.out.println(a.equals(b)); // 判断两字符串的值是否相等不区分大小写) System.out.println(a.equalsIgnoreCase(b)); // 获取字符个数 System.out.println(a.length()); // 获取子字符串在字符串对象中第一次出现的索引位置,找不到返回-1 int index = a.indexOf('m'); System.out.println(index); // 获取子字符串在字符串对象中最后一次出现的索引位置,找不到返回-1 int lastIndex = a.lastIndexOf('t'); System.out.println(lastIndex); // 字符串截取 System.out.println(a.substring(2)); // 截取2后面的所有字符 System.out.println(a.substring(2, 5)); // 截取0 - 4的所有字符 // 字符串转大写 System.out.println(a.toUpperCase()); // 字符串转小写 System.out.println(b.toLowerCase()); // 字符串拼接 String c = "begin"; c = c.concat(a).concat(b); System.out.println(c); // 替换 c = c.replace("begin", "end"); System.out.println(c); // 分割字符串 String 春日山中对雪 = "竹树无声或有声,霏霏漠漠散还凝," + "岭梅谢后重妆蕊,岩水铺来却结冰," + "牢系鹿儿防猎客,满添茶鼎候吟僧," + "好将膏雨同功力,松径莓苔又一层"; String[] splitRes = 春日山中对雪.split(","); for (String splitRe : splitRes) { System.out.println(splitRe); } // 字符串转化为字符数组 char[] chs = a.toCharArray(); for (char ch : chs) { System.out.println(ch); } // 字符串比较,前者大返回正数,后者大返回负数,相等返回0 System.out.println("abcd".compareTo("abcz")); // 字符串格式化 String info = String.format("网站名字%s,首字母大写后%s", a, b); System.out.println(info); } }
输出:
false
true
8
1
6
ustctf
ust
IMUSTCTF
imustctf
beginimustctfImustctf
endimustctfImustctf
竹树无声或有声
霏霏漠漠散还凝
岭梅谢后重妆蕊
岩水铺来却结冰
牢系鹿儿防猎客
满添茶鼎候吟僧
好将膏雨同功力
松径莓苔又一层
i
m
u
s
t
c
t
f
-22
网站名字imustctf,首字母大写后Imustctf
4.StringBuffer
概述
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer。
StringBuffer的本质依然是char数组(或者byte数组,要看JDK的版本)但是和String不同的是,该数组不是final类型的和String类一样,StringBuffer类也是final类型,代表它不能被继承!
String VS StringBuffer:
StringBuffer三种构造器初始化
// 创建一个大小为16的char[] 数组,用于存放字符内容 StringBuffer stringBuffer = new StringBuffer(); // 指定char[]容量大小 StringBuffer stringBuffer1 = new StringBuffer(100); // 通过给一个string创建stringbuffer,初始容量为字符串长度 + 16 StringBuffer dahezhiquan = new StringBuffer("dahezhiquan");
String和StringBuffer的转换
String --> StringBuffer
// String --> StringBuffer String str = "hello"; // 方法一:通过构造器 StringBuffer stringBuffer2 = new StringBuffer(str); // 方法二:通过append StringBuffer stringBuffer3 = new StringBuffer(); stringBuffer3.append(str);
StringBuffer --> String
// StringBuffer --> String StringBuffer stringBuffer4 = new StringBuffer("lsp"); // 方法一:通过toString方法 String s = stringBuffer4.toString(); // 方法二:使用构造器 String s1 = new String(stringBuffer4);
StringBuffer的常用方法
代码示例:
// StringBuffer的常用方法 StringBuffer imustctf = new StringBuffer("imustctf"); // 追加操作 imustctf.append(" nice"); imustctf.append(" yes").append(true).append(5.21).append(1314); System.out.println(imustctf); // 删除操作 // 删除索引为5到6的字符 imustctf.delete(5,7); System.out.println(imustctf); // 修改操作,替换9到10的字符为方文杰 imustctf.replace(9,11,"方文杰"); System.out.println(imustctf); // 查找操作 int index = imustctf.indexOf("方文杰"); System.out.println(index); // 插入操作,在索引为9的后面插入张三 imustctf.insert(9,"张三"); System.out.println(imustctf); // 长度 System.out.println(imustctf.length());
输出:
imustctf nice yestrue5.211314
imustf nice yestrue5.211314
imustf ni方文杰 yestrue5.211314
9
imustf ni张三方文杰 yestrue5.211314
30
5.StringBuilder
概述
一个可变的字符序列,此类提供一个与StringBuffer兼容的API,但不保证同步(不是线程安全的),用在字符串缓冲区被单个线程使用的时候,如果可能建议优先使用该类,因为在大多数的时候,它比StringBuffer要快
StringBuilder类是final类型,不能被继承!StringBuilder的本质依然是char数组(或者byte数组,要看JDK的版本),该数组不是final类型
StringBuilder和StringBuffer同属一个父类,故他们的方法一致
现在我们来看一下String,StringBuffer,StringBuilder的区别:
加载全部内容