string常用方法
string的值是不可变的,因为底层用的是final修饰的一个char数组
字符串的定义
String str1="hello";
String str2=new String("hello");
string容易出现的问题:
private static void demo1() {
String str1="he"+"llo";
String str2="hello";
System.out.println(str1==str2);//true
String str3="he";
String str4="llo";
String str5=str3+str4;
System.out.println(str2==str5);//false
}
string(bytes):
byte[] bytes={97,98,99};
String str3=new String(bytes);
System.out.println("str3:"+str3);//str3:abc
System.out.println(Charset.defaultCharset());//UTF-8
string(bytes[],charset)
try {
String str4=new String(bytes,"UTF-8");
System.out.println("str4"+str4);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
getbytes()得到字符串的字节码解码
String str4="欧阳";
byte[] bytes1= str4.getBytes();
System.out.println(Arrays.toString(bytes1));
//解码[-26, -84, -89, -23, -104, -77]
string(byte[],charset)将字符数组用特定的编码格式编码
String s = null;
try {
s = new String(bytes1,"GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(s);
//编码默认utf-8,我这里给了GBK,出现乱码:娆ч槼
string(byte[],charset.forName())
//string(byte[],charset.foeName())
String s1=new String(bytes1,Charset.forName("UTF-8"));
System.out.println(s1);//欧阳,底层已经处理了异常
string(char[],fromindex,endindex)
char[] chars={'h','e','l','l','o'};
String s2=new String(chars,0,3);
System.out.println(s2);
//从第一个元素开始,将三个字符转换成字符串:hel
toCharArray():将字符串转换成字符数组来输出
String num="123";
char[] chars = num.toCharArray();
for (char aChar : chars) {
System.out.print(aChar);//将字符串的字符遍历输出
int n=Character.digit(aChar,10);
}
split方法利用指定的regex来分割字符串:
String str="1001-admin-23-46";
String[] split = str.split("-");
for (String s : split) {
System.out.println(s);
}
split的参数有两个时,其中limit表示控制匹配次数
- limit大于零时:输出limit个元素的数组,匹配次数为limit-1
String str="abaeaaasash";
String[] as = str.split("a",5);
//默认limit为0,最大值为数组的长度
System.out.println(Arrays.toString(as));
// 输出结果[, b, e, , asash],匹配了四次剩下的未匹配的都丢进同一个数组索引,as[4]
System.out.println(as.length);//5
- limit=0,默认limit等于零,若最后元素为空会舍弃空元素
String str="abaeaa";
String[] as = str.split("a");//默认limit为0,最大值为数组的长度
System.out.println(Arrays.toString(as));
System.out.println(as.length);
//limit=0时,最后元素为空会舍掉
// 输出结果[, b, e]
- limit<0时,不会舍弃末尾为空的元素
String str="abaeaa";
String[] as = str.split("a",-1);
//这里-1,-2,-3结果都是一样的
System.out.println(Arrays.toString(as));
// 输出结果[, b, e, , ]
System.out.println(as.length);//5
charAt():将指定位置字符串转化成字符
String str="hello";
int len=str.length();
for(int i=0;i<len;i++){
System.out.println(str.charAt(i));
}
indexOf():检索字符串第一次所出现的索引位置,如果找到末尾也没找到返回-1,包头不包尾
String str = "hello,he is headache";
System.out.println(str.indexOf("l"));
System.out.println(str.indexOf("l", str.indexOf("l") + 1));
//包含第一个l出现的索引位置,因此得+1
//循环遍历查找出现he的索引
int i = 0;
int len=str.length();
while (i < len) {
int index = str.indexOf("he", i);
i = index + 2;
System.out.println(index);
}
lastIndexOf()寻找最后一次出现指定字符的位置,他是从右向左找,依旧包头不包尾
String str="hello,he is headache";
System.out.println(str.lastIndexOf("he"));
//寻找出现指定字符串的最后一个索引位置
System.out.println(str.lastIndexOf("he",5));
//从第5个索引开始向左边开始寻找索引位置,返回0
System.out.println(str.lastIndexOf("he",6));
//包头不包尾,输出6
截取:substring()
private static void demo6() {
String str="abdec";
System.out.println(str.substring(1));
//从指定索引开始到末尾:bdec
System.out.println(str.substring(1,3));
//从指定索引开始到指定索引结束包头不包尾:bd
}
private static void demo9() {
String phone="18379876753";
String first=phone.substring(0,3);
//包头不包尾
String end=phone.substring(7);
System.out.println(first+"****"+end);
}
截取常用的位置:截取文件名称
public static void main(String[] args) {
demo7("E:\\知乎.jpg");
demo7("D:\\知乎.jpg");
}
private static void demo7(String filesPath) {
//可以利用split分割,将最后一个元素输出,但是需要四个"\"
String[] split = filesPath.split("\\\\");
System.out.println(split[split.length - 1]);
String
//利用lastIndexOf()方法来实现
fileName=filesPath.substring(filesPath.lastIndexOf("\\")+1);
System.out.println(fileName);
//但是当有两个名称相同但是储存位置不同的不同文件
//需要保证文件名称的唯一性:
/* //1.时间戳:获得当前时间纳秒数 fileName=System.currentTimeMillis()+"_"+fileName;
System.out.println(fileName);*/
//2.随机的java.util.UUID
fileName=UUID.randomUUID().toString()+"_"+fileName;
System.out.println(fileName);
}
replace(): 替换
private static void demo8() {
String fileName = "4e854dfe-b84c-4a42-9a06-c0657415061f_知乎.jpg";
String name=fileName.replaceAll("-", "");
System.out.println(name);
String name1=fileName.replaceFirst("-","");
System.out.println(name1);
}
字符串比较:
String str="abc";
String str1=new String("abc");
//System.out.println(str==str1.intern());
//比较的是常量,比较的是常量池的常量
//使用equals来比较,底层是instanceof,因此比较的对象要先转成字符串
System.out.println(str.equals(str1));
System.out.println(str.hashCode()==str1.hashCode());
String code="AbdHj";
String code1="abdhj";
//不区分大小写来比较,也可以全部转换成大写或者小写来比较
System.out.println(code.equalsIgnoreCase(code1));
//用compareTo来比较,相等为0
System.out.println(code1.compareTo(code));
System.out.println(code1.compareToIgnoreCase(code));
endsWith(" "): 判断字符串是否是以开头/结尾
String path="C:\\a.jpg";
if(!path.endsWith("jpg")&&!path.endsWith("png"))throw new RuntimeException("文件格式不符合需求");
System.out.println(path);
contains(" "): 判断字符串是否包含某字符,底层时indexOf()
String s="hello";
System.out.println(s.contains("l"));
isEmpty(): 判断字符串是否是空
String s1=null;
if(s1.isEmpty())throw new RuntimeException("string is null");
string的拼接:
String str1="hello";
String str2="world";
String str=str1.concat(str2);
System.out.println(str);
String str3=str1+str2;
System.out.println(str3);
System.out.println(str3==str);//concat是new的,因此返回false
//join拼接
String name="admin";
String password="admin123";
int age=23;
//拼接成admin-admin23-23
String s= String.join("-",name,password,String.valueOf(age));
System.out.println(s);
trim()
String str=" hello ";
String s1="hello";
//去除字符串左右两端的空格
System.out.println(str.trim().equals(s1));//true
//如果要去掉所有的空格,可以用replace/replaceAll替换
str="he l l o";
String str1=str.replaceAll("\\s","");//\s是特殊转义字符,表示空格
System.out.println(str1);
intern():将字符串的值与常量池的值相比较,如果相等返回true,如果常量池没有该常量,将该字符串放进常量池再进行比较
When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
String str = "hello";
String str1 = new String("hello");
System.out.println(str == str1.intern());//true
正则表达式:
基本语法:
/*
^:开头
$:结尾,$n:$1获得第n个小括号里面的内容
():组/域段
[]:具体的字符内容
{}:限定相邻[]里面的数据出现的次数 如:[a]{3,9}表示a必须出现3次到9次
\d:匹配任意数字0-9
\s:匹配任意空白字符
+,*,?:匹配内容出现一次或多次
.:匹配任意的一个单字符
[a-z],[A-Z],[0-9]
*/
案例:
校验用户名是否输入规范:
String name="admin_123";
//第一个字母要大写,后面有3到5位的字母或者数字,要有一个_-#,小写字母或数字2-4个
String nameRegex="^([A-Z]{1})([a-zA-Z0-9]{3,5})([_|-|#]{1})([a-z]{2,4})$";
Pattern pattern=Pattern.compile(nameRegex);
Matcher matcher = pattern.matcher(name);
boolean result=matcher.matches();
System.out.println(result);//false
//可以用下面match来替换
System.out.println(name.matches(nameRegex));//false
手机号码加*号:
String phone="18379758337";
String phoneRegex="^([\\d]{3})([\\d]{4})([\\d]{4})$";
//需要使用源字符串的部分数据替换本身
//动态获取第一个()和第三个()的数据
System.out.println(phone.replaceAll(phoneRegex,"$1****$3"));
去除重复的字符数据:
String str = "huechsghkshhj";
int len = str.length();
char[] c = new char[len];
int i = 0;
for (int index = 0; index < len; index++) {
boolean flag = false;
char ch = str.charAt(index);
for (char c1 : c) {
if (c1 == ch) {
flag = true;
break;
}
}
//每次c数组的元素值会改变,因此需要得到c遍历完之后的结果再来进行赋值
if (!flag) {
c[i++] = ch;
}
}
str = new String(c);
System.out.println(str);
stringBuilder和stringBuffer继承同一个抽象类,功能一模一样,
值是否可变 | 线程是否安全 | 效率 | 内存(拼接) | |
---|---|---|---|---|
String | 不可变,底层是final修饰的char数组 | 值不可变,安全 | 一般 | 每次拼接都会生成新的对象,占据堆内存 |
StringBuffer | 可变,底层为没加final修饰的char数组 | 底层是同步的,安全 | 最慢 | 有且只有一个对象 |
StringBuilder | 可变 | 不安全:不可充当成员变量来使用 | 最快 | 有且只有一个对象 |
在不考虑线程安全的情况下,优先使用stringbuilder,初始化容量为16
StringBuilder builder=new StringBuilder();
builder.append("hello");
builder.append("hello");
builder.append("hello");
builder.append("hello");
System.out.println(builder);
//hellohellohellohello
当初始化值大于16的时候会创建一个新的容量:
string.getChars()方法:
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
- srcBegin -- 字符串中要复制的第一个字符的索引。
- srcEnd -- 字符串中要复制的最后一个字符之后的索引。
- dst -- 目标数组。
- dstBegin -- 目标数组中的起始偏移量。
没有返回值但是会抛出异常
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
insert(拼接位置索引,拼接字符串)
builder.insert(0,"123");
System.out.println(builder);
//123hellohellohellohello
builder.insert(0,"123");//在第0个索引位拼接123字符串
System.out.println(builder);
builder.deleteCharAt(0);//删除第一个字符串
builder.deleteCharAt(builder.lastIndexOf("l"));//删除最后一次出现的l
builder.delete(0,3);//删除前三个字符串
System.out.println(builder);
//elo包头不包尾,删掉前三个字符串
builder.setCharAt(builder.indexOf("l"),'a'); //将第一次出现的l换成a字符 System.out.println(builder.reverse());//oae