java学习笔记9——常用类

字符串相关的类:

String

指向同一个地址可才相等

注意这个地方,两个person对象的name实际上指向的是同一个字符串常量池(Tom)

String常用方法

总结: 

 

1.string类的理解(以JDK8为例说明)
1.1 类的声明
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence
> final:String是不可被继承的
> Serializable:可序列化的接口。凡是实现此接口的类的对象就可以通过网络或本地流进行数据的传输。
> Comparable:凡是实现此接口的类,其对象都可以比较大小。
1.2 内部声明的属性
jdk8中:
private final char value[];//存储字符串数据的容器> final :指明此value数组一旦初始化,其地址就不可变。
jdk9开始: 为了节省内存空间,做了优化
private final byte[] value;//存储字符串数据的容器
2.字符串常量的存储位置
> 字符串常量都存储在字符串常量池(StringTable)中
> 字符串常量池不允许存放两个相同的字符串常量。
> 字符串常量池,在不同的jdk版本中,存放位置不同。jdk7之前:字符串常量池存放在方法区jdk7及之后:字符串常量池存放在堆空间3.String的不可变性的理解了。
① 当对字符串变量重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置修改
②当对现有的字符申进行拼接操作时,需要重新开辟空间保存拼接以后的字符串,不能在原有的位置修改
③ 当调用字符串的replace()替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有的位置修改4.string实例化的两种方式
第1种方式:String s1="hello";
第2种方式:String s2=new String("hello");【面试题】
String s2 = new string("hello");在内存中创建了几个对象?
一个是堆空间中new的对象。另一个是在字符串常量池中生成的字面量。5.String的连接操作:+
情况1:常量 + 常量:结果仍然存储在字符串常量池中
情况2:常量 + 变量 或 变量 + 变量:都会通过new的方式创建一个新的字符串,返回堆空间中此字符串对象的地址
情况3:调用字符串的intern(): 返回的是字符串常量池中字面量的地址(了解)情况4:concat(xxx): 不管是常量调用此方法,还是变量调用,同样不管参数是常量还是变量,总之,调用完concat()方法都返回一个新new的对象。6.string的构造器和常用方法
6.1 构造器
public String():初始化新创建的 string对象,以使其表示空字符序列。
public String(string original): 初始化一个新创建的'string’对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本
public String(char[] value):通过当前参数中的字符数组来构造新的String。
public String(char[] value,int offset,int count):通过字符数组的一部分来构造新的String。
public String(byte[] bytes):通过使用平台的**默认字符集**解码当前参数中的字节数组来构造新的String。
public String(byte[] bytes,String charsetName):通过使用指定的字符集解码当前参数中的字节数组来构造新的String6.2 常用方法
4.StringBuffer和StringBuilder中的常用方法
增:append(xx)
删:delete(int start, int end)deleteCharAt(int index)
改:replace(int start,int end, String str)setCharAt(int index,char c)
查:charAt(int index)
插:insert(int index,xx)
长度:length()7.String的算法练习

代码:

public class StringDemo {@Testpublic void test1(){String s1 = "hello"; //字面量的定义方式String s2 = "hello";System.out.println(s1 == s2); //true}/*** String的不可变性* ① 当对字符串变量重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置修改* ②当对现有的字符申进行拼接操作时,需要重新开辟空间保存拼接以后的字符串,不能在原有的位置修改* ③ 当调用字符串的replace()替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有的位置修改*/@Testpublic void test2(){String s1 = "hello";String s2 = "hello";s2 = "hi";System.out.println(s1); //hello}@Testpublic void test3(){String s1 = "hello";String s2 = "hello";s2 += "world";System.out.println(s1);//helloSystem.out.println(s2); //helloworld}@Testpublic void test4(){String s1 = "hello";String s2 = "hello";String s3 = s2.replace('l', 'w');System.out.println(s1);//helloSystem.out.println(s2);//helloSystem.out.println(s3);//hewwo}
}

练习2:

 

public class StringDemo1 {@Testpublic void test1(){String s1 = "hello";String s2 = "hello";String s3 = new String("hello");String s4 = new String("hello");System.out.println(s1 == s2); // trueSystem.out.println(s1 == s3); // falseSystem.out.println(s1 == s4);//falseSystem.out.println(s3 == s4);//falseSystem.out.println(s1.equals(s2));//true}/*** String s = new String("hello");的内存解析?或:** String s = new String("hello");在内存中创建了几个对象?*/@Testpublic void test2(){Person p1 = new Person();Person p2 = new Person();p1.name = "Tom";p2.name = "Jerry";System.out.println(p2.name); //Tom}/*** 测试String的连接符 +*/@Testpublic void test3(){String s1 = "hello";String s2 = "world";String s3 = "helloworld";String s4 = "hello" + "world";String s5 = s1 + "world"; // 通过查看字节码文件发现调用了StringBuilder的toString() ---> new String()String s6 = "hello" + s2;String s7 = s1 + s2;System.out.println(s3 == s4); //trueSystem.out.println(s3 == s5);//falseSystem.out.println(s3 == s6);//falseSystem.out.println(s3 == s7);//falseSystem.out.println(s5 == s6);//falseSystem.out.println(s5 == s7);//falseSystem.out.println();String s8 = s5.intern(); //intern():返回的是字符串常量池中字面量的地址System.out.println(s3 == s8); //true}@Testpublic void test4(){final String s1 = "hello";final String s2 = "world";String s3 = "helloworld";String s4 = "hello" + "world";String s5 = s1 + "world"; // 通过查看字节码文件发现调用了StringBuilder的toString() ---> new String()String s6 = "hello" + s2;String s7 = s1 + s2;System.out.println(s3 == s5); //trueSystem.out.println(s3 == s6); //trueSystem.out.println(s3 == s7); //true}@Testpublic void test5(){String s1 = "hello";String s2 = "world";String s3 = s1.concat(s2);String s4 = "hello".concat("world");String s5 = s1.concat("world");System.out.println(s3 == s4); //falseSystem.out.println(s3 == s5); //falseSystem.out.println(s4 == s5); //false}
}
class Person {String name;}

 练习3

public class StringMethod {@Testpublic void test1(){String s1 = new String();String s2 = new String("");String s3 = new String(new char[]{'a','b','c'});System.out.println(s3);}/*** String与常见的其他结构之间的转换* 1.String与基本数据类型,包装类之间的转换(复习)**/@Testpublic void test2(){int num = 10;//基本数据类型 ---> String//方式1:String s1 = num + "";//方式2:String s2 = String.valueOf(num);//String ---> 基本数据类型:调用包装类的parseXxx(String str)String s3 = "123";int i1 = Integer.parseInt(s1);}//String与char[]之间的转换@Testpublic void test3(){String str = "hello";//String ---> char[]:调用String的toCharArray()char[] arr = str.toCharArray();for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}//char[] ---> String:调用String的构造器String str1 = new String(arr);System.out.println(str1); //hello}//String与byte[]之间的转换(难度)/*** 在utf-8字符集中,一个汉字占用3个字节,一个字母占用1个字节* 在gbk字符集中,一个汉字占用2个字节,一个字母占用1个字节* utf-8或gbk都向下兼容了ascii码* 编码与解码:* 编码:String ---> 字节或字节数组* 解码:字节或字节数组 ---> String* 要求:解码时使用的字符集必须与编码时使用的字符集一致!不一致,就会乱码*/@Testpublic void test4() throws UnsupportedEncodingException {String str = new String("abc中国");//String ---> byte[]:调用String的getBytes()byte[] arr = str.getBytes();for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}System.out.println();//getBytes(String charsetName):使用指定的字符集byte[] arr1 = str.getBytes("gbk");for (int i = 0; i < arr1.length; i++) {System.out.println(arr1[i]);}//byte[] ---> StringString str1 = new String(arr); //使用默认的字符集:utf-8System.out.println(str1);//        String str2 = new String(arr, "utf-8"); //显式的指明解码的字符集:utf-8
//        System.out.println(str2);//乱码
//        String str3 = new String(arr, "gbk"); //显式的指明解码的字符集: gbk
//        System.out.println(str3);String str4 = new String(arr1, "gbk");System.out.println(str4);}
}

 练习4

public class StringMethodTest1 {
// int length():返回字符串的长度: return value.length
// char charAt(int index): 返回某索引处的字符return value[index]
// boolean isEmpty():判断是否是空字符串:return value.length == 0
// String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
// String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
// String trim():返回字符串的副本,忽略前导空白和尾部空白
// boolean equals(Object obj):比较字符串的内容是否相同
// boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
// String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
// int compareTo(String anotherString):比较两个字符串的大小@Testpublic void test1(){String s1 = "";String s2 = new String();String s3 = new String("");System.out.println(s1.isEmpty()); //trueSystem.out.println(s2.isEmpty()); //trueSystem.out.println(s3.isEmpty()); //true
//        String s4 = null;
//        System.out.println(s4.isEmpty()); //包空指针异常String s5 = "hello";System.out.println(s5.length()); //5}@Testpublic void test2(){String s1 = "hello";String s2 = "hello";System.out.println(s1.equals(s2));System.out.println(s1.equalsIgnoreCase(s2));String s3 = "abcd";String s4 = "adef";System.out.println(s3.compareTo(s4));String s5 = "abcd";String s6 = "aBcd";System.out.println(s5.compareTo(s6));System.out.println(s5.compareToIgnoreCase(s6));String s7 = "张ab";String s8 = "李cd";System.out.println(s7.compareTo(s8));String s9 = " he llo   ";System.out.println("***" + s9.trim() + "****"); //***he llo****}/*** boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列* 时,返回 true* int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引* int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出* 现处的索引,从指定的索引开始* int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引* int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后* 一次出现处的索引,从指定的索引开始反向搜索* 注:indexOf和lastIndexOf方法如果未找到都是返回-1*/@Testpublic void test3(){String s1 = "教育尚硅谷教育";System.out.println(s1.contains("硅谷"));System.out.println(s1.indexOf("教育"));System.out.println(s1.indexOf("教育", 1));System.out.println(s1.lastIndexOf("教育",4));}// String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。// String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。@Testpublic void test4(){String s1 = "教育尚硅谷教育";System.out.println(s1.substring(2));System.out.println(s1.substring(2,5));//[2,5)}/*** 18)char charAt(index):返回[index]位置的字符* (19)char[] tocharArray():将此字符串转换为一个新的字符数组返回* (20)static string valueof(char[] data):返回指定数组中表示该字符序列的 String* (21)static String valueof(char[] data,int offset,int count): 返回指定数组中表示该字符序列的 string* (22)static string copyValue0f(char[] data): 返回指定数组中表示该字符序列的 string* (23)static string copyValue0f(char[] data, int ofset,int count):返回指定数组中表示该字符序列的 string*//*** (24)boolean startswith(xx):测试此字符串是否以指定的前缀开始* (25)boolean startswith(string prefix,int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始* (26)boolean endswith(xx):测试此字符串是否以指定的后缀结束*/@Testpublic void test5(){String s1 = "教育尚硅谷教育";System.out.println(s1.charAt(2));String s2 = String.valueOf(new char[]{'a','b','c'});String s3 = String.copyValueOf(new char[]{'a','b','c'});System.out.println(s2);System.out.println(s3);System.out.println(s2 == s3);System.out.println(s1.startsWith("教育a"));System.out.println(s1.startsWith("教育",5));}/*** (27)String replace(char oldchar, char newchar):返回一个新的字符串,它是通过用 newchar 替换此字符串中出* 现的所有 oldchar 得到的。 不支持正则。* (28)string replace(charSequence target, charSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。* (29)String replaceAll(string regex,string replacement):使用给定的replacement 替换此字符串所有匹配给定的正则表达式的子字符串。* (30)String replaceFirst(String regex,string replacement):使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。*/@Testpublic void test6(){String s1 = "hello";String s2 = s1.replace('l','w');System.out.println(s1); //helloSystem.out.println(s2); //hewwoString s3 = s1.replace("ll","wwww");System.out.println(s3); //hewwwwo}
}

 练习5

/*** ClassName: StringTest* Package: com.atguigu01.string.exer1* Description:* //考查:方法参数的值传递机制、String的不可变性* @Author: lwfstart* @Create 2025-03-29 13:27* @Version: 1.0*/
public class StringTest {String str = "good";char[] ch = {'t','e','s','t'};public void change(String str,char ch[]){str = "test ok";ch[0] = 'b';}public static void main(String[] args) {StringTest ex = new StringTest();ex.change(ex.str,ex.ch);System.out.println(ex.str); // goodSystem.out.println(ex.ch); // best}
}

练习6

 

算法练习:
题目1:模拟一个trim方法,去除字符串两端的空格。
题目2:将一个字符串进行反转。将字符串中指定部分进行反转。
比如"abcdefg"反转为"abfedcg"题目3:获取一个字符串在另一个字符串中出现的次致
比如:获取"ab"在"abkkcadkabkebfkabkskab"中出现的次数题目4:获取两个字符串中最大相同子串。比如:str1 = "abcwerthelloyuiodef";str2 ="cvhellobnm"
提示:将短的那个串进行长度依次递减的子串与较长的串比较。题目5:对字符串中字符进行自然顺序排序。提示:1)字符串变成字符数组。2)对数组排序,选择,冒泡,Arrays.sort();3)将排序后的数组变成字符串

代码:

public class StringTest {/*** 题目2:将一个字符串进行反转。将字符串中指定部分进行反转。* 比如"abcdefg"反转为"abfedcg"*/@Testpublic void test(){String s = "abcdefg";String s1 = reverse(s,2,5);String s2 = reverse(s,2,5);System.out.println(s1);System.out.println(s2);}/*** 方式1:将String转为char[],针对char[]数组进行相应位置的反转,反转以后将char[]转为String*/public String reverse(String str, int fromIndex, int toIndex) {//char[] arr = str.toCharArray();//for (int i = fromIndex,j=toIndex; i < j; i++,j--) {char temp = arr[i];arr[i] = arr[j];arr[j] = temp;}//return new String(arr);}public String reverse2(String str,int fromIndex,int toIndex){//获取str的第1部分String finalStr = str.substring(0,fromIndex); //ab//拼接上第2部分for(int i = toIndex; i >= fromIndex;i--){finalStr += str.charAt(i);} //abfedc//拼接上第3部分finalStr += str.substring(toIndex +1);return finalStr;}/*** 题目3:获取一个字符串在另一个字符串中出现的次致* 比如:获取"ab"在"abkkcadkabkebfkabkskab"中出现的次数*//*** 判断subStr在str中出现的次数* @param str* @param subStr* @return 返回次数*/public int getSubStringCount(String str,String subStr){int count = 0; //记录出现的次数int index = str.indexOf(subStr);while(index >= 0){count++;index = str.indexOf(subStr,index+subStr.length());}return count;}@Testpublic void test2(){String subStr = "ab";String str = "abkkcadkabkebfkabkskab";int count = getSubStringCount(str,subStr);System.out.println(count);}
}

 算法代码:

/** 1.模拟一个trim方法,去除字符串两端的空格。* * 2.将一个字符串进行反转。将字符串中指定部分进行反转。比如将“abcdefg”反转为”abfedcg”* * 3.获取一个字符串在另一个字符串中出现的次数。比如:获取“ab”在 “cdabkkcadkabkebfkabkskab”    中出现的次数4.获取两个字符串中最大相同子串。比如:str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"//10提示:将短的那个串进行长度依次递减的子串与较长  的串比较。5.对字符串中字符进行自然顺序排序。"abcwerthelloyuiodef"
提示:
1)字符串变成字符数组。
2)对数组排序,选择,冒泡,Arrays.sort(str.toCharArray());
3)将排序后的数组变成字符串。*/
public class StringExer {// 第1题public String myTrim(String str) {if (str != null) {int start = 0;// 用于记录从前往后首次索引位置不是空格的位置的索引int end = str.length() - 1;// 用于记录从后往前首次索引位置不是空格的位置的索引while (start < end && str.charAt(start) == ' ') {start++;}while (start < end && str.charAt(end) == ' ') {end--;}if (str.charAt(start) == ' ') {return "";}return str.substring(start, end + 1);}return null;}// 第2题// 方式一:public String reverse1(String str, int start, int end) {// start:2,end:5if (str != null) {// 1.char[] charArray = str.toCharArray();// 2.for (int i = start, j = end; i < j; i++, j--) {char temp = charArray[i];charArray[i] = charArray[j];charArray[j] = temp;}// 3.return new String(charArray);}return null;}// 方式二:public String reverse2(String str, int start, int end) {// 1.String newStr = str.substring(0, start);// ab// 2.for (int i = end; i >= start; i--) {newStr += str.charAt(i);} // abfedc// 3.newStr += str.substring(end + 1);return newStr;}// 方式三:推荐 (相较于方式二做的改进)public String reverse3(String str, int start, int end) {// ArrayList list = new ArrayList(80);// 1.StringBuffer s = new StringBuffer(str.length());// 2.s.append(str.substring(0, start));// ab// 3.for (int i = end; i >= start; i--) {s.append(str.charAt(i));}// 4.s.append(str.substring(end + 1));// 5.return s.toString();}@Testpublic void testReverse() {String str = "abcdefg";String str1 = reverse3(str, 2, 5);System.out.println(str1);// abfedcg}// 第3题// 判断str2在str1中出现的次数public int getCount(String mainStr, String subStr) {if (mainStr.length() >= subStr.length()) {int count = 0;int index = 0;// while((index = mainStr.indexOf(subStr)) != -1){// count++;// mainStr = mainStr.substring(index + subStr.length());// }// 改进:while ((index = mainStr.indexOf(subStr, index)) != -1) {index += subStr.length();count++;}return count;} else {return 0;}}@Testpublic void testGetCount() {String str1 = "cdabkkcadkabkebfkabkskab";String str2 = "ab";int count = getCount(str1, str2);System.out.println(count);}@Testpublic void testMyTrim() {String str = "   a   ";// str = " ";String newStr = myTrim(str);System.out.println("---" + newStr + "---");}// 第4题// 如果只存在一个最大长度的相同子串public String getMaxSameSubString(String str1, String str2) {if (str1 != null && str2 != null) {String maxStr = (str1.length() > str2.length()) ? str1 : str2;String minStr = (str1.length() > str2.length()) ? str2 : str1;int len = minStr.length();for (int i = 0; i < len; i++) {// 0 1 2 3 4 此层循环决定要去几个字符for (int x = 0, y = len - i; y <= len; x++, y++) {if (maxStr.contains(minStr.substring(x, y))) {return minStr.substring(x, y);}}}}return null;}// 如果存在多个长度相同的最大相同子串// 此时先返回String[],后面可以用集合中的ArrayList替换,较方便public String[] getMaxSameSubString1(String str1, String str2) {if (str1 != null && str2 != null) {StringBuffer sBuffer = new StringBuffer();String maxString = (str1.length() > str2.length()) ? str1 : str2;String minString = (str1.length() > str2.length()) ? str2 : str1;int len = minString.length();for (int i = 0; i < len; i++) {for (int x = 0, y = len - i; y <= len; x++, y++) {String subString = minString.substring(x, y);if (maxString.contains(subString)) {sBuffer.append(subString + ",");}}System.out.println(sBuffer);if (sBuffer.length() != 0) {break;}}String[] split = sBuffer.toString().replaceAll(",$", "").split("\\,");return split;}return null;}// 如果存在多个长度相同的最大相同子串:使用ArrayList
//	public List<String> getMaxSameSubString1(String str1, String str2) {
//		if (str1 != null && str2 != null) {
//			List<String> list = new ArrayList<String>();
//			String maxString = (str1.length() > str2.length()) ? str1 : str2;
//			String minString = (str1.length() > str2.length()) ? str2 : str1;
//
//			int len = minString.length();
//			for (int i = 0; i < len; i++) {
//				for (int x = 0, y = len - i; y <= len; x++, y++) {
//					String subString = minString.substring(x, y);
//					if (maxString.contains(subString)) {
//						list.add(subString);
//					}
//				}
//				if (list.size() != 0) {
//					break;
//				}
//			}
//			return list;
//		}
//
//		return null;
//	}@Testpublic void testGetMaxSameSubString() {String str1 = "abcwerthelloyuiodef";String str2 = "cvhellobnmiodef";String[] strs = getMaxSameSubString1(str1, str2);System.out.println(Arrays.toString(strs));}// 第5题@Testpublic void testSort() {String str = "abcwerthelloyuiodef";char[] arr = str.toCharArray();Arrays.sort(arr);String newStr = new String(arr);System.out.println(newStr);}
}

模拟用户登录

案例:模拟用户登录
(1)定义用户类,属性为用户名和密码,提供相关的getter和setter方法,构造器,toString()。(2)使用数组存储多个用户对象。(3)录入用户和密码,对比用户信息,匹配成功登录成功,否则登录失败。> 登录失败时,当用户名错误,提示没有该用户。> 登录失败时,当密码错误时,提示密码有误。效果如图所示:

练习:

UserTest 
public class UserTest {public static void main(String[] args) {//1.创建数组,并初始化几个User对象User[] arr = new User[3];arr[0] = new User("Tom", "8888");arr[1] = new User("songhk", "123");arr[2] = new User("Jerry","6666");System.out.println("库中的用户有:");for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}//2.实例化Scanner,获取输入的用户名和密码Scanner scan = new Scanner(System.in);System.out.println("请输入用户名:");String userName = scan.next();System.out.println("请输入密码:");String password = scan.next();//3.遍历数组元素,匹配用户名和密码boolean isFlag = true;for (int i = 0; i < arr.length; i++) {if(arr[i].getName().equals(userName)) { //存在此用户名isFlag = false;if(arr[i].getPassword().equals(password)) {System.out.println("登录成功" + userName);}else {System.out.println("密码有误");}break;}}if(isFlag) {System.out.println("没有该用户");}scan.close();}
}User
public class User {private String name; //姓名private String password; //密码public User() {}public User(String name, String password) {this.name = name;this.password = password;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return name + "-" + password;}
}

String与基本数据类型转换

String与字节数组转换

StringBuffer

总结:

1.三个类的对比:String、stringBuffer、StringBuilder
> String:不可变的字符序列;底层使用char[](jdk8及之前),底层使用byte[](jdk9及之后)
> StringBuffer:可变的字符序列;JDK1.0声明,线程安全的,效率低;底层使用byte[](jdk9及之后)
> StringBuilder: 可变的字符序列;JDK5.0声明,线程不安全的,效率高;底层使用byte[](jdk9及之后)2.StringBuffer/stringBuilder的可变性分析(源码分析):
回顾:
String s1 = new String();//char[] value = new char[0];
String s2 = new String("abc");// char[] value = new char[]{'a','b','c'};
针对于StringBuilder来说:
内部的属性有:char[] value;//存储字符序列int count;//实际存储的字符的个数StringBuilder sBuffer1 = new StringBuilder();//char[] value = new char[16];
StringBuilder sBuffer1 = new stringBuilder("abc"): //char[] value = new char[16 + "abc".length()];
sBuffer1.append("ac");//value[0]='a';value[1]='c';
sBuffer1.append("b");//value[2]='b';
...不断的添加,一旦count要超过value.length时,就需要扩容:默认扩容为原有容量的2倍+2。
并将原有value数组中的元素复制到新的数组中,
3.源码启示:
> 如果开发中需要频繁的针对于字符串进行增、删、改等操作,建议使用stringBuffer或stringBuilder替换String.
因为使用string效率低。
> 如果开发中,不涉及到线程安全问题,建议使用StringBuilder替换StringBuffer
> 如果开发中大体确定要操作的字符的个数,建议使用带int capacity参数的构造器。因为可以避免底层多次扩容操作,性能更高
4.StringBuffer和StringBuilder中的常用方法5.对比三者的执行效率
效率从高到低排列:
StringBuilder > StringBuffer > String

代码:

public class StringBufferBuilderTest {/*** *(1)StringBuffer append(xx):提供了很多的append()方法,用于进行字符串追加的方式拼接* (2)StringBuffer delete(int start, int end): 删除[start,end)之间字符* (3)StringBuffer deleteCharAt(int index):删除[index]位置字符* (4)StringBuffer replace(int start, int end,string str):替换[start,end)范围的字符序列为str* (5)void setCharAt(int index,char c):替换[index]位置字符* (6)char charAt(int index):查找指定index位置上的字符* (7)StringBuffer insert(int index,xx):在[index]位置插入xx* (8)int length():返回存储的字符数据的长度* (9)StringBuffer reverse():反转*/@Testpublic void test1(){StringBuilder sBuilder = new StringBuilder();sBuilder.append("abc").append("123").append("def"); //方法链的调用System.out.println(sBuilder); //abc123def}@Testpublic void test2(){StringBuilder sBuilder = new StringBuilder("hello");sBuilder.insert(2,1);sBuilder.insert(2, "abc");System.out.println(sBuilder);StringBuilder sBuilder1 = sBuilder.reverse();System.out.println(sBuilder1);System.out.println(sBuilder == sBuilder1); //trueSystem.out.println(sBuilder.length()); //实际存储的字符的个数}@Testpublic void test3(){StringBuilder sBuilder = new StringBuilder("hello");sBuilder.setLength(2);System.out.println(sBuilder);sBuilder.append("c");System.out.println(sBuilder);sBuilder.setLength(10);System.out.println(sBuilder);System.out.println(sBuilder.charAt(6)==0); //true}/*** 测试String、StringBuffer、StringBuilder在操作数据方面的效率**/@Testpublic void test4(){//初始设置long startTime = 0L;long endTime = 0L;String text = "";StringBuffer buffer = new StringBuffer("");StringBuilder builder = new StringBuilder("");//开始对比startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {buffer.append(String.valueOf(i));}endTime = System.currentTimeMillis();System.out.println("StringBuffer的执行时间:" + (endTime - startTime));startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {builder.append(String.valueOf(i));}endTime = System.currentTimeMillis();System.out.println("StringBuilder的执行时间:" + (endTime - startTime));startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {text = text + i;}endTime = System.currentTimeMillis();System.out.println("String的执行时间:" + (endTime - startTime));}
}

面试题:

public class InterviewTest1 {public static void main(String[] args) {StringBuffer a = new StringBuffer("A");StringBuffer b = new StringBuffer("B");operate(a,b);System.out.println(a + "," + b); //ABx,B}//引用类型传递地址public static void operate(StringBuffer x, StringBuffer y) {x.append(y);y = x; //y指向的是地址,这个地址指向的是堆空间实际的对象,所以最后这个对象更改成了ABxy.append('x');} //a的地址给了x,x的地址给了y,y也指向了a所指向的地址,所以y的地址改变了,a的内容页同样会改变
}2
public class InterviewTest2 {public static void stringReplace(String text){//这个地方改变的是形参text = text.replace('j','i');}public static void bufferReplace(StringBuffer text){text.append("C");text = new StringBuffer("Hello"); //这个地方重新赋值了一个地址,所以后面的改变跟传递过来的那个地址没有关系了text.append("World!");}public static void main(String[] args) {String textString = new String("java");StringBuffer textBuffer = new StringBuffer("java");stringReplace(textString); //java  传递过去的是一个地址,但是体现了String的不可变性bufferReplace(textBuffer); //javaCSystem.out.println(textString + textBuffer); //javajavaC}
}3
public class InterviewTest3 {public static void change(String s,StringBuffer sb){s = "aaaa";sb.setLength(0);sb.append("aaaa");}public static void main(String[] args) {String s = "bbbb";StringBuffer sb = new StringBuffer("bbbb");change(s,sb);System.out.println(s+sb); //bbbbaaaa}
}4
public class InterviewTest4 {public static void main(String[] args) {String str = null;StringBuffer sb = new StringBuffer();sb.append(str);System.out.println(sb.length()); //0 4 16System.out.println(sb); //"null"StringBuffer sb1 = new StringBuffer(str);System.out.println(sb1);//"" "null" null  NullPointerException 空指针异常}
}

JDK8之前日期时间API

相关代码: 

public class DateTimeTest {/*** Date类的使用* |--java.util.Date*  >两个构造器的使用*  >两个方法的使用 ① tostring()   ② getTime()*      |----java.sql.Date:对应着数据库中的date类型*/@Testpublic void test1(){Date date1 = new Date(); //创建一个基于当前系统时间的Date的实例System.out.println(date1.toString());long milliTime = date1.getTime();System.out.println("对应的毫秒数为:" + milliTime); //1743247093560Date date2 = new Date(1743247093560L); //创建一个基于指定时间戳的Date的实例System.out.println(date2.toString());}@Testpublic void test2(){java.sql.Date date1 = new java.sql.Date(1743247093560L);System.out.println(date1.toString()); //2025-03-29System.out.println(date1.getTime()); //1743247093560}/*** SimpleDateFormat类:用于日期时间的格式化和解析* 格式化:日期 ---> 字符串* 解析:字符串 ---> 日期*/@Testpublic void test3() throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat();//格式化:日期 ---> 字符串Date date1 = new Date();String strDate = sdf.format(date1);System.out.println(strDate); //25-3-29 下午8:08//解析:字符串 ---> 日期Date date2 = sdf.parse("25-3-29 下午5:08");System.out.println(date2); //Sat Mar 29 17:08:00 CST 2025}@Testpublic void test4() throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//格式化:日期 ---> 字符串Date date1 = new Date();String strDate = sdf.format(date1);System.out.println(strDate); //星期六, 29 三月 2025 20:19:39 +0800 ---> 2025-03-29 20:22:39//解析:字符串 ---> 日期Date date2 = sdf.parse("2025-03-29 20:22:39");System.out.println(date2); //Sat Mar 29 20:22:39 CST 2025
//        解析失败,因为参数的字符串不满足SimpleDateFormat可以识别的格式  DateFormat
//        sdf.parse("2025-03-29 下午2:39");
//        System.out.println(date2);}/*** Calender:日历类* ① 实例化 由于Calendar是一个抽象类,所以我们需要创建其子类的实例,这里我们通过Calendar的静态方法*      getInstance()即可获取* ② 常用方法:get(int field) / set(int field, xx) / add(int field, xx) / getTime() / setTime()*/@Testpublic void test5(){Calendar calendar = Calendar.getInstance();
//        System.out.println(calendar.getClass());//测试方法System.out.println(calendar.get(Calendar.DAY_OF_MONTH));System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
//        set(int field, xx)calendar.set(Calendar.DAY_OF_MONTH, 23);System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//add(int field, xx)calendar.add(Calendar.DAY_OF_MONTH, 3);calendar.add(Calendar.DAY_OF_MONTH, -5);System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//getTime():Calendar --> DateDate date = calendar.getTime();System.out.println(date);//setTime():使用指定Date重置CalendarDate date1 = new Date();calendar.setTime(date1);System.out.println(calendar.get(Calendar.DAY_OF_MONTH));}
}

JDK8中新日期时间API

LocalDateLocalTimeLocalDateTime

瞬时:Instant

格式化与解析日期或时间 

 其它API

 总结:

一、JDK8之前的API:
1.System类的currentTimeMillis()
> 获取当前时间对应的毫秒数,Long类型,时间戳
> 当前时间与1970年1月1日0时0分0秒之间的毫秒数
> 常用来计算时间差2.两个Date类|--java.util.Date>两个构造器的使用>两个方法的使用 ① tostring()   ② getTime()|----java.sql.Date:对应着数据库中的date类型
3.SimpleDateFormat类
SimpleDateFormat类:用于日期时间的格式化和解析格式化:日期 ---> 字符串解析:字符串 ---> 日期4.Calendar类(日历类):抽象类
Calender:日历类① 实例化 由于Calendar是一个抽象类,所以我们需要创建其子类的实例,这里我们通过Calendar的静态方法getInstance()即可获取② 常用方法:get(int field) / set(int field, xx) / add(int field, xx) / getTime() / setTime()二、JDK8中的API:
1.LocalDate,LocalTime,LocalDateTime ---> 类似于Calendar
> 实例化:now() / of(xxx,xx,xx)
> 方法:get() / withXxx() / plusXxx() / minusXxx()’2. Instant:瞬时 --->类似于Date
> 实例化:now() / ofEpochMilLi()
> 方法:toEpochMilli()3. DateTimeFormatter --> 类似于SimpleDateFormat
用于格式化和解析LocalDate,LocalTime,LocalDateTime

代码:

练习:
如何将一个java.util.Date的实例转换为java.sql.Date的实例拓展:
将控制台获取的年月日(比如:2022-12-13)的字符串数据,保存在数据库中。
(简化为得到java.sql.Date的对象,此对象对应的时间为2022-12-13)。
public class Exer01 {/*** 练习:* 如何将一个java.util.Date的实例转换为java.sql.Date的实例*/@Testpublic void test1(){Date date1 = new Date();//错误的:
//        java.sql.Date date2 = (java.sql.Date) date1;
//        System.out.println(date2);//正确的:java.sql.Date date2 = new java.sql.Date(date1.getTime());System.out.println(date2);}/*** 拓展:* 将控制台获取的年月日(比如:2022-12-13)的字符串数据,保存在数据库中。* (简化为得到java.sql.Date的对象,此对象对应的时间为2022-12-13)。** 字符串 ---> java.util.Date ---> java.sql.Date*/@Testpublic void test2() throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String pattern = "2022-12-13";//得到java.util.DateDate date1 = sdf.parse(pattern);//转换为java.sql.Datejava.sql.Date date2 = new java.sql.Date(date1.getTime());System.out.println(date2); //2022-12-13}
}

 代码2:

案例:百天推算
使用Calendar获取当前时间,把这个时间设置为你的生日,再获取你的百天(出生后100天)日期。
使用LocalDateTime获取当前时间,把这个时间设置为你的生日,再获取你的百天(出生后100天)日期。
public class Exer02 {/*** 使用Calendar获取当前时间,把这个时间设置为你的生日,再获取你的百天(出生后100天)日期。*/@Testpublic void test1(){Calendar calendar = Calendar.getInstance();Date date = calendar.getTime();System.out.println("你的生日为:" + date);calendar.add(Calendar.DAY_OF_YEAR,100);Date newDate = calendar.getTime();System.out.println("100天以后是:" + newDate);}/*** 使用LocalDateTime获取当前时间,把这个时间设置为你的生日,再获取你的百天(出生后100天)日期。*/@Testpublic void test2(){LocalDateTime  localDateTime = LocalDateTime.now();System.out.println("你的生日为:" + localDateTime);LocalDateTime localDateTime1 = localDateTime.plusDays(100);System.out.println("100天以后是" + localDateTime1);}
}

代码3:

 

public class DateTimeTest {/*** 可变性:像日期和时间这样的类应该是不可变的。* 偏移性:Date中的年份是从1900开始的,而月份都从0开始。* 格式化:格式化只对Date有用,Calendar则不行。* 此外,它们也不是线程安全的;不能处理闰秒等。*/@Testpublic void test1(){String s1 = "hello";String s2 = s1.replace('l','w'); //String的不可变性System.out.println(s2);//体会Calendar的可变性Calendar calendar = Calendar.getInstance();calendar.set(Calendar.DAY_OF_MONTH,23);System.out.println(calendar.get(Calendar.DAY_OF_MONTH));}@Testpublic void test2(){// 偏移性:Date中的年份是从1900开始的,而月份都从0开始。Date date = new Date(2022,11,14);System.out.println(date);}/*** JDK8的api:LocalDate \ LocalTime \ LocalDateTime*/@Testpublic void test3(){//now():获取当前日期和时间对应的实例LocalDate localDate = LocalDate.now();LocalTime localTime = LocalTime.now();LocalDateTime localDateTime = LocalDateTime.now();System.out.println(localDate); //2025-03-29System.out.println(localTime); //21:56:26.981System.out.println(localDateTime); //2025-03-29T21:56:26.981//of():获取指定的日期、时间对应的实例LocalDate localDate1 = LocalDate.of(2021, 5, 23);LocalDateTime localDateTime1 = LocalDateTime.of(2022,12,5,11,23,45);System.out.println(localDate1);System.out.println(localDateTime1);//getXXX()LocalDateTime localDateTime2 = LocalDateTime.now();System.out.println(localDateTime2.getDayOfMonth());//体现不可变性
//        withXxx()LocalDateTime localDateTime3 = localDateTime2.withDayOfMonth(15);System.out.println(localDateTime2); //2025-03-29T22:05:16.169System.out.println(localDateTime3); //2025-03-15T22:05:16.169LocalDateTime localDateTime4 = localDateTime2.plusDays(5);System.out.println(localDateTime2); //2025-03-29T22:05:16.169System.out.println(localDateTime4); //2025-04-03T22:08:00.499}/*** JDK8的api:Instant*/@Testpublic void test4(){//now():Instant instant = Instant.now();System.out.println(instant); //2025-03-29T14:15:09.671Z//了解:OffsetDateTime instance1 = instant.atOffset(ZoneOffset.ofHours(8));System.out.println(instance1); //2025-03-29T22:17:40.782+08:00Instant instance2 = Instant.ofEpochMilli(24123123312L);System.out.println(instance2); //1970-10-07T04:52:03.312Zlong milliTime = instant.toEpochMilli();System.out.println(milliTime); //1743258123429System.out.println(new Date().getTime()); //1743258123470}/*** JDK8的api: DateTimeFormatter*/@Testpublic void test5(){//自定义格式:如:ofPattern("yyyy-MM-dd hh:mm:ss")DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd hh:mm:ss");//格式化:日期、时间-->字符串LocalDateTime localDateTime = LocalDateTime.now();String strDateTime = dateTimeFormatter.format(localDateTime);System.out.println(strDateTime); //2025/03/29 10:39:16//解析:字符串 ---> 日期、时间TemporalAccessor temporalAccessor = dateTimeFormatter.parse("2025/03/29 10:39:16");
//        LocalDateTime.from(temporalAccessor);
//        LocalDateTime localDateTime1 = LocalDateTime.from(temporalAccessor);
//        System.out.println(localDateTime1); //}
}

Java比较器

 总结:

1.实现对象的排序,可以考虑两种方法: 自然排序、定制排序
2.方式一:实现Comparable接口的方式
实现步骤:
① 具体的类A实现Comparable接口
② 重写Comparable接口中的compareTo(0bject obj)方法,在此方法中指明比较类A的对象的大小的标准
③ 创建类A的多个实例,进行大小的比较或排序。3.方式二:
实现步骤:
① 创建一个实现了Comparator接口的实现类A
② 实现类A要求重写Comparator接口中的抽象方法compare(0bject o1,0bject o2),在此方法中指明要比较大小的对象的大小关系。(比如,string类、Product类)
③ 创建此实现类A的对象,并将此对象传入到相关方法的参数位置即可。(比如:Arrays.sort(.,类A的实例))4.对比两种方式:
角度一:自然排序:单一的,唯一的定制排序:灵活的,多样的
角度二:自然排序:一劳永逸的定制排序:临时的
角度三:细节自然排序:对应的接口是Comparable,对应的抽象方法compareTo(Object obj)定制排序:对应的接口是Comparator,对应的抽象方法compare(Object obj1,Object obj2)

相关代码:

Product 
public class Product implements Comparable{ //商品类private String name; //商品名称private double price; //价格public Product() {}public Product(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", price=" + price +'}';}/*** 当前的类需要实现Comparable中的抽象方法:compareTo(Object o)* 在此方法中,指明如何判断当前类的对象的大小,比如:按照价格的高低进行大小的比较(或从低到高排序)** 如果返回值是正数,当前对象大* 如果返回值是负数,当前对象小* 如果返回值是0,一样大*/
//    @Override
//    public int compareTo(Object o){
//         if(o == this){
//             return 0;
//         }
//         if(o instanceof Product){
//             Product p = (Product)o;
//             return Double.compare(this.price,p.price);
//         }
//         //手动抛出一个异常类的对象
//        throw new RuntimeException("类型不匹配");
//    }//比较的标准:先比较价格,进行名字的比较,(从小到大)@Overridepublic int compareTo(Object o){if(o == this){return 0;}if(o instanceof Product){Product p = (Product)o;int value = Double.compare(this.price, p.price);if(value != 0){return -value;}return -this.name.compareTo(p.name);}//手动抛出一个异常类的对象throw new RuntimeException("类型不匹配");}
}

 

ComparableTest 
public class ComparableTest {@Testpublic void test1(){/*** Jack* Jerry* Lucy* Rose* Tom* Tony*/String[] arr = new String[]{"Tom","Jerry","Tony","Rose","Jack","Lucy"};Arrays.sort(arr);//排序后,遍历for(int i = 0; i < arr.length; i++){System.out.println(arr[i]);}}@Testpublic void test2(){Product[] arr = new Product[5];arr[0] = new Product("HuaweiMate50Pro", 6299);arr[1] = new Product("Xiaomi13pro", 4999);arr[2] = new Product("VivoX90pro", 5999);arr[3] = new Product("Iphone14ProMax", 9999);arr[4] = new Product("HonorMagic4", 6299);Arrays.sort(arr);for(int i = 0; i < arr.length; i++){System.out.println(arr[i]);}}@Testpublic void test3(){Product p1 = new Product("HuaweiMate50Pro", 6999);Product p2 = new Product("VivoX90pro", 5999);int compare =  p1.compareTo(p2);if(compare > 0) {System.out.println("p1大");}else if(compare < 0){System.out.println("p2大");}else{System.out.println("p1hep2一样大");}}
}

 

public class ComparatorTest {@Testpublic void test1(){Product[] arr = new Product[5];arr[0] = new Product("HuaweiMate50Pro", 6299);arr[1] = new Product("Xiaomi13pro", 4999);arr[2] = new Product("VivoX90pro", 5999);arr[3] = new Product("Iphone14ProMax", 9999);arr[4] = new Product("HonorMagic4", 6299);//创建一个实现了Comparator接口的实现类的对象Comparator comparator = new Comparator(){//如何判断两个对象o1,o2的大小,其标准就是此方法的方法体要编写的逻辑//按照价格从高到低排序@Overridepublic int compare(Object o1, Object o2) {if(o1 instanceof Product && o2 instanceof Product){Product p1 = (Product)o1;Product p2 = (Product)o2;return -Double.compare(p1.getPrice(),p2.getPrice());}throw new RuntimeException("类型不匹配");}};Comparator comparator1 = new Comparator(){//如何判断两个对象o1,o2的大小,其标准就是此方法的方法体要编写的逻辑//比如:按照name从低到高排序@Overridepublic int compare(Object o1, Object o2) {if(o1 instanceof Product && o2 instanceof Product){Product p1 = (Product)o1;Product p2 = (Product)o2;return p1.getName().compareTo(p2.getName());}throw new RuntimeException("类型不匹配");}};Arrays.sort(arr,comparator1);for(int i = 0; i < arr.length; i++){System.out.println(arr[i]);}}@Testpublic void test2(){String[] arr = new String[]{"Tom","Jerry","Tony","Rose","Jack","Lucy"};Arrays.sort(arr,new Comparator(){@Overridepublic int compare(Object o1, Object o2) {if(o1 instanceof String && o2 instanceof String){String s1 = (String)o1;String s2 = (String)o2;return -s1.compareTo(s2);}throw new RuntimeException("类型不匹配");}});//排序后,遍历for(int i = 0; i < arr.length; i++){System.out.println(arr[i]);}}
}

System

Math

BigInteger

BigDecimal

总结:

1.System类
> 属性:out、in、err
> 方法:currentTimeMillis() / gc() / exit(int status) / getProperty(String property)2. Runtime类
> 对应着Java进程的内存使用的运行时环境,是单例的3.Math类
> 凡是与数学运算相关的操作,大家可以在此类中找相关的方法即可4.BigInteger类和BigDecimal类BigInteger:可以表示任意长度的整数BigDecimal:可以表示任意精度的浮点数5. Random类
> 获取指定范围的随机整数:nextInt(int bound)

相关代码:

public class OtherAPITest {@Testpublic void test1(){String javaVersion = System.getProperty("java.version");System.out.println("java的version:" + javaVersion);String javaHome = System.getProperty("java.home");System.out.println("java的home:" + javaHome);String osName = System.getProperty("os.name");System.out.println("os的name:" + osName);String osVersion = System.getProperty("os.version");System.out.println("os的version:" + osVersion);String userName = System.getProperty("user.name");System.out.println("user的name:" + userName);String userHome = System.getProperty("user.home");System.out.println("user的home:" + userHome);String userDir = System.getProperty("user.dir");System.out.println("user的dir:" + userDir);}@Testpublic void test2(){Runtime runtime = Runtime.getRuntime();long initialMemory = runtime.totalMemory();//获取虚拟机初始化时堆内存总量long maxMemory = runtime.maxMemory();//获取虚拟机最大堆内存总量String str ="";//模拟占用内存for(int i=0;i<10000;i++){str += 1;}long freeMemory = runtime.freeMemory();//获取空闲堆内存总量System.out.println("总内存:" + initialMemory / 1024 / 1024 * 64 +"MB");System.out.println("总内存:"+ maxMemory / 1024 / 1024 * 4 + "MB");System.out.println("空闲内存:"+freeMemory /1024 / 1024 +"MB");System.out.println("已用内存:"+(initialMemory-freeMemory)/ 1024 / 1024 + "MB");}@Testpublic void test3(){//四舍五入,往大了的方向靠//技巧:floor(x + 0.5)System.out.println(Math.round(12.3)); //12System.out.println(Math.round(12.5)); //13System.out.println(Math.round(-12.3)); //-12System.out.println(Math.round(-12.6)); //-13System.out.println(Math.round(-12.5)); //-12}@Testpublic void test4(){
//        long bigNum = 123456789123456789123456789L;BigInteger b1 = new BigInteger( "12345678912345678912345678");BigInteger b2 = new BigInteger( "78923456789123456789123456789");//System.out.println("和:"+(b1+b2));//错误的,无法直接使用+进行求和System.out.println("和:"+ b1.add(b2));System.out.println("减:"+ b1.subtract(b2));System.out.println("乘:"+ b1.multiply(b2));System.out.println("除:"+ b2.divide(b1));System.out.println("余:"+ b2.remainder(b1));}@Testpublic void test5(){BigInteger bi =new BigInteger( "12433241123");BigDecimal bd =new BigDecimal( "12435.351");BigDecimal bd2 = new BigDecimal( "11");System.out.println(bi);
//        System.out.println(bd.divide(bd2));System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));System.out.println(bd.divide(bd2, 15,BigDecimal.ROUND_HALF_UP));}@Testpublic void test6(){Random random = new Random();int i = random.nextInt();System.out.println(i);int j = random.nextInt(10); //随机获取[0,10)范围的整数System.out.println(j);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/73960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day 09

文章目录 指针数组指针和函数技术名词解释技术细节课堂笔记 指针数组 #include<stdio.h> int main() {int a[3] {0,1,2};//指针数组&#xff0c;它是数组&#xff0c;每个元素都是指针int *p[3];p[0] &a[0];p[0] a;p[1] &a[1];p[1] a1;p[2] &a[2];p[…

Nginx — Nginx安装证书模块(配置HTTPS和TCPS)

一、安装和编译证书模块 [rootmaster nginx]# wget https://nginx.org/download/nginx-1.25.3.tar.gz [rootmaster nginx]# tar -zxvf nginx-1.25.3.tar.gz [rootmaster nginx]# cd nginx-1.25.3 [rootmaster nginx]# ./configure --prefix/usr/local/nginx --with-http_stub_…

计算机网络 用deepseek帮助整理的复习资料(一)

### 计算机网络基础知识整理 --- #### **一、网络类型** 1. **局域网 (LAN)** - **定义**&#xff1a;覆盖小范围&#xff08;如家庭、教室、公司&#xff09;。 - **特点**&#xff1a;高带宽、低延迟&#xff0c;设备通过交换机互联。 - **示例**&#xff1…

Linux SCP传输文件免密配置

文章目录 Linux SCP传输文件免密配置生成SSH密钥对将公钥复制到远程服务器测试SSH连接使用SCP免密传输文件可选配置带密码的秘钥连接处理使用 ssh-agent进行缓存管理&#xff08;该方式只能确保同一个回话中&#xff0c;多次传输只输一次密码&#xff09;使用 keychain&#xf…

数字电子技术基础(三十六)——利用Multisim软件实现3线-8线译码器

目录 1 手动方式实现3线-8线译码器 2 使用字选择器实现3线-8线译码器 现在尝试利用Multisim软件来实现3线-8线译码器。本实验目的是验证74LS138的基本功能&#xff0c;简单来说就是“N中选1”。 实验设计&#xff1a; &#xff08;1&#xff09;使能信号&#xff1a;时&am…

wait和notify : 避免线程饿死(以及votile内存可见性和指令重排序问题)

各位看官&#xff0c;大家早安午安晚安呀~~~ 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习&#xff1a;wait和notify : 避免线程饿死&#xff08;以及votile内存可见性和指令重排序问题&#xff09; …

HarmonyOS 介绍

HarmonyOS简介 随着万物互联时代的开启&#xff0c;应用的设备底座将从几十亿手机扩展到数百亿IoT设备。全新的全场景设备体验&#xff0c;正深入改变消费者的使用习惯。 同时应用开发者也面临设备底座从手机单设备到全场景多设备的转变&#xff0c;全场景多设备的全新底座&am…

【视觉提示学习】3.28阅读随想

2109.01134 CoOp通过可学习的向量来建模提示的上下文词汇&#xff0c;这些向量可以用随机值或预训练的词嵌入进行初始化&#xff08;见图2&#xff09;。我们提供了两种实现方式&#xff0c;以处理不同性质的任务&#xff1a;一种是基于统一上下文&#xff08;unified context…

计算机求职面试中高频出现的经典题目分类整理

以下为计算机求职面试中高频出现的经典题目分类整理&#xff0c;涵盖技术核心与深度考察方向&#xff0c;答案要点已附解析思路&#xff1a; 一、数据结构与算法 链表操作 题目&#xff1a;反转链表&#xff08;迭代/递归实现&#xff09;考察点&#xff1a;指针操作、递归思维…

uniapp选择文件使用formData格式提交数据

1. Vue实现 在vue项目中,我们有个文件,和一些其他字段数据需要提交的时候,我们都是使用axios 设置请求头中的Content-Type: multipart/form-data,然后new FormData的方式来进行提交。方式如下: const sendRequest = () => {const formData = new FormData()formData…

BeanDefinition和Beanfactory实现一个简单的bean容器

目录 什么是 Springbean 容器 设计思路 图解 参考文章 开源地址 BeanDefinition 类 BeanFactory 类 测试类 什么是 Springbean 容器 Spring 包含并管理应用对象的配置和生命周期&#xff0c;在这个意义上它是一种用于承载对象的容器&#xff0c;你可以配置你的每个 Bea…

AI Agent开发大全第十四课-零售智能导购智能体的RAG开发理论部分

开篇 经过前面的一些课程,我们手上已经积累了各种LLM的API调用、向量库的建立和使用、embedding算法的意义和基本使用。 这已经为我们具备了开发一个基本的问答类RAG的开发必需要素了。下面我们会来讲一个基本问答类场景的RAG,零售中的“智能导购”场景。 智能导购 大家先…

向字符串添加空格

给你一个下标从 0 开始的字符串 s &#xff0c;以及一个下标从 0 开始的整数数组 spaces 。 数组 spaces 描述原字符串中需要添加空格的下标。每个空格都应该插入到给定索引处的字符值 之前 。 例如&#xff0c;s "EnjoyYourCoffee" 且 spaces [5, 9] &#xff0…

百人会上的蔚小理与「来的刚刚好」的雷军

这就是2025百人会上的蔚小理&#xff0c;努力的李斌、宣扬飞行汽车的何小鹏与大讲开源的李想。那么小米汽车的模式是什么呢&#xff1f;站在蔚小理的肩上。 这就是2025百人会上的蔚小理&#xff0c;努力的李斌、宣扬飞行汽车的何小鹏与大讲开源的李想。那么小米汽车的模式是什么…

解锁Nginx路由器匹配规则

引言 Nginx 无疑是一款备受瞩目的明星产品。它以其高性能、高可靠性以及出色的并发处理能力&#xff0c;在众多 Web 服务器和反向代理服务器中脱颖而出 &#xff0c;广泛应用于各类网站和应用程序中。据统计&#xff0c;超过 30% 的网站都在使用 Nginx 作为其 Web 服务器&…

传统策略梯度方法的弊端与PPO的改进:稳定性与样本效率的提升

为什么传统策略梯度方法&#xff08;如REINFORCE算法&#xff09;在训练过程中存在不稳定性和样本效率低下的问题 1. 传统策略梯度方法的基本公式 传统策略梯度方法的目标是最大化累积奖励的期望值。具体来说&#xff0c;优化目标可以表示为&#xff1a; max ⁡ θ J ( θ )…

Qwt入门

Qwt(Qt Widgets for Technical Applications)是一个用于科学、工程和技术应用的 Qt 控件库,提供曲线图、仪表盘、刻度尺等专业可视化组件。 1. 安装与配置 1.1 安装方式 源码编译(推荐): git clone https://github.com/qwt/qwt.git cd qwt qmake qwt.pro # 生成 Makef…

软考《信息系统运行管理员》- 6.1 信息系统安全概述

信息系统安全的概念 信息系统安全是指保障计算机及其相关设备、设施(含网络)的安全&#xff0c;运行环境的安全&#xff0c; 信息的安全&#xff0c;实现信息系统的正常运行。 信息系统安全包括实体安全、运行安全、信息安全和 人员安全等几个部分。 影响信息系统安全的因素…

Canvas实现旋转太极八卦图

Canvas实现旋转太极八卦图 项目简介 这是一个使用HTML5 Canvas技术实现的动态太极八卦图&#xff0c;包含了旋转动画和鼠标交互功能。项目展示了中国传统文化元素与现代Web技术的结合。 主要特点 动态旋转的太极图八卦符号的完整展示鼠标悬停暂停动画流畅的动画效果 技术实…

机器学习、深度学习和神经网络

机器学习、深度学习和神经网络 术语及相关概念 在深入了解人工智能&#xff08;AI&#xff09;的工作原理以及它的各种应用之前&#xff0c;让我们先区分一下与AI密切相关的一些术语和概念&#xff1a;人工智能、机器学习、深度学习和神经网络。这些术语有时会被交替使用&#…