StringBuffer
StringBuffer就是字符串缓冲区,是用于存储数据的容器。
特点:
1、长度可变
2、可以存储不同类型的数据
3、最终要转换为字符串使用
4、可以对字符串进行修改
构造函数:
StringBuffer():构造一个其中不带字符的字符串缓冲区,初始容量为16个字符;
StringBuffer(int capacity):构造一个不带字符,但具有指定初始容量的字符串缓冲区,可以避免初始容量太小,而不得不重新开辟新的空间来存储,这样可以节约资源,提高效率;
StringBuffer(String str):构造一个字符串缓冲区,并将其内容初始化为指定的字符串。
当字符串缓冲区存储的内容超过长度时,它会另外开辟一段空间,这个空间通常比原数组多一倍,这个新的数组空间会将原来的数组内容复制过来(通过遍历),再将新的元素也放在原内容之后。
既然StringBuffer是一种容器,那么它就该具备容器的基本功能:增删改查C(create)U(update)R(read)D(delete)。
1.添加(包括插入)
StringBuffer append(data);各种数据类型都可以 除了byte和short类型
StringBuffer insert(index,data);
public class StringBufferDemo_1 {
public static void main(String[] args) {
//创建缓冲区对象
StringBuffer sb=new StringBuffer();
sb.append(4).append(false).append("haha");
sb.append(true);
sb.insert(2,"wuwuwu");
System.out.println(sb);
}
}//输出:4fwuwuwualsehahatrue
2.删除
StringBuffer delete(int start,int end):删除的元素包含头不包含尾
StringBuffer deleteCharAt(int index):删除指定位置的元素
public class StringBufferDemo_2 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("abcde");
sb.delete(1,3);
System.out.println(sb);
//清空缓冲区
// sb.delete(0,sb.length());
// System.out.println(sb);
}
}//输出:ade
3.查找
char charAt(index);
int indexOf(string);
int lastIndexOf(string);
public class StringBufferDemo_3 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("abcdae");
char x=sb.charAt(3);
int y=sb.indexOf("cd");
int z=sb.lastIndexOf("a");
System.out.println(x);//d
System.out.println(y);//2
System.out.println(z);//4
}
}
4.修改
StringBuffer replace(start,end,string);
void setCharAt(int index,char ch);
public class StringBufferDemo_4 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("abcdae");
sb.replace(1, 3, "mmm");
System.out.println(sb);//ammmde
sb.setCharAt(2, 'w');
System.out.println(sb);//amwmde
sb.setLength(2);
System.out.println("sb="+sb);//sb=am
System.out.println(sb.length());//2
System.out.println(sb.reverse());//ma
}
}
StringBuilder
一个线程在添加另外一个线程在删除就会出现线程安全问题,需要加同步。但是单线程就没有线程安全问题,如果还是用StringBuffer则每次操作都需要判断锁,效率降低。
jdk1.5以后出现了功能和StringBuffer(jdk1.1版本时就已经存在)一模一样的对象,就是Stringbuilder。
两种不同在于:
StringBuffer是线程同步的,多用于多线程;
StringBulider是线程不同步的,通常用于单线程。它的出现提高效率。
每个字符缓冲区都有一定的容量。只要字符缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从jdk1.5开始,为该类补充了一个单线程使用的等价类,即StringBuilder,与该类相比,通常应该优先使用StringBuilder类,因为它支持所有相同的操作。但是由于它不执行同步,所以速度更快。
练习一:将一个int型数组变成字符。
public class StringBuiderTest {
public static void main(String[] args) {
int[] arr={3,1,4,5,8};
String s=arrayToString(arr);
String s1=arrayToString_2(arr);
System.out.println(s);
System.out.println(s1);
}
public static String arrayToString_2(int[] arr){
StringBuilder sb=new StringBuilder();
sb.append("[");
for(int i=0;i<arr.length;i++)
{
if(i!=arr.length-1)
sb.append(arr[i]+",");
else
sb.append(arr[i]+"]");
}
return sb.toString();
}
//这种方法每转换一个数组元素都会在字符串池中产生一个新的字符串,浪费空间
public static String arrayToString(int[] arr){
String str="[";
for(int i=0;i<arr.length;i++)
{
if(i!=arr.length-1)
str+=arr[i]+",";
else
str+=arr[i]+"]";
}
return str;
}
}
基本数据类型包装类
为了方便操作基本数据类型值,将其封装成了对象, 在对象中定义了属性和行为丰富可该数据的操作。 用于描述该对象的类就称为基本数据类型对象包装类。
基本数据类型与其对应的包装类如下:
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
包装类对象主要用于基本类型和字符串之间的转换。
基本类型—>字符串
1.基本类型数值+””
2.用String类中的静态方法valueOf(基本类型数值)
3.用Integer的静态方法toString(基本数据类型)
字符类型—->基本类型
1.使用包装类中的静态方法 xxx parseXxx(“xxx类型的字符串”);
int parseInt(“intstring”)
long parseLong(“longstring”)
boolean parseBoolean(“booleanstring”)
只有Character没有parse方法。
2,如果字符串被Integer进行对象的封装,可以使用另一个非静态的方法:intValue()将一个Integer对象转成基本数据类型值。
下面以Integer类举例:
public class WrapperDemo {
public static void main(String[] args) {
//Integer类提供的四个常量
System.out.println(Integer.MAX_VALUE);//2147483647
System.out.println(Integer.MIN_VALUE);//-2147483648
System.out.println(Integer.SIZE);//32
System.out.println(Integer.TYPE);//int
//字符类型---->基本类型
int num=4;
Integer i=new Integer(5);
int x=Integer.parseInt("123");//parseInt是静态方法,可以直接类名调用
Integer j=new Integer("123");
System.out.println(j.intValue());
System.out.println(Integer.parseInt("123")+1);//1234
System.out.println("123"+1);//1231
//基本类型--->字符串
System.out.println(""+4+1);//41
System.out.println(String.valueOf(4)+1);//41
System.out.println(Integer.toString(4)+1);//41
}
}
Integer类对进制转换的操作
十进制—>其他进制:
toBinaryString
toOctalString
toHexString
其他进制—>十进制:
parseInt(“string”,radix)
代码示例:
public class WrapperDemo {
public static void main(String[] args) {
//十进制--->其他进制
System.out.println(Integer.toBinaryString(60));//111100
System.out.println(Integer.toOctalString(60));//74
System.out.println(Integer.toHexString(60));//3c
System.out.println(Integer.toString(60, 4));//330
//其他进制---->十进制
System.out.println(Integer.parseInt("3c",16));//60
}
}
自动装箱
jdk1.5之后,有了一个新的特性:自动装箱。
一般我们要创建一个类的对象实例的时候,我们会这样:
Class a = new Class(parameter);
当我们创建一个Integer对象时,却可以这样:
Integer i=4;
执行上面那句代码的时候,系统为我们执行了:
Integer i=new Integer(4);
自动装箱后的数据可以与基本数据类型进行直接的运算。这个时候便实现了自动拆箱,即将将对象中的基本数据从对象中自动取出:
i=i+6;
这里的i是上一语句的Integer对象,执行本句,实际上等于执行了:
i=new Integer(i.intValue()+6);
这种自动装箱实现了代码的简化书写。
如果装箱的是一个字节,那么该数据会被共享不会开辟新的空间。下面以代码来说明这句话的含义:
public class WrapperDemo {
public static void main(String[] args) {
//Integer类重写了equals方法,此方法在这里会比较Integer类封装的值的大小
Integer a=new Integer("3");
Integer b=new Integer(3);
System.out.println(a==b);//false
System.out.println(a.equals(b));//true
System.out.println(a.compareTo(b));//>:1 =:0 <:-1
//在jdk1.5之前未自动装箱,虽然m,n都是用127这个int型的数据作为参数而创建的,但是它们不共享数据
Integer m=new Integer(127);
Integer n=new Integer(127);
System.out.println(m==n);//false
System.out.println(m.equals(n));//true
//jdk1.5以后,自动装箱,如果装箱的是一个字节,那么该数据会被共享不会开辟新的空间,如果超过了一个字节,则要开辟新的空间。
Integer x=127;
Integer y=127;
System.out.println(x==y);//true
System.out.println(x.equals(y));//true
Integer x1=128;
Integer y1=128;
System.out.println(x1==y1);//false
System.out.println(x1.equals(y1));//true
}
}
练习二:对一个字符串中的数值进行从小到大的排序:
“20 78 9 -7 88 36 29”
思路: 1、将字符串变成字符串数组:用split方法。
2、将字符串数组中的元素变成int型:parseInt方法
3、对int型数组进行排序:数组的静态方法Arrays.sort(num_arr)
public class Test {
public static void main(String[] args) {
String numStr="20 78 9 -7 88 36 29";
System.out.println(numStr);//20 78 9 -7 88 36 29
numStr=sortStringNumber(numStr);
System.out.println(numStr);//-7 9 20 29 36 78 88
}
public static String sortStringNumber(String numStr){
//1,将字符串变成字符串数组
String[] str_arr=StringToArray(numStr);
//2,将字符串数组变成int数组
int[] num_arr=toIntArray(str_arr);
//3,对int数组排序
mySortArray(num_arr);
//4,将排序的int数组变成字符串
String temp=arrayToString(num_arr);
return temp;
}
public static String[] StringToArray(String numStr){//封装 ,提高阅读性
String[] str_arr=numStr.split(" ");//已有对象的功能
return str_arr;
}
public static int[] toIntArray(String[] str_arr){
int[] num_arr=new int[str_arr.length];
for(int i=0;i<str_arr.length;i++)
{
num_arr[i]=Integer.parseInt(str_arr[i]);
}
return num_arr;
}
public static void mySort(int[] num_arr){
Array.sort(num_arr);
}
public static String arrayToString(int[] num_arr) {
StringBuilder sb=new StringBuilder();
for(int x=0;x<num_arr.length;x++){
if(x!=num_arr.length-1)
sb.append(num_arr[x]+" ");
else
sb.append(num_arr[x]);
}
return sb.toString();
}
}