今日学习:
StringBuffer
StringBuilder
数组常见操作
Arrays
基本数据类型包装类
StringBuffer类的概述
- StringBuffer类(线程安全的可变字符序列)
可以认为是一个字符容器,你可以不断往容器中追加内容。 - StringBuffer和String的区别
StringBuffer重写了toString方法,会把它容器中的内容转换成字符串形式。
StringBuffer类的构造方法
- StringBuffer的构造方法:
public StringBuffer(): 无参构造方法
public StringBuffer(int capacity): 指定容量的字符串缓冲区对象
public StringBuffer(String str): 指定字符串内容的字符串缓冲区对象 - StringBuffer的方法:
public int capacity():返回当前容量。 理论值
public int length():返回长度(字符数)。 实际值
StringBuffer的添加功能
- public StringBuffer append(String str):
可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身。
例如 sb.append(“abc”); - public StringBuffer insert(int offset,String str):
在指定位置把任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身。
例如 sb.insert(offset:0,str:0000000);
StringBuffer的删除功能
- public StringBuffer deleteCharAt(int index):
删除指定位置的字符,并返回本身。
例如:sb.deletecharAt(0); - public StringBuffer delete(int start,int end):
删除从指定位置开始指定位置结束的内容,并返回本身。
例如:sb.delete(start:0,end:3);
StringBuffer的替换和反转功能
-
StringBuffer的替换功能
public StringBuffer replace(int start,int end,String str):从start开始到end用str替换。 -
StringBuffer的反转功能
public StringBuffer reverse():字符串反转。 -
从头查找该字符串,在容器中第一次出现的索引,如果找不到就返回-1:
int indexOf (String str) -
从指定索引处开始查找该字符串第一次出现的索引,如果找不到就返回-1:
int indexOf (String str,int fromIndex)
从后往前找
int lastIndexOf (String str)int lastIndexOf (String str,int fromIndex)
StringBuffer的截取功能及注意事项
public String substring(int start): 从指定位置截取到末尾
public String substring(int start,int end): 截取从指定位置开始到结束位置,包括开始位置,不包括结束位置
注意:返回值类型不再是StringBuffer本身
StringBuffer和String的相互转换
- String – StringBuffer
(1).通过构造方法
(2).通过append()方法 - StringBuffer – String
(1).使用substring方法
(2).通过构造方法
(3).通过toString()方法
小练习1:拼接字符串
需求:把数组中的数据按照指定个格式拼接成一个字符串
举例:
int[] arr = {1,2,3};
输出结果:
"[1, 2, 3]"
用StringBuffer的功能实现
**代码如下:**
public class Test {
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]).append(']').insert(0,"[");
}else{
sb.append(arr[i]).append(',');
}
}
System.out.println(sb.toString());
}
}
小练习2:字符串反转
需求:把字符串反转
举例:键盘录入"abc"
输出结果:"cba"
用StringBuffer的功能实现
**代码如下:**
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串:");
String s = sc.nextLine();
StringBuffer sb = new StringBuffer(s).reverse().toString();
System.out.println(s1);
}
}
StringBuffer和StringBuilder的特点
StringBuffer(线程安全的可变字符序列,效率低)
StringBuilder(线程不安全的可变字符序列,效率高)
String和StringBuffer分别作为参数传递
String作为参数传递 String虽然是引用类型,但是它是一个常量,所以在做传递的时候,完全可以将其看成基本数据类型数据进行传递,String类型输入值传递,StringBuffer作为参数传递。
**代码如下:**
public class Test {
public static void main(String[] args) {
//引用类型,作为参数传递,形参的改变会影响实参。
//基本类型作为参数传递,形参的改变,不影响实参。
//字符串虽说是引用类型,但是他作为参数传递,属于值传递,跟基本数据类型一致。
String str="hello";
test(str);
System.out.println(str);//2.hello
StringBuilder sb = new StringBuilder("abc");
test(sb);
System.out.println(sb.toString());//3.bbbcba
}
private static void test(StringBuilder sb) {
sb.append("bbb");
sb.reverse();
}
private static void test(String s) {
s+="world";
System.out.println(s); //1.helloworld
}
}
StringJoiner类
- StringJoiner(CharSequence delimiter)
构建了一个字符容器,指定分隔符。 - StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
构建了一个字符容器,指定分隔符,前缀,后缀。 - StringJoiner add(CharSequence newElement)
增加了一份给 CharSequence值的 StringJoiner价值的下一个元素。
数组排序
- 原理:通过对数组元素的比较替换移动位置等等,是一个无序序列,变成一个有序序列。
- 排序方法:排序算法:冒泡排序,选择排序,插入排序,快速排序,归并排序,基数排序,堆排序。
冒泡排序原理图解
原理:相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处。
**代码如下:**
private static void main(int[] arr) {
//第一轮:比4次
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
int t = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = t;
}
}
System.out.println(Arrays.toString(arr));
//第二轮比3次
for (int i = 0; i < arr.length - 1 - 1; i++) {
if (arr[i] > arr[i + 1]) {
int t = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = t;
}
}
System.out.println(Arrays.toString(arr));
//第三轮比2次
for (int i = 0; i < arr.length - 1 - 1 - 1; i++) {
if (arr[i] > arr[i + 1]) {
int t = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = t;
}
}
System.out.println(Arrays.toString(arr));
//第三轮比1次
for (int i = 0; i < arr.length - 1 - 1 - 1 - 1; i++) {
if (arr[i] > arr[i + 1]) {
int t = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = t;
}
}
System.out.println(Arrays.toString(arr));
}
}
冒泡排序优化代码实现
**代码如下:**
public class Test {
public static void main(String []args) {
int []arr={13,45,34,23,56,23,14,33};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
选择排序原理图解
原理:从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处。
**代码如下:**
private static void main(int[] arr) {
//第一轮:从0索引处开始
int index = 0;
for (int i = 0 + 1; i < arr.length; i++) {
if (arr[index] > arr[i]) {
int t = arr[index];
arr[index] = arr[i];
arr[i] = t;
}
}
System.out.println(Arrays.toString(arr));
//第二轮:从1索引处开始
index = 1;
for (int i = 0 + index + 1; i < arr.length; i++) {
if (arr[index] > arr[i]) {
int t = arr[index];
arr[index] = arr[i];
arr[i] = t;
}
}
System.out.println(Arrays.toString(arr));
//第三轮:从2索引处开始
index = 2;
for (int i = 0 + index + 1; i < arr.length; i++) {
if (arr[index] > arr[i]) {
int t = arr[index];
arr[index] = arr[i];
arr[i] = t;
}
}
System.out.println(Arrays.toString(arr));
//第4轮:从3索引处开始
index = 3;
for (int i = 0 + index + 1; i < arr.length; i++) {
if (arr[index] > arr[i]) {
int t = arr[index];
arr[index] = arr[i];
arr[i] = t;
}
}
System.out.println(Arrays.toString(arr));
}
}
选择排序优化代码实现
**代码如下:**
public class Test {
public static void main(String[] args) {
int arr[]={23,12,43,22,13,45,67};
for (int index = 0; index < arr.length-1; index++) {
for (int i = 1 + index ; i < arr.length; i++) {
if(arr[index]>arr[i]){
int temp=arr[index];
arr[index]=arr[i];
arr[i]=temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
直接插入排序概述及代码实现
原理:从1索引处开始,把后面的元素插入到之前的一个有序序列中,使之扔保持有序。
代码如下:
1.while循环:
public class Test {
public static void main(String[] args) {
int arr[]={23,12,0,-1,5,6,43,22,13,45,67};
//外层循环控制轮次
for (int i = 1; i < arr.length; i++) {
//由于i++和原本的j-1共用一个变量会导致冲突,故而将变量i赋给变量j
int j=i;
//由于不能无限次运用j--,故而设定到j=0前为截止
while(j>0&&arr[j]<arr[j-1]){
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
j--;
}
}
System.out.println(Arrays.toString(arr));
}
}
2.for循环:
public class Test {
public static void main(String[] args) {
int arr[] = {23, 12, 0, -1, 5, 6, 43, 22, 13, 45, 67};
//外层循环控制轮次
for (int i = 1; i < arr.length; i++) {
for (int j = i; j > 0; j--) {
if (arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
快速排序概述及代码
原理:"挖坑填数"思想
**代码如下:**
public class QuickSort {
//start 默认是0
//end 是数组长度-1
public void quickSort(int[] arr, int start, int end) {
if (start < end) {
//获取分区索引
int index = getIndex(arr, start, end);
//对左右两个分区 再进行同样的步骤 ,即是递归调用
quickSort(arr, start, index - 1);//左半部分
quickSort(arr, index + 1, end);//右半部分
}
}
private int getIndex(int[] arr, int start, int end) {
int i = start;
int j = end;
//定义基准数
int x = arr[i];
//循环
while (i < j) {
//从右往左比较
while (i < j && arr[j] >= x) {
j--;
}
//从右往左找到比基准数小的数了后,填坑
if (i < j) {
//把这个数填到上一个坑位
arr[i] = arr[j];
//让 i++;
i++;
}
//从左往右找
while (i < j && arr[i] < x) {
i++;
}
// 找比基准数大的数,找到后填坑
if (i < j) {
arr[j] = arr[i];
j--;
}
}
//当上面的循环结束后把基准数填到最后一个坑位,也就一基准数为界,分成了左右两部分
arr[i] = x; //把基准数填进去
return i; //返回基准数所在位置的索引
}
}
二分查找
思想(前提数组元素必须有序):每一次都查中间的那个元素,比较大小就能减少一半的元素。
**代码如下:**
//底层算法编写
public class Test {
public static void main(String[] args) {
int arr[]={1,2,2,3,4,5,5,6,7,8};
int index=getIndex(arr,4);
System.out.println(index);
}
//二分查找
private static int getIndex(int[] arr, int ele) {
int minindex = 0;//最小索引
int maxindex = arr.length - 1;//最大索引
int centerindex = (minindex + maxindex) / 2;//中间索引
while (minindex <= maxindex) {
//假如查找元素小于中间索引,将中间索引-1继续
if (ele < arr[centerindex]) {
minindex = centerindex - 1;
}
//假如查找元素大于中间索引,将中间索引+1继续
if (ele > arr[centerindex]) {
maxindex = centerindex + 1;
}
//假如查找元素恰好等于中间索引,直接将中间索引输出
else {
return centerindex;
}
}
return -1;
}
}
//调用方法
public class Test1 {
public static void main(String[] args) {
int arr[]={1,2,2,3,4,5,5,6,7,8};
int i=Arrays.binarySearch(arr,4);
System.out.println(i);
}
}
Arrays类的概述和方法使用
- Arrays类概述
针对数组进行操作的工具类;提供了排序,查找等功能。 - 成员方法
public static String toString(int[] a)
将数组转换成字符串
public static void sort(int[] a)
快捷升序排列
public static int binarySearch(int[] a,int key)
快捷实现二分查找
static boolean equals(int[] a, int[] a2)
比较两个数组中的元素,是否一样
static int[] copyOf(int[] original, int newLength)
复制旧数组中的元素到一个新的数组中,新的数组长度是newLength,从0开始复制旧数组
static int[] copyOfRange(int[] original, int from, int to)
通过指定初始索引和终止索引,从旧数组中拷贝几个元素到新数组中(from是起始索引,to是终止索引,“含头不含尾”)
基本类型包装类的概述
- 定义:为了对基本数据类型进行更多的操作,更方便的操作,java就针对每一种基本数据类型提供了对应的类类型。
- 常用操作:用于基本数据类型与字符串之间的转换。
- 对应方式如下表:
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Interger |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
Integer类的概述和构造方法
- Integer类概述
Integer 类在对象中包装了一个基本类型 int 的值,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。 - 构造方法
public Integer(int value)
public Integer(String s) //要个一个字面上是数字的字符串,如果不是就会报错
String和int类型的相互转换
- int – String
a:和""进行拼接
b:public static String valueOf(int i)
c:int – Integer – String
d:public static String toString(int i) - String – int
a:String – Integer – intValue();
b:public static int parseInt(String s)
**代码如下:**
public class MyTest {
public static void main(String[] args) {
// String和int类型的相互转换
//int---String
int num=100;
String str=num+""; //"100"
String s = String.valueOf(num); //"100"
//方式3:
Integer integer = new Integer(num);
String s1 = integer.toString();
//String---int "666" ----- 666
String ss="666";
//NumberFormatException
int i = Integer.parseInt(ss); //这个字符串,字面上一定是个数字
System.out.println(i);
Integer integer1 = new Integer(ss);
int i1 = integer1.intValue();
System.out.println(i1);
}
}
JDK1.5的新特性:自动装箱和拆箱
- JDK5的新特性
自动装箱:把基本类型转换为包装类类型
自动拆箱:把包装类类型转换为基本类型 - 注意事项
在使用时,Integer x = null;代码就会出现NullPointerException。
建议先判断是否为null,然后再使用。
代码如下:
public class Test {
public static void main(String[] args) {
Integer ii = 100; //自动装箱
ii += 200; //自动拆箱,自动装箱。
//手动拆装箱。
int num=100;
//手动装箱 valueOf(num)
Integer integer = Integer.valueOf(num);
//手动拆箱 intValue()
int i = integer.intValue();
System.out.println(i);
int b=20+i;
System.out.println(b);
}
}
Integer的面试题
看程序写结果
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
//Integer类也重写了父类equals()方法,比较的是包装的值是否等
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true
System.out.println("-----------");
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);//false
System.out.println(i3.equals(i4));//true
System.out.println("-----------");
Integer i5 = 128;
Integer i6 = 128;
/*
Integer类也重写了父类toString()方法,把包装的值转换成字符串。
但这里有一个范围(-128-127)若超出这个范围就会导致重新new,从而导致地址值不同。
*/
System.out.println(i5 == i6);//false
System.out.println(i5.equals(i6));//true
System.out.println("-----------");
Integer i7 = 127;
Integer i8 = 127;
System.out.println(i7 == i8);//true
System.out.println(i7.equals(i8));//true
注意:
当我们采用自动装箱 Integer i7 = 127 这种方式 底层调用的是valueOf()来进行
装箱的时候,在 valueOf() 方法里面有这个判断,当我们装箱的值大于127
小于 -128 就会创建一个新的Integer对象返回。如果说我们包装的这个值,
在 -128 <=值<=127 之间,他会从 IntegerCache 这个内部类中的cache[] 数组
中取一个Integer对象返回给你,IntegerCache 他已经提前帮你创建好了 256个
Integer对象到这个cache[]中的。