java第十六天学习笔记
1.常见对象(StringBuffer类)
(1)StringBuffer类概述(理解)
我们如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费空间。
而StringBuffer就可以解决这个问题
线程安全的可变字符序列
B:简述安全问题
C:StringBuffer和String的区别
(2)_常见对象(StringBuffer类的构造方法)(掌握)
A:StringBuffer的构造方法:
public StringBuffer(): 无参构造方法
public StringBuffer(int capacity): 指定容量的字符串缓冲区对象
public StringBuffer(String str): 指定字符串内容的字符串缓冲区对象
B:StringBuffer的方法:
public int capacity():返回当前容量。 理论值
public int length():返回长度(字符数)。 实际值
C:案例演示
构造方法和长度方法的使用
(3)常见对象(StringBuffer的添加功能)(掌握)
A:StringBuffer的添加功能
public StringBuffer append(String str):可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身
public static void main(String[] args) {
//如果我们要进行拼串的操作,推荐使用StringBuffer
// StringBuffer 长度可变的字符序列
//String 长度不可变的字符序列 String s="abc";
// StringBuffer() 构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符。
//StringBuffer 其实可以看做一个字符容器,不断的可以往这个容器中添加数据
StringBuffer sb = new StringBuffer();
//获取容量
int capacity = sb.capacity();
System.out.println(capacity);
//获取长度
int length = sb.length();
System.out.println(length);
//水杯:额定容量 500ML 空杯子 capacity()
//往水杯中装水 你实际装了100ML length()
//往字符串缓冲区中添加内容 如果超过了默认的容量,会自动扩充
StringBuffer sb2= sb.append("abcasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf");
//获取容器的长度
int length2 = sb.length();
System.out.println(length2);
System.out.println("===================================");
/* StringBuffer( int capacity)
构造一个不带字符,但具有指定初始容量的字符串缓冲区。*/
StringBuffer sb3 = new StringBuffer(100);
System.out.println(sb3.capacity());
sb3.append("abcdef");
System.out.println(sb3.length());
}
public StringBuffer insert(int offset,String str):在指定位置把任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("aaa");
sb.append("bbb"); //往后面追加
System.out.println(sb);
//可以在指定的位置插入任意数据,返回的还是字符串缓冲区本身
sb.insert(0, "cccc");
System.out.println(sb);
//在3索引位置的前面插入
sb.insert(3, "eeee");
System.out.println(sb);
}
(4)常见对象(StringBuffer的删除功能)(掌握)
A:StringBuffer的删除功能
public StringBuffer deleteCharAt(int index):删除指定位置的字符,并返回本身
public StringBuffer delete(int start,int end):删除从指定位置开始指定位置结束的内容,并返回本身
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("好好学习,天天向上,大家五一快乐");
//根据索引删除容器中的一个字符,返回的还是容器本身
sb.deleteCharAt(0).deleteCharAt(0).deleteCharAt(0).deleteCharAt(0);
System.out.println(sb);
System.out.println("==================================");
StringBuffer sb2 = new StringBuffer("好好学习,天天向上,大家五一快乐");
//根据起始索引和终止索引删除一段内容,返回的还是容器本身
sb2.delete(0,2); //含头不含尾
System.out.println(sb2.toString());
}
(5)常见对象(StringBuffer的替换和反转功能)(掌握)
A:StringBuffer的替换功能
public StringBuffer replace(int start,int end,String str): 从start开始到end用str替换
B:StringBuffer的反转功能
public StringBuffer reverse(): 字符串反转
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("红尘来呀来去呀去,都是一场梦");
//根据起始索引和终止索引,替换一段内容。返回的还是容器本身
sb.replace(0, 8, "皮皮虾我们走");
System.out.println(sb);
//反转容器中的数据,返回的还是容器本身
sb.reverse();
System.out.println(sb.toString));
}
C.查找该元素在数组中第一次出现的索引
public static void main(String[] args) {
//查找该元素在数组中第一次出现的索引
int[] arr = {20, 20, 3, 2, 1, 0, 2, 6, 8, 9, 100};
int index = getIndex(arr, 100);
System.out.println("索引是:"+index);
}
//基本查找:挨个找
private static int getIndex(int[] arr, int ele) {
for (int j = 0; j < arr.length; j++) {
if (ele == arr[j]) {
return j;
}
}
return -1;
}
D.在容器中查找索引
从头查找该字符串,在容器中第一次出现的索引,如果找不到就返回-1
int indexOf (String str)
从指定索引处开始查找该字符串第一次出现的索引,如果找不到就返回-1
int indexOf (String str,int fromIndex)
从后往前找
int lastIndexOf (String str)
int lastIndexOf (String str,int fromIndex)
public static void main(String[] args) {
//从头查找该字符串,在容器中第一次出现的索引,如果找不到就返回-1
// int indexOf (String str)
//从指定索引处开始查找该字符串第一次出现的索引,如果找不到就返回-1
// int indexOf (String str,int fromIndex)
/* int lastIndexOf (String str)
int lastIndexOf (String str,int fromIndex)*/
StringBuffer sb = new StringBuffer("尘红来呀来去呀去,都是一场梦");
int index = sb.indexOf("来");
System.out.println(index);
}
(6)常见对象(StringBuffer的截取功能及注意事项)(掌握)
A:StringBuffer的截取功能
public String substring(int start): 从指定位置截取到末尾
public String substring(int start,int end): 截取从指定位置开始到结束位置,包括开始位置,不包括结束位置
B:注意事项 注意:返回值类型不再是StringBuffer本身
C:案例演示
StringBuffer的截取功能及注意事项
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("红尘来呀来去呀去,都是一场梦");
//截取容器中的一段内容,返回的是截取到的字符串
//从3索引处,截取到末尾
String s = sb.substring(3);
System.out.println(s);
System.out.println("=======================");
//根据起始索引和终止索引,截取一段内容,以String类型返回。不会影响,容器中的内容
String s1 = sb.substring(0, 8);
System.out.println(s1);
System.out.println(sb);
}
(7)常见对象(StringBuffer和String的相互转换)(掌握)
A:String – StringBuffer
a:通过构造方法
b:通过append()方法
B:StringBuffer – String
a: 使用substring方法
b:通过构造方法
c:通过toString()方法
C:案例演示
public static void main(String[] args) {
//StringBuffer类型和String类型的相互转换
// StringBuffer------>String
StringBuffer sb = new StringBuffer("abcdfe");
sb.append("123456789");
//方式1,使用toString()方法 记住
String string = sb.toString();
System.out.println(string);
//方式2:sbString(0)
String s = sb.substring(0);
System.out.println(s);
//方式3:可以采用String类中的构造方法
/* String(StringBuffer buffer)
分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。*/
String s1 = new String(sb);
System.out.println(s1);
System.out.println("===================================");
// Stirng----->StringBuffer
String str="abc";
//方式1:采用StringBuffer的构造方法
StringBuffer stringBuffer= new StringBuffer(str);
//方式2:使用append() insert()方法
StringBuffer buffer = new StringBuffer();
buffer.append(str);
buffer.insert(0,str);
}
(8)常见对象(把数组转成字符串)(掌握)
A:案例演示
需求:把数组中的数据按照指定个格式拼接成一个字符串
举例:
int[] arr = {1,2,3};
输出结果:
"[1, 2, 3]"
用StringBuffer的功能实现
public static void main(String[] args) {
int[] arr = {1, 2, 3,4,5};
StringBuffer sb = new StringBuffer("[");
for (int i = 0; i < arr.length; i++) {
if(i==arr.length-1){
sb.append(arr[i]).append("]");
}else{
sb.append(arr[i]).append(",");
}
}
//把容器中的数据,以字符串的形式取出来
String string = sb.toString();
System.out.println(string);
}
(9)常见对象(字符串反转)(掌握)
A:案例演示
需求:把字符串反转
举例:键盘录入"abc"
输出结果:"cba"
用StringBuffer的功能实现
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一段字符串");
String s = scanner.nextLine();
//链式编程
String s1 = new StringBuffer(s).reverse().toString();
System.out.println(s1);
}
(10)常见对象(StringBuffer和StringBuilder的区别)(掌握)
A:StringBuilder的概述
通过查看API了解一下StringBuilder类
B:面试题
String,StringBuffer,StringBuilder的区别
相同点:他们两个的API是相同的。
区别是:线程安全方面的区别
//StringBuffer是线程安全的,效率低
//StringBuilder 线程不安全的,效率高。多线程环境下,可能会存在线程安全问题
/*StringBuilder 一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,
但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,
用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,
建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。*/
(11)常见对象(String和StringBuffer分别作为参数传递)(掌握)
A:形式参数问题
String作为参数传递 String虽然是引用类型,但是它是一个常量,所以在做传递的时候,完全可以将其看成基本数据类型数据进行传递,String类型输入值传递
StringBuffer作为参数传递
public static void main(String[] args) {
//引用类型,作为参数传递,属于引用传递,传递的是地址值,形参的改变会影响实参。(String例外,String属于值传递)
//但是String字符串比较特殊,虽说String是引用类型。但是他作为参数传递,属于值传递。
String str="abc";
test(str);
System.out.println(str); //2 abc
System.out.println("================================");
//引用类型,作为参数传递,属于引用传递,传递的是地址值,形参的改变会影响实参。
StringBuffer sb = new StringBuffer("好好学习");
test(sb);
String string = sb.toString();
System.out.println(string);
}
private static void test(StringBuffer ss) {
ss.append(",天天向上").reverse();
System.out.println(ss.toString());
}
private static void test(String s) {
s+="我爱你";
System.out.println(s); //1 abc我爱你
}
2.数组排序
数组排序:把一个无序序列,通过比较交换等手段,使其变成一个有序序列。
数组排序:冒泡排序,选择排序,插入排序,快速排序,归并排序,基数排序,堆排序,等
(1)常见对象(数组高级冒泡排序原理图解)(掌握)
A:画图演示
需求:
数组元素:{24, 69, 80, 57, 13}
请对数组元素进行排序。
B:冒泡排序原理
相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处
/数组中的元素两两比较,大的往后放,经过一轮比较后,最大的元素,就出现在了最后面。/
(2)常见对象(数组高级冒泡排序代码实现)(掌握)
public static void main(String[] args) {
int[] arr = {24, 69, 80, 57, 13,20,30,1,0,-1};
//把一坨代码抽取到方法中 快捷键 ctrl+alt+M
// tuiDao(arr);
//外层循环控制轮次
for (int j = 0; j <arr.length-1; j++) {
//里层循环进行两两比较
for (int i = 0; i < arr.length - 1-j; 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));
}
private static void tuiDao(int[] arr) {
//第一轮:比较了四次
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));
//第二轮:比较三次
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));
}
(3)常见对象(数组高级选择排序原理图解)(掌握)
A:画图演示
需求:
数组元素:{24, 69, 80, 57, 13}
请对数组元素进行排序。
B:选择排序原理
从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
public static void main(String[] args) {
//选择排序:从0索引处的元素开始,依次跟他后面的元素挨个比较,小的往前放,经过一轮比较后,最小的元素就出现在最前面
int[] arr = {24, 69, 80, 57, 13, 2, 20, 30, 50, 1};
// tuiDao(arr);
//外层循环控制轮次
for (int index = 0; index < arr.length - 1; index++) {
for (int i = 1 + index; 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));
}
private static void tuiDao(int[] arr) {
//第一轮:从0索引处开始,比较了4次
int index = 0; //
for (int i = 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 = 1 + index; 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 = 1 + index; 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));
//第四轮:从3索引处开始
index = 3; //
for (int i = 1 + index; 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)直接插入排序
A.写法一
public static void main(String[] args) {
//直接插入排序
//每次拿后面的一个元素,插入到之前的一个有序序列当中,使之任保持有序.
// [2,3,9,9,6]
//假如我这个序列只有一个元素,那他就是一个有序序列
//[2]
/* [2], 3, 1, 9, 6]
[2,3]
[1,2,3]
[1,2,3,9]
[1, 2, 3,6,9]*/
int[] arr = {10, 3, 20, 0, 1,-1,200,50,30,20,15};
//直接插入排序
//外层循环定义轮次
for (int i = 1; i < arr.length; i++) {
//如果当前元素,小于前一个元素,得交换位置
int j=i;
while (j>0&&arr[j] < arr[j- 1]) {
int t=arr[j];
arr[j]=arr[j-1];
arr[j-1]=t;
//递减,跟前面的元素继续比
j--;
}
}
System.out.println(Arrays.toString(arr));
}
B.写法二
public static void main(String[] args) {
int[] arr = {10, 3, 20, 0, 1, -1, 200, 50, 30, 20, 15, 22, 23, 11};
//直接插入排序写法2
//外层循环控制轮次
for (int i = 1; i < arr.length; i++) {
for (int j = i; j > 0; j--) {
//如果当前元素,比前一个元素小,就交换位置
if (arr[j] < arr[j - 1]) {
int t = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = t;
}
}
}
System.out.println(Arrays.toString(arr));
}
(5)快速排序的方法
/**
* @param arr 待排序数组
* @param start 起始索引
* @param end 终止索引
*/
public static 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);
}
}
/*
挖坑填数
1. 将基准数挖出形成第一个坑。
2.由后向前找比他小的数,找到后挖出此数填到前一个坑中。
3.由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
4.再重复执行2,3两步骤。
*/
private static int getIndex(int[] arr, int start, int end) {
int i = start;
int j = end;
//1.找一个数作为基准数
int x = arr[i];
//4.重复2,3步
while (i<j){
// 2.由后向前找比他小的数,找到后挖出此数填到前一个坑中。
while (i < j && arr[j] >= x) {
j--;
}
//找到之后,挖坑填数
if (i < j) {
arr[i] = arr[j];
i++;// 下一次要从前完后找,那就顺便让i递增一下
}
//3.由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
while (i < j && arr[i] < x) {
i++;
}
//找到之后,挖坑填数
if (i < j) {
arr[j] = arr[i];
j--; //下次要从后往前找,那就顺边让j 递减一下
}
}
//让基准数填到最后一个坑中
arr[i]=x;
return i; //i==j 返回基准数所在位置
}
(6)二分查找
A:画图演示
B:二分查找:前提数组元素必须有序
C:二分查找的思想:每一次都查中间的那个元素,比较大小就能减少一半的元素。
public static void main(String[] args) {
//二分查找:前提是数组元素有序
int[] arr = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
//C:二分查找的思想:每一次都查中间的那个元素,比较大小就能减少一半的元素。
int index = getIndex(arr, 20);
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; //4
while (minIndex <= maxIndex) {
//如果我们要找的元素,正好等于中间索引所对应的元素,那就直接返回中间索引
if (ele == arr[centerIndex]) {
return centerIndex;
//如果我们找的元素小于中间索引所对应的元素,我们就移动最大索引
} else if (ele < arr[centerIndex]) {
maxIndex = centerIndex - 1;
//如果我们要找的元素大于中间索引所对应的元素,我们就移动最小索引
} else if (ele > arr[centerIndex]) {
minIndex = centerIndex + 1;
}
//再次计算中间索引
centerIndex = (minIndex + maxIndex) / 2;
}
return -1;
}