如果我们对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费空间。我们用StringBuffer就可以解决这个问题。
A:StringBuffer的构造方法:
public StringBuffer(): 无参构造方法
public StringBuffer(int capacity): 指定容量的字符串缓冲区对象
public StringBuffer(String str): 指定字符串内容的字符串缓冲区对象
B:StringBuffer的方法:
public int capacity():返回当前容量。 理论值
public int length():返回长度(字符数)。 实际值
C:案例演示
构造方法和长度方法的使用
public class Demo1 {
public static void main(String[] args) {
//字符串缓冲区
//StringBuffer相当于一个容器,是一个长度可变的字符序列
//无参构造:public StringBuffer(): 构造一个不带字符的字符串缓冲区,它的初始容量为16个字符
StringBuffer stringBuffer = new StringBuffer();
//有参构造:public StringBuffer(int capacity): 指定容量的字符串缓冲区对象
StringBuffer sb = new StringBuffer(32);
//有参构造:public StringBuffer(String str): 指定字符串内容的字符串缓冲区对象
StringBuffer sb1 = new StringBuffer("abcde");
/* public int capacity ():返回当前容量。理论值
* public int length ():返回长度(字符数)。实际值*/
int capacity = stringBuffer.capacity();//容量——会自动扩充
int length = stringBuffer.length();//实际长度
System.out.println(capacity);//16
System.out.println(length);//0
}
}
A:StringBuffer的添加功能
public StringBuffer append(String str):
可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身
public StringBuffer insert(int offset,String str):
在指定位置把任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身
B:案例演示
StringBuffer的添加功能
public class Demo2 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("abc");
/* public StringBuffer append(String str):
* 可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身*/
StringBuffer sb2 = sb.append("ABC");
System.out.println(sb == sb2);//true
//两个的地址值一样,说明append()方法返回的还是原来这个对象
System.out.println(sb2.toString());//abcABC
//StringBuffer类重写了toString方法。把存在容器中的数据,转成字符串类型
/* public StringBuffer insert(int offset,String str):
* 在指定位置把任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身*/
StringBuffer sb3 = sb.insert(0, "i am "); //可以传任意类型
System.out.println(sb3);//i am abcABC
//输出的是i am abcABC,而不是i am abc,再次说明他们都指向同一个地址
System.out.println(sb == sb3); //true
}
}
A:StringBuffer的删除功能
public StringBuffer deleteCharAt(int index):
删除指定位置的字符,并返回本身
public StringBuffer delete(int start,int end):
删除从指定位置开始指定位置结束的内容,并返回本身
B:案例演示
StringBuffer的删除功能
*/
public class Demo3 {
public static void main(String[] args) {
//上面已经提到,StringBuffer相当于一个容器
// 我们可以通过append和insert方法给里面追加内容
// 那么我们也可以通过deleteCharAt和delete方法删除容器里的内容,用法是相似的
/* public StringBuffer deleteCharAt(int index):
* 删除指定位置的字符,并返回本身
* public StringBuffer delete(int start,int end):
* 删除从指定位置开始指定位置结束的内容,并返回本身*/
StringBuffer sb1 = new StringBuffer("abc");
StringBuffer sb2 = sb1.deleteCharAt(0);
System.out.println(sb2);//bc
System.out.println(sb1 == sb2);//true
StringBuffer sb3 = sb1.delete(0, 1);
System.out.println(sb3);//c
//删除指定索引的一段字符,含头不含尾
System.out.println(sb2 == sb3);//true
}
}
A:StringBuffer的替换功能
public StringBuffer replace(int start,int end,String str):
从start开始到end用str替换,含头不含尾
B:StringBuffer的反转功能
public StringBuffer reverse():
字符串反转
C:案例演示
StringBuffer的替换和反转功能
public class Demo4 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("aslfjlskafjilawjflskdfssdf");
int f = sb.indexOf("f", 3);
//返回指定字符第一次出现的索引
System.out.println(f);//3
int f1 = sb.lastIndexOf("f", sb.length() - 1);
//从后往前检索,返回指定字符第一次出现的索引
System.out.println(f1);//25
/* * public StringBuffer replace(int start,int end,String str):
* 从start开始到end用str替换,含头不含尾*/
StringBuffer replace = sb.replace(0, sb.length(), "我爱中国");
//含头不含尾
System.out.println(replace.toString());//我爱中国
System.out.println(sb.toString());//我爱中国
System.out.println(sb == replace);//true
/* B:StringBuffer的反转功能
* public StringBuffer reverse():
* 字符串反转*/
StringBuffer sb1 = new StringBuffer("abcde");
StringBuffer reverse = sb1.reverse();
//返回的还是字符串缓冲区本身
System.out.println(reverse.toString()); //edcba
System.out.println(sb1 == reverse); //true
}
}
A:StringBuffer的截取功能
public String substring(int start):
从指定位置截取到末尾
public String substring(int start,int end):
截取从指定位置开始到结束位置,包括开始位置,不包括结束位置
B:注意事项
注意:返回值类型不再是StringBuffer本身
C:案例演示
StringBuffer的截取功能及注意事项
public class Demo5 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("salesmanshipslaksdjfaksd");
String substring = sb.substring(0, 4);
//注意这里返回的类型是String类而非Substring类
System.out.println(substring);
}
}
A:String -- StringBuffer
a:通过构造方法
b:通过append()方法
B:StringBuffer -- String
a: 使用substring方法
b:通过构造方法
c:通过toString()方法
C:案例演示
StringBuffer和String的相互转换
public class Demo6 {
public static void main(String[] args) {
//1、String —— StringBuffer
String s = new String("abcd");
//方法一:通过构造方法
StringBuffer sb = new StringBuffer(s);
//方法二:通过append方法
StringBuffer sb2 = new StringBuffer().append(s);
//方法三:通过insert方法
StringBuffer sb3 = new StringBuffer().insert(0, s);
//2、StringBuffer —— String
StringBuffer stringBuffer = new StringBuffer("aaaaaa");
//方法一:使用substring方法
String s1 = stringBuffer.substring(0,2);//截取两个a
//方法二:通过构造方法
String s2 = new String(stringBuffer);
//方法三:通过toString方法
String s3 = stringBuffer.toString();
}
}
A:案例演示
需求:把数组中的数据按照指定个格式拼接成一个字符串
举例:
int[] arr = {1,2,3};
输出结果:
"[1, 2, 3]"
用StringBuffer的功能实现
public class Demo7 {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
StringBuffer sb = new StringBuffer("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
sb.append(arr[i] + "]");
} else {
sb.append(arr[i] + ",");
}
}
String s = sb.toString();
System.out.println(s);
}
}
A:案例演示
需求:把字符串反转
举例:键盘录入"abc"
输出结果:"cba"
用StringBuffer的功能实现
public class Demo8 {
public static void main(String[] args) {
System.out.println("请输入一个字符串");
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
String s1 = new StringBuffer(s).reverse().toString();
System.out.println(s1);
}
}
String类:代表字符串。 Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例。 字符串不变; 它们的值在创建后不能被更改。 字符串缓冲区支持可变字符串。 因为String对象是不可变的,它们可以被共享。
StringBuffer类:线程安全,可变的字符序列。 字符串缓冲区就像一个String ,但可以修改。 在任何时间点,它包含一些特定的字符序列,但可以通过某些方法调用来更改序列的长度和内容。 字符串缓冲区可以安全地被多个线程使用。
StringBulider类:一个可变的字符序列。 此类提供与StringBuffer的API,但不保证同步。 此类设计用作简易替换为StringBuffer在正在使用由单个线程字符串缓冲区的地方(如通常是这种情况)。 在可能的情况下,建议使用这个类别优先于StringBuffer ,因为它在大多数实现中将更快。
1)字符修改上的区别(主要)
String:不可变字符串;
StringBuffer:可变字符串、效率低、线程安全;
StringBuilder:可变字符序列、效率高、线程不安全;
2)初始化上的区别,String可以空赋值(null),后者不行,报错
小结:
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
大部分情况下,在速度上,StringBuilder > StringBuffer > String
A:形式参数问题
String作为参数传递
String虽然是引用类型,但是它是一个常量
所以在做传递的时候,完全可以将其看成基本数据类型数据进行传递
StringBuffer作为参数传递
B:案例演示
String和StringBuffer分别作为参数传递问题
public class Demo9 {
public static void main(String[] args) {
/*基本数据类型作为参数传递,形参的改变,不影响实参
*引用数据类型作为参数传递,形参的改变,会影响实参*/
int a = 1;
setInt(a);
System.out.println(a);//输出的还是1,实参a没有发生变化
//String类型的传参方式与基本类型的特点是一致的,特殊一些
String s = "abc";
setSt(s); //形参改变不影响实参
System.out.println(s); //输出的还是abc
//String这个类一旦被初始化就不会被改变
//setSt方法调用完之后就弹栈了,ABC就消失了
//所以打印的s还是heima
StringBuffer sb = new StringBuffer("abcde");
setSB(sb);
System.out.println(sb);//edcba
//用数据类型作为参数传递,形参的改变,会影响实参
}
private static void setSB(StringBuffer sb) {
sb.reverse();
}
private static void setSt(String st) {
st.toUpperCase();
}
private static void setInt(int i) {
i++;
}
}
A:Arrays类概述
针对数组进行操作的工具类。
提供了排序,查找等功能。
B:成员方法
public static String toString(int[] a)
public static void sort(int[] a)
public static int binarySearch(int[] a,int key)
C:案例演示
通过Arrays类的功能来进排序和查找
关于这部分我想总结的比较多,数组的排序、查找都是比较重要的内容,我后面专门写一篇博客来总结,完成后我会在这里贴一个链接。
A: 需求:
a:将100转换成二进制 , 八进制 , 十六进制
b:判断一个数是否在int的范围内
B:为什么会有基本类型包装类
为了对基本数据类型进行更多的操作,更方便的操作,java就针对每一种基本数据类型提供了对应的类类型.
C:常用操作: 常用的操作之一:用于基本数据类型与字符串之间的转换。
D:基本类型和包装类的对应
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
A:Integer类概述
Integer 类在对象中包装了一个基本类型 int 的值,
该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,
还提供了处理 int 类型时非常有用的其他一些常量和方法
B:构造方法
public Integer(int value)
public Integer(String s)
C:案例演示
使用构造方法创建对象
public class IntegerDemo1 {
public static void main(String[] args) {
/*[static int] MAX_VALUE:值为 2^(31-1) 的常量,它表示 int 类型能够表示的最大值。
[static int] MIN_VALUE:值为 -2^(31) 的常量,它表示 int 类型能够表示的最小值。*/
//1、获取int类型能够表示的最大值和最小值
int minValue = Integer.MIN_VALUE;
int maxValue = Integer.MAX_VALUE;
System.out.println("最大值是" + maxValue + "最小值是" + minValue);
//最大值是2147483647最小值是 - 2147483648
/*B:构造方法
* public Integer(int value)
* 构造一个新分配的 Integer 对象,它表示指定的 int 值
* public Integer(String s)
* 构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。*/
Integer integer = new Integer(100);
//参数是int
Integer integer1 = new Integer("100");
//参数是String,字符串必须全是数字,否则会报
//NumberFormatException 数字格式化异常
}
}
A:int -- String
a:和""进行拼接
b:public static String valueOf(int i)
c:int -- Integer -- String
d:public static String toString(int i)
B:String -- int
a:String -- Integer -- intValue();
b:public static int parseInt(String s)
C:案例演示
String和int类型的相互转换
public class IntegerDemo2 {
public static void main(String[] args) {
//1、int-------String,主要记第二个方法
int i = 100;
//方法一:和空字符串拼接
String s = i + "";
//方法二:String类的valueOf()静态方法----很强大,可以把所有基本数据类型转成字符串
String s1 = String.valueOf(i);
//方法三:int----Integer.toString()静态方法;
String s2 = Integer.toString(i);
//2、String-------int,记第二个方法
String string = "100";
//方法一:String----Integer-----intValue()非静态
int i1 = new Integer(string).intValue();
//方法二:String-----Intrger.parseInt()静态方法
int i2 = Integer.parseInt(string);
}
}
public class IntegerDemo3 {
public static void main(String[] args) {
int i =100;
System.out.println(Integer.toBinaryString(i)); //二进制
System.out.println(Integer.toOctalString(i)); //八进制
System.out.println(Integer.toHexString(i)); //十六进制
//见名知意,它们返回的都是String类型
}
}
自动装箱:把基本类型转换成包装类类型;
自动拆箱:把包装类类型装换成基本类型;
这里有一篇前辈的详解> https://blog.csdn.net/teacher_lee_zzsxt/article/details/79230501
A:JDK5的新特性
自动装箱:把基本类型转换为包装类类型
自动拆箱:把包装类类型转换为基本类型
B:案例演示
JDK5的新特性自动装箱和拆箱
Integer ii = 100;
ii += 200;
C:注意事项
在使用时,Integer x = null;代码就会出现NullPointerException。
建议先判断是否为null,然后再使用。
public class IntegerDemo4 {
public static void main(String[] args) {
//我们先按照上面的方法创建一个新的Integer对象
int num = 100;
Integer in = new Integer(num);
//JDK5之后的新特性,自动装箱和自动拆箱,我们就可以简写
Integer integer = 100;//自动装箱:int---Integer
//自动装箱:把基本数据类型转换成包装类类型
int i = integer + 100;//自动拆箱:Integer---int
//我们也可以手动拆装箱----了解
int n = 100;
Integer integer1 = Integer.valueOf(n); //手动装箱
int intValue = integer1.intValue(); //手动拆箱
//其实java里的自动箱也是这样实现的,我们用反编译软件就可以看到
//记住这两个方法就行
//注意:在使用时,Integer x = null;代码会出现NullPointException。
//建议使用前进行null判断。
Integer a = 100;
if (a != null) {
a += 100;
}
System.out.println(a);//200
}
}
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2);
//false,new了两个新对象,引用地址不同
System.out.println(i1.equals(i2));
//true,Integer重写了equals方法,比较值是否相同
System.out.println("-----------");
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);
//false,new了两个新对象
System.out.println(i3.equals(i4));
//true
System.out.println("-----------");
Integer i5 = 128;
Integer i6 = 128;
System.out.println(i5 == i6);
//false 因为 超过了一个字节-128~127的范围 会new 一个Integer对象
System.out.println(i5.equals(i6));
System.out.println("-----------");
Integer i7 = 127;
Integer i8 = 127;
System.out.println(i7 == i8);
//true 没有超过一个字节的范围 因为在方法区中存在一个 字节常量池 范围-128---127
System.out.println(i7.equals(i8));
我们知道在 i >= -128 并且 i <= 127 的时候,第一次声明会将 i 的值放入缓存中,第二次直接取缓存里面的数据,而不是重新创建一个Ingeter 对象。所以 i7 == i8 输出的是true(127在缓存中),而 i5 == i6输出的是false(第二次声明i6时new了新对象)。
基本类型和包装类的对应
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
与int和Integer的关系一样,其余的基本数据类型也都有各自对应的包装类,它们的用法与Integer是相似的。
public class ByteDemo {
public static void main(String[] args) {
//获取byte类型的最大值和最小值
System.out.println(Byte.MAX_VALUE);//127
System.out.println(Byte.MIN_VALUE);//-128
byte a = 100;
//byte----String
String s = String.valueOf(a);
//Stirng----byte
byte a2 = Byte.parseByte(s);
Byte b = a;//自动装箱byte---Byte
Byte b1 = Byte.valueOf(a);//手动装箱
byte a3 = b;//自动拆箱Byte---byte
byte a4 = b1.byteValue();//手动拆箱
}
}
public class CharacterDemo {
public static void main(String[] args) {
char ch = 'c';
//自动装箱
Character character = ch;
//手动装箱
Character character1 = Character.valueOf(ch);
//自动拆箱
char c = character;
//手动拆箱---charValue()
char c1 = character.charValue();
//static boolean isUpperCase ( char ch)
//确定指定字符是否为大写字母。
boolean a = Character.isUpperCase('A');//true
//static boolean isSpaceChar ( char ch)
//确定指定字符是否为 Unicode 空白字符。
boolean spaceChar = Character.isSpaceChar(' ');//true
//static boolean isLowerCase ( char ch)
//确定指定字符是否为小写字母。
boolean a1 = Character.isLowerCase('a');//true
//static boolean isDigit ( char ch)
//确定指定字符是否为数字。
boolean digit = Character.isDigit('9');//true
}
}