String/StringBuffer/StringBuilder三个类,都是表示字符串的类
● String对象的创建
package com.wkcto.chapter04.string;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
/**
* String对象的创建
* String类的构造方法
* @author 蛙课网
*
*/
public class Test01 {
public static void main(String[] args) throws UnsupportedEncodingException {
//1) 直接赋值字符串字面量
String s1 = "wkcto";
//2) 无参构造
String s2 = new String(); //new运算符在堆区中创建一个String对象, 把该对象的引用保存到s2中
if ( s2 == null ) {
System.out.println("s2的值是null");
}else {
System.out.println("s2是一个长度为0的字符串,是一个空字符串"); //相当于""
}
//Person p1 = new Person(); new运算符在堆区中创建一个对象,把对象的引用保存到p1中
//3) 根据字节数组创建String对象
byte[] bytes = {65 , 66, 67, 97, 98, 99};
//把bytes字节数组中所有字节,根据当前默认的编码(UTF-8)转换为字符串对象
String s3 = new String(bytes);
System.out.println( s3 ); //ABCabc
//把字节数组中的部分字节转换为字符串对象
s3 = new String(bytes, 0, 3); //把bytes字节数组从0开始的3个字节转换为String对象
//字符串的getBytes()方法可以把字符串以当前默认的编码转换为字节数组
bytes = "wkcto是一个神奇的网站".getBytes(); //在UTF-8编码中,一个英文占1字节,一个汉字占3个字节
System.out.println( Arrays.toString(bytes ));
//[119, 107, 99, 116, 111, -26, -104, -81, -28, -72, -128, -28, -72, -86, -25, -91, -98, -27, -91, -121, -25, -102, -124, -25, -67, -111, -25, -85, -103]
s3 = new String(bytes, 0, 8);
System.out.println( s3 );
s3 = new String(bytes, 4, 8);
System.out.println( s3 );
//把字符串转换为指定编码格式下对应的字节数组
bytes = "wkcto是一个神奇的网站".getBytes("GBK"); //在GBK编码中, 一个英文占1字节,一个汉字占2字节
System.out.println( Arrays.toString(bytes ));
//[119, 107, 99, 116, 111, -54, -57, -46, -69, -72, -10, -55, -15, -58, -26, -75, -60, -51, -8, -43, -66]
s3 = new String(bytes); //把bytes字节数组按照当前默认编码utf-8转换为字符串
System.out.println( s3 );
s3 = new String(bytes, "GBK"); //把bytes字节数组中 字节按指定的编码GBK转换为字符串
System.out.println( s3 );
//4) 把字符数组转换为字符串
char [] contents = {'w','k','很','牛','B'};
String s4 = new String(contents);
System.out.println( s4 );
s4 = new String(contents, 0, 2);
System.out.println( s4 );
//5)根据已有的字符串生成新的字符串对象
String s5 = new String(s3);
System.out.println( s5 );
System.out.println( s3 == s5 ); //false
System.out.println( s3.equals(s5)); //true
}
}
● String常用操作
char:charAt(int index) 返回指定索引位置的字符
int:compareTo(String anotherString) String类实现了Comaprable接口,可以比较两个字符串的大小, 遇到第一个不相同的字符, 码值相减
String:concat(String str) 在当前字符串的后面连接str字符串
boolean:contains(CharSequence s) 在当前字符串中判断是否包含指定的字符串s, 如果包含返回true
boolean:endsWith(String suffix) 判断当前字符串是否以suffix结尾
boolean:equals(Object anObject) 判断两个字符串的内容是否一样
boolean:equalsIgnoreCase(String anotherString)忽略大小写
staticString:format(String format, Object... args) 字符串的格式化
byte[]:getBytes() 返回当前字符串在默认的编码格式下对应的字节数组
byte[]:getBytes(String charsetName) 返回当前字符串在指定的编码格式下对应的字节数组
void:getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 把当前字符串[srcBegin,srcEnd) 范围内的字符复制到dst数组中desBegin开始的位置
int:hashCode()
int:indexOf(int ch) 返回字符ch在当前字符串中第一次出现的位置
int:indexOf(int ch, int fromIndex). 返回字符ch在当前字符串中从fromIndex开始第一次出现的位置
int:indexOf(String str) 返回字符串str在当前字符串中第一次出现的位置
int:indexOf(String str, int fromIndex) 返回字符串str在当前字符串中从fromIndex开始第一次出现的位置
String:intern()返回当前字符串对应的字符串常量
boolean:isEmpty() 判断当前字符串是否为空串
int:lastIndexOf(int ch) 返回字符ch在当前字符串中最后一次出现的位置
int:lastIndexOf(int ch, int fromIndex)
int:lastIndexOf(String str) 返回字符串str在当前字符串中最后一次出现的位置
int:lastIndexOf(String str, int fromIndex)
int:length() 返回字符串中字符的个数
boolean:matches(String regex) 判断当前字符串是否匹配指定的正则表达式
String:replaceAll(String regex, String replacement) 把当前字符串中符合regex正则表达式的字符串替换为replacement
String[]:split(String regex) 使用正则表达式regex把当前字符串进行分隔
boolean:startsWith(String prefix)
String:substring(int beginIndex) 返回从beginIndex开始到最后的子串
String:substring(int beginIndex, int endIndex) 返回从beginIndex开始到endIndex范围内的子串
char[]:toCharArray() 把字符串转换为字符数组
String:toLowerCase() 把大写字母转换为小写字母
String:toString()
String:toUpperCase() 把小写字母转换为大写字母
String:trim() 去掉前后的空白字符
staticString:valueOf(int i) 把基本类型转换为字符串
staticString:valueOf(Object obj)
package com.wkcto.chapter04.string;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
/**
* 演示String类的基本操作
* @author 蛙课网
*
*/
public class Test02 {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "wkctoisthebest";
//1)charAt(index), length()
for(int i = 0 ; i<str.length() ; i++){
System.out.print( str.charAt(i) );
}
System.out.println( );
//2) contains()
System.out.println( str.contains("wkcto"));
System.out.println( str.contains("powernode"));
//3)字符串的比较
String str2 = "wkctogood";
System.out.println( str.compareTo(str2)); //2 'i' - 'g'
System.out.println("张三".compareTo("李四")); //-2094 '张'的码值比'李'的码值小
//4)equals()字符串内容的比较
System.out.println( str.equals(str2)); //fasle
//5)format()字符串的格式化,%s格式符对应字符串, %d格式符代表整数, %f格式符代表小数
System.out.println( String.format("姓名:%s,年龄:%d,工资:%f", "feifei", 28 , 30000.0));
// 姓名:feifei,年龄:28,工资:30000.000000
//6)getBytes()返回字符串对应的字节数组
byte[] bytes = "wkcto是一个神奇的网站".getBytes(); //在当前utf-8编码下对应的字节数组
System.out.println( Arrays.toString(bytes));
bytes = "wkcto是一个神奇的网站".getBytes("GBK"); //在指定的GBK编码下对应的字节数组
System.out.println( Arrays.toString(bytes));
//7) 把文件路径 分离, 文件夹,文件名,扩展名
String path = "d:/Chapter04/src/com/wkcto/chapter04/string/Test02.java";
int lastSlashIndex = path.lastIndexOf("/");
int dotindex = path.indexOf(".");
String folder = path.substring(0, lastSlashIndex);
String filename = path.substring(lastSlashIndex+1 , dotindex);
String suffix = path.substring(dotindex+1);
System.out.println( folder );
System.out.println( filename );
System.out.println( suffix );
//8) trim()去掉前后的空白字符
str = " wkcto good ";
System.out.println( "aaaaa" + str.trim() + "BBBB");
//9) valueOf() 可以把其他类型转换为字符串
str = String.valueOf( 456 );
str = "" + 789; //字符串与基本类型连接时, 先把基本类型转换为字符串再连接
}
}
package com.wkcto.chapter04.string;
/**
* String中和正则表达式相关的方法
* 正则表达式就是一个模式串,常用于判断字符串是否匹配指定的格式, 如判断用户名必须包含字母与数字,如判断邮箱是否合理
* 正则表达式中的字符
* 转义字符
* [abc] 匹配a/b/c中的一个
* [a-zA-Z] 小写字母a~z或者大写字母A~Z中的一个
* . 任意字符
* \d 数字
* \s 空白符, 空格, Tab, 回车
* \w 单词字符 [a-zA-Z0-9_]
* X? 匹配0次或1次
* X* 任意次
* X+ 至少1次
* X{n} 正好n次
* X{n,} 至少n次
* X{n,m} 至少n次,最多m次
*
*
* @author 蛙课网
*
*/
public class Test03 {
public static void main(String[] args) {
//判断字符串是否匹配邮箱格式
String email = "feifei@wkcto.com";
String regex = "[a-zA-Z1-9]\\w{4,30}@\\w{2,}\\.(com|cn)";
System.out.println( email.matches( regex ));
// 替换所有
String text = "wkcto123good";
text = text.replaceAll("\\d", "*"); //把替换后的字符串给返回
System.out.println( text );
//字符串的分隔
text = "wkcto is the best website.";
String [] words = text.split("[.,\\s]+");
for (String string : words) {
System.out.println( string );
}
}
}
● String字符串是不可变的
package com.wkcto.chapter04.string;
/**
* String对象是不可变的
* @author 蛙课网
*
*/
public class Test04 {
public static void main(String[] args) {
String s1 = "hello";
s1 = "world";
/* String对象是不可变的
* "hello"是字符串对象 , s1是String类型变量, s1保存String对象的引用
* String对象不可变是指不能把"hello"字符串变为"world"字符串
* 在执行s1="world"时, 创建了一个新的"world"字符串对象, 把该对象的引用保存到s1变量中
*/
String s2 = "world";
System.out.println( s1.equals(s2)); //true
System.out.println( s1 == s2 ); //true, 说明s1和s2引用 了同一个"world"对象
//new运算符会在堆区中创建一个新的对象
String s3 = new String("hello");
String s4 = new String("hello");
System.out.println( s3 == s4 );
}
}
package com.wkcto.chapter04.string;
/**
* String对象是不可变的
* 每次进行字符串连接都 会生成新的字符串对象
* @author 蛙课网
*
*/
public class Test05 {
public static void main(String[] args) {
String s1 = "wkcto";
String s2 = s1 + "sxbdqn";
/*
* 使用+运算符进行字符串连接时, 借助StringBuilder类实现
* 先根据s1创建一个StringBuidler对象, 假设叫sb
* 调用sb对象的append()方法把"sxbdqn"连接起来
* 最后调用sb对象的toString()方法,在该方法中创建一个新的String对象,并把该对象返回赋值给s2
*/
//以下两行共创建了多少个String对象? 3个: 常量 :"abc", "def" 生成的新的对象"abcdef"
String s3 = "abc";
String s4 = s3 + "def"+ "abc" + "def";
//以下两行共创建了多少个String对象? 3个: 常量 : "hehe", "he" , 生成新的: "hehehehe"
s3 = "hehe";
s4 = s3 + "he" + "he";
//以下两行共创建了多少个String对象? 2个: 常量 : "haha", "hahahaha"
s3 = "haha";
s4 = "ha" + "ha" + s3; //javac编译器,会把"ha"+"ha"常量的连接进行优化为"haha"
//以下两行共创建了多少个String对象? 2个: 常量 : "heihei", new出来一个对象
s3 = "heihei";
s4 = new String("hei" + "hei"); //javac编译器会把"hei"+"hei"优化为"heihei"
}
}
StringBuilder/StringBuffer
String对象是不可变的, 每次进行字符串的连接都会生成新的字符串对象, 如果需要频繁进行字符串连接时, 不建议使用String字符串, 而是使用StringBuilder/StringBuffer
StringBuilder/StringBuffer称为可变的字符串
package com.wkcto.chapter04.string;
/**
* StringBuilder/StringBuffer
* 1) 称为可变的字符串
* 2) 最常用的方法是append(), 在当前字符串的后面追加另外一个字符串
* 3) 默认初始化大小: 16
* 4) 当value数组已满,需要扩容, 按 value.length * 2 + 2 大小扩容
* 5) StringBuffer提供的方法都使用了synchronized进行了修饰, 是线程安全的.
* StringBuilder不是线程安全的
* @author 蛙课网
*
*/
public class Test06 {
public static void main(String[] args) {
String text = "";
for( int i = 1; i <= 100; i++){
text = text + i; //每次会生成新的字符串对象, 还会产生一些垃圾对象
}
//频繁字符串连接, 使用StringBuilder/StringBuffer
StringBuilder sb = new StringBuilder();
for( int i = 1; i <= 100; i++){
sb.append(i);
}
StringBuffer sb2 = new StringBuffer();
sb2.append("hello");
}
}