String是final类,不允许有子类,是操作字符串的类。
字符串的常见定义:
String s1 ="abc"; //s1是一个类类型变量,"abc"是一个对象,字符串一旦初始化,就不可以被改变
String s2="abc"; //s1,s2两个变量指向通一个对象,即s1,s2在栈中存放的地址所指向堆中的"abc"对象是一样的,换句话说s1==s2
String s3=new String("abc"); //s3是用new方法重新建立一个String类对象,此对象与s1,s2所值的对象不同,即s3!=s1
String s4=s2; //将s2的指向赋给s4并没有创建对象
String s5=s1+"efg"; //在堆内存中new一个String类对象放入s1所指向的"abc"对象,然后再将"egf"加到“abc”后面,原来堆中的"abc"并没发生变化
以上代码设计到字符串常量池概念。
字符串和字节数组在转换的过程中是可以指定编码表的:
String(byte[] bytes,Charset charset)
String(byte[] bytes,String charsetName)
此知识点在后面的IO中也有涉及到。
常见的字符串操作:
1.获取
①获取长度
int length();//前面的int是返回值,下同
②获取某个位置上的字符
char charAt(int Index);
③根据字符获取该字符在字符串中的位置
int indexOf(int ch);//返回ch在字符串中第一次出现的位置
int indexOf(int ch,int fromIndex);//从formIndex位置开始获取ch在字符串中第一次出现的位置
int indexOf(String str);//返回的是str在字符串中第一次出现的位置
int indexOf(String str,int fromIndex);//从formIndex位置开始获取str在字符串中第一次出现的位置
2.判断
①字符串是否包含一个子串
boolean contains(Stringstr);//比较:int indexOf(String str);//返回值为int的方法也可用作判断,不包含是返回-1
②字符串中是否有内容
boolean isEmpty();//此方法的原理是判断字符串长度是否为0
③字符串是否以指定的内容开头和结尾
boolean startWith(String str);
boolean endWith(String str);
⑤判断字符串内容是否相同
boolean equals(String str);
⑥判断内容是否相同,并忽略大小写
boolean equalsIgnoreCase(String str);//个人认为此方法在账号登陆,验证码等应用很多
3.转换
①将字符数组转成字符串
构造函数:
String(char[] ch);
String(char[] ch,int offset,int count);//将字符数组的一部分转换成字符串,注意:在JAVA的API中出现很频繁的词语应该掌握,比如offset,代表偏移量,此处即从哪开始
静态方法:
static String copyValueOf(char[] ch);
static String copyValueOf(char[] ch,int offset,int count);
static String valueOf(char[] ch);
②将字符串转换为字符数组
char[] toCharArray();
③将字节数组转换成字符串,上面有描述了,此处不再赘述
④将字符串转成字节数组
byte[] getBytes();
⑤将基本数据类型转成字符串
static String valueOf(int num);
static String valueOf(double num);
3+""; //这代码很常见
4.替换
String repalce(char oldchar,char newchar);//如果要替换的字符不存在则返回原串
5.切割
String[] split(String regex);
例:String str="changsan,lisi,wuwu";
String[] arr=str.split(",");//将str切割成字符串数组"changsan""lisi""wuwu"
6.子串
String subString(int begin);
String subString(int begin,int end);
7.转换,去除空格,比较
①将字符串转成大写或者是小写
String toUpperCase();
String toLowerCase();
②将字符串两端的多个空格去除
String trim();
③对两个字符串进行自然顺序的比较
s1.compareTo(S2);
练习:s1,s2两个字符串,找出最大的共同子串(注:以下为关键代码,其中s1是长度较大的子串)
for(int x=0;x for(int y=0,z=s2.length()-x;z!=s2.length()+1;y++,z++){ String temp=s2.subString(y,z); if(s1.contains(temp)) return temp; } } 感想:个人认为还是思路算法很重要,如果没有明确的思路,怎么想都想不出怎么比较,通过这个练习,在黑马论坛有一道杨哥专栏中的题目,也找到类似的练习,详见我的另一篇日记《黑马论坛中的练习》 StringBuffer与StringBuilder StringBuffer是字符串缓冲区,是一个容器,是线程安全的,是效率低下的 以下是StringBuffer的功能,我觉得重要的就写个代码出来,其他的可以参与API 1.存储 StringBuffer append(String str);//此方法传入参数并不止String对象,详见API文档 2.删除 3.获取 4.修改 5.反转 StringBuffer reverse(); Jdk1.5后出现的StringBuilder不保证同步,线程不安全,效率高,简易实现StringBuffer 小常识:java升级的三因素:①提高效率②简化书写③提高安全性 基本数据类型对象包装类最常见的作用: 基本数据类型对象包装类和字符串之间的转换 ①基本数据类型==>字符串 基本数据类型+"" 基本数据类型.toString(基本数据类型的值) 如:Integer.toString(34);//将整数变成字符串"34" ②字符串==>基本数据类型 基本数据类型包装类.parseXxx(String str); 如:Integer.parseInt("123");//注意:必须传入数字格式的字符串,要不会抛异常 基本数据类型这里涉及到一个涉及模式,好像是“享元设计”,即操作较频繁的对象静态化,我花了点时间查了API,API代码如下:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low));
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
通过上述代码可知自动装箱其实调用的就是valueOf(int num)的方法,而不new对象的情况下[-128,127]的自动装箱生成的Integer对象都是单例对象,即用“==”比较的地址引用也相同