“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情”
引言
String,StringBuffer,StringBuilder,char[],用来表示字符串。
I 预备知识
1.1 Object类
是所有类的根类
toString():
打印格式为全限定名@hashCode。
注:全限定名=包名+类名,包名与类名使用点号连接,用来唯一标识一个类。
在输出对象时,默认调用对象的toStirng方法。
个人推荐使用如下重写toString,有更高的兼容性:
@Override
public String toString() {
return org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(this);
}
equals():
在Object中比较的是对象的地址是否相等
sun建议:重写equals方法时,保证两个相同内容的对象作比较的结果为true,来达到equals方法比较对象的内容,
==运算符比较的是对象地址的目的。
1.2 重写的规则
- 自反性:如果对象o非空,那么o.equals(o)的放回值为TRUE。
- 对称性:如果对象x,y非空,那么x.equals(y)与y.equals(x)的放回值一样。
- 传递性:如果对象x,y,z非空,如果x.equals(y)的放回值为TRUE,y.equals(z)的放回值为TRUE,那么 如果x.equals(z)的放回值为TRUE.
- 一致性:对于任何非空引用x,y,那么多次调用x.equals(y)的放回值始终2一样(前提:对象上被比较的内容没被修改)
- 对于任何非空应用x,那么x.equals(null)的放回值始终为false。
在写实体类是必须重写equals方法
public class EqualsDemo{
int id;
public boolean equals(Object obj){
if(obj==null){
return false;
}
if(this==obj){
return true;
}
if(obj instanceof EqualsDemo){
EqualsDemo e=(EqualsDemo)obj;
return this.id=s.id;//比较的是内容,是具体的cr而定
}
return false;
}
}
面试题:
shopping[] ss=new Shopping[]{s,new shopping()};
shopping[] ss1=new Shopping[]{s1,new shopping()};
System.out.println(Arrays.equals(ss,ss1));
注: 1))ss和ss1作比较时,是把数组中的对象作比较,在对象作比较时需要调用equals方法,
所以要求shopping对象要重写equals方法。
另外在扩展一下:list和set的contains方法:
- List的contains():只调用equals方法来判断结果
- Set的contains方法是先调用hashCode方法来判断,如果为真,就再调用对应的equals方法进行判断;如果hashCode方法比较的结果为false,就直接返回结果。
1.3 hashCode方法
public native int hashCode();
是一个本地方法,采用hash算法将地址转换成唯一编码。
1)在重写equals方法时,须重写hashCode方法。
注:如果equals方法的值为TRUE,那么对象的hashCode必须一致 如果equals方法的值为false,那么对象的hashCode必须不一致 (因为hashCode方法返回的值是唯一标识当前对象的内容,而非它的地址)
2)当一个对象产生后,那么它的hashCode不能改变。hashCode通常情况下采用唯一标识(OID)。
II String
2.1 String的特性
- String类是不能被继承的,它被final修饰。
- String类内部的实现是char[](为什么不直接使用char[],干嘛还要用String: char[]值可随意的被改变,且字符串本身也是一种类型)
- 字符串的字面量也是String类型的实例(比如:String str="abc";//abc为字面量)。
- String类的设计原则是对象的内容不变。
- String类在实例化的过程中,如果他的实例都是字面量,且字面量的结果一致,那么系统会优化,让其在内存中的值存在一个空间中。 示例:
package com.csuinfosoft.stringDemo;
/**
*
* @author 张坤楠
* @date 下午3:22:58
* String对象的比较,这里同一个对象的概念为内存地址,即使采用==比较对象,
* 而非采用equals和hashCode,因为他们比的是内容。
*/
public class StringDemo {
public static void main(String[] args){
String str1="abc123";
String str2="abc"+"123";
final int i=123;
String str3="abc"+i;
//其中str1,str2,str3均为同一个对象。
String str7="abc";
String str8=str7+"123";//str1,和str8不是同一个对象,因为str7是变量,而非字面量。
String str9=new String("abc123");//str1,str7,str8,str9这是个为不同的四个对象
System.out.println(str1==str2);//true,比较的是内存地址
System.out.println(str1==str3);//true,比较的是内存地址
System.out.println(str2==str3);//true,比较的是内存地址
System.out.println(str1.equals(str2));//true,比较的是内容
System.out.println(str1==str8);//false,比较的是内存地址
System.out.println(str1.equals(str8));//true,比较的是内容
System.out.println(str1.hashCode()==str8.hashCode());//true,比较的是内容
System.out.println(str1==str9);//false,比较的是内存地址
System.out.println(str8==str9);//false,比较的是内存地址
}
}
- String重写了toString(),equals(),hashCode()方法
- String API,如果String的方法的返回值为String类型时,那么就会产生一个新的对象,包括加号也会产生新对象。toString方法除外。
int length() 字符串长度
char charAt() 切割字符串,索引从0开始。
boolean equals(Object ) 比较两个字符串的内容是否相等
String trim() 去(前后)空白(空格,换行,制表符)的方法,
示例:
package com.zhongxin.util;
/**
*
* @author 张坤楠
* 去掉字符串的中间空白的示例
*/
public class DeleteSpaceUtil {
public static String deleteSpace(String message){
String str = new String();
String[] middle = message.split(" ");//没有必要提前去前后空白,
//因为middle的最后一个元素和第一个元素的长度与message前后空白无关
for(int i=0;i
String toLowerCase() 吧字符串大写转化成小写
String toUpperCase() 吧字符串大写转化成小写
String indexof(String str) 按照从左至右顺序查找str的位置,值查找第一个str就返回,找不到就返回-1.
String indexof(char c)
String indexof(String str,int loc ) 从loc位置开始,从左查找字符串的第一次出现的位置。
String ilastIdexof(String str ) 从字符串的微博查找字符串str的第一次出现的位置。
String subString(int i) 从i的位置开始到字符串结尾的字符串截取出来
String subString(int start,int end) 截取从start到end-1的位置的字符串。
String concat(String str) 连接字符串,和加号的作用一样
char[] tocharArray 吧字符串转化成字符串数组
new String(char[] c) 把字符数组转化成字符串
2.2 字符串和正则
- api
boolean match(String regex) ;
用于判断当前的字符串是否符合regex正则表达式。String split (String regex)
根据regex将字符串切割成多个字串String replaceAll(String regex ,String str);
regex为要被替换的正则表达式,str为替换的内容。
分割字符串
// 添加活动的限制条件
if (StringUtils.isNotBlank(activity.getMerchantNatures())) {
var natures = StringUtils.split(activity.getMerchantNatures(), ",");
if (natures.length == 1) {
lambda.eq(TMerMerchant::getNature, activity.getMerchantNatures());
} else {
lambda.in(TMerMerchant::getNature, natures);//(nature IN (?,?)
}
}
- 正则表达式:用指定字符来限制当前字符串的内容。
正则的语法:
普遍的字符串 ”abc“
【】
代表当前位置可以出现的字符{}
代表当前字符串可以出现的次数:示例,手机号码,num.matches("[1]{1}[3458]{1}[0-9]{9}");
注:【0-9】- 从起始位置到结束之间的字符串多可取。
- ^ 字符串的起始位置,行的开头
$
字符串的结束位置,行的结尾
示例:用户名:字母,数字,下划线,长度为6,20.
^[0-9a-zA-Z_]{6,20}$
或者^\\w{6,20}$
其中\
是用于转换的
{start,end}
代表可以出现start到end之间数字的次数
\d
代表【0-9】\D
代表非数字\w
代表【a-zA-Z0-9_】 字符\W
代表【^\w】
2.3 StringBuilder,StringBuffer
- 特点:都是被final修饰,不能被继承。
都是动态字符序列(采用动态数组的算法,来实现动态存储数据方式,完成字符串的动态存储,采用变长数组存储。)
内存对象内容是可变的,说明他们是一个可变的字符序列。
StringBuilderAPI
StringBuilder append(String)
向原字符串追加新的字符串 -StringBuilder insert(int index,String str)
在index位置向原字符串插入新的字符串str,index从0开始StringBuilder delete(int index,int end)
删除start到end的字符串,小标不包含end,即到end-1
- 应用场景:有大量的字符串操作
String
,StringBuilder
,StringBuffer
之间的转化
StringBuilder
,StringBuffer
到String
的转化:调用toString()
方法String
转化到StringBuilder
,StringBuffer
:使用对应的构造器,比如:new StringBuilder(String str);
//注:java优化String代码的示例:
public class StringJavaDemo{
public static void main(String[] args){
String str1="a";
String str2="b";
String str3=str1+str2;//ava会优化此代码,相当于Str3=new StringBuilder().appned(str1).append(str2).toString();
}
}
- StringBuilder,StringBuffer之间的关系
- 相同点:
内部是char[],是可变的字符序列
API大致相同
- 不相同点:
StringBuffer,是java早期引入的,线程安全,速度慢
StringBuilder,是java 5.0引入的,非线程安全,速度快
String采用定长数组,StringBuilder,StringBuffer采用变长数组