1. String类
-
String的声明:final修饰、实现了Comparable接口
-
String的不可变性
-
String的两种定义方式:① 字面量的定义方式 String s = "hello" ② new 的方式:String s = new String("hello");
-
String s = new String("hello");在内存中创建的对象的个数。
-
String的内存解析:字符串常量池、堆内存的使用
-
-
String的连接操作:+
-
常量 + 常量 、变量 + 常量 、变量+变量、concat(String otherString)
-
String intern()
-
-
熟悉String的构造器、与其他结构之间的转换、常用方法
-
编码和解码
-
编码:字符、字符串 --> 字节、字节数组。对应着编码集
-
解码:字节、字节数组 --> 字符、字符串。对应着解码集
-
规则:解码集必须使用当初编码时使用的编码集。只要不一致,就可能出现乱码!
-
-
-
String相关的算法问题。
-
题目1:模拟一个trim方法,去除字符串两端的空格。
-
题目2:将一个字符串进行反转。将字符串中指定部分进行反转。 比如"abcdefg"反转为"abfedcg"
-
题目3:获取一个字符串在另一个字符串中出现的次数。 比如:获取"ab"在 "abkkcadkabkebfkabkskab" 中出现的次数
-
题目4:获取两个字符串中最大相同子串。比如: str1 = "abcwerthelloyuiodef"; str2 = "cvhellobnm" 提示:将短的那个串进行长度依次递减的子串与较长的串比较。
-
题目5:对字符串中字符进行自然顺序排序。
-
提示: 1)字符串变成字符数组。 2)对数组排序,选择,冒泡,Arrays.sort(); 3)将排序后的数组变成字符串。
-
public class StringAnswers { //题目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; } @Test public void testMyTrim() { String str = " a "; // str = " "; String newStr = myTrim(str); System.out.println("---" + newStr + "---"); } //题目2: // 方式一: public String reverse1(String str, int start, int end) {// start:2,end:5 if (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. StringBuilder s = new StringBuilder(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(); } @Test public 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; } } @Test public void testGetCount() { String str1 = "cdabkkcadkabkebfkabkskab"; String str2 = "ab"; int count = getCount(str1, str2); System.out.println(count); } //题目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; } @Test public void testGetMaxSameSubString() { String str1 = "abcwerthelloyuiodef"; String str2 = "cvhellobnmiodef"; String[] strs = getMaxSameSubString1(str1, str2); System.out.println(Arrays.toString(strs)); } //题目5 @Test public void testSort() { String str = "abcwerthelloyuiodef"; char[] arr = str.toCharArray(); Arrays.sort(arr); String newStr = new String(arr); System.out.println(newStr); } }
StringTest { /* * 题目2:将一个字符串进行反转。将字符串中指定部分进行反转。 比如"abcdefg"反转为"abfedcg" * */ @Test public void test(){ String s = "abcdefg"; String s1 = reverse(s,2,5); String s2 = reverse1(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); } /* * 第2种方式 * */ public String reverse1(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;//记录出现的次数 if(str.length() >= subStr.length()){ int index = str.indexOf(subStr); while(index >= 0){ count++; index = str.indexOf(subStr,index + subStr.length()); } } return count; } @Test public void test2(){ String subStr = "ab"; String str = "abkkcadkabkebfkabkskab"; int count = getSubStringCount(str,subStr); System.out.println(count); } }
2. StringBuffer、StringBuilder类
[面试题]String、StringBuffer、StringBuilder的区别
知道什么场景下使用StringBuffer、StringBuilder
3. jdk8之前的日期、时间API
-
System的currentTimeMillis()
-
两个Date的使用
-
|--java.util.Date > 两个构造器的使用 > 两个方法的使用:①toString() ② long getTime() |----java.sql.Date: 对应着数据库中的date类型
-
SimpleDateFormat用于格式化、解析
-
Calendar日历类的使用
-
Calendar:日历类 ① 实例化 由于Calendar是一个抽象类,所以我们需要创建其子类的实例。这里我们通过Calendar的静态方法 getInstance()即可获取 ②常用方法:get(int field) / set(int field,xx) / add(int field,xx) / getTime() / setTime()
4. jdk8中新的日期、时间API
-
LocalDate、LocalTime、LocalDateTime -->类似于Calendar
-
Instant -->类似于Date
-
DateTimeFormatter --->类似于SimpleDateFormat
public class DateTimeTest {
/*
* - 可变性:像日期和时间这样的类应该是不可变的。
- 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
- 格式化:格式化只对Date有用,Calendar则不行。
- 此外,它们也不是线程安全的;不能处理闰秒等。
*
* */
@Test
public void test1(){
String s1 = "hello";
String s2 = s1.replace('l', 'w'); //String的不可变性
System.out.println(s1);//hello
//体会Calendar的可变性
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH,23);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
}
@Test
public void test2(){
//偏移性:Date中的年份是从1900开始的,而月份都从0开始。
Date date = new Date(2022,11,14);
System.out.println(date);
}
/*
* JDK8的api:LocalDate \ LocalTime \ LocalDateTime
* */
@Test
public void test3(){
//now():获取当前日期和时间对应的实例
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);//2022-12-05
System.out.println(localTime);//15:43:51.474
System.out.println(localDateTime); //2022-12-05T15:43:51.475
//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);//2022-12-05T15:48:48.399
System.out.println(localDateTime3);//2022-12-15T15:48:48.399
//plusXxx()
LocalDateTime localDateTime4 = localDateTime2.plusDays(5);
System.out.println(localDateTime2);//2022-12-05T15:50:21.864
System.out.println(localDateTime4);//2022-12-10T15:50:21.864
}
/*
* JDK8的api: Instant
* */
@Test
public void test4(){
//now():
Instant instant = Instant.now();
System.out.println(instant);//2022-12-05T07:56:27.327Z
//了解:
OffsetDateTime instant1 = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println(instant1);
Instant instant2 = Instant.ofEpochMilli(24123123312L);
System.out.println(instant2); //1970-10-07T04:52:03.312Z
long milliTime = instant.toEpochMilli();
System.out.println(milliTime);
System.out.println(new Date().getTime());
}
/*
* JDK8的api: DateTimeFormatter
* */
@Test
public 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);//2022/12/05 16:04:44
//解析:字符串 ---> 日期、时间
TemporalAccessor temporalAccessor = dateTimeFormatter.parse("2022/12/05 15:04:44");
LocalDateTime localDateTime1 = LocalDateTime.from(temporalAccessor);
System.out.println(localDateTime1);//2022-12-05T15:04:44
}
}
5. 比较器(重点)
-
自然排序涉及到Comparable
-
compareTo(Object obj)
-
实现步骤: ① 具体的类A实现Comparable接口 ② 重写Comparable接口中的compareTo(Object obj)方法,在此方法中指明比较类A的对象的大小的标准 ③ 创建类A的多个实例,进行大小的比较或排序。
-
public class ComparableTest {
@Test
public void test1(){
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]);
}
}
@Test
public 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]);
}
}
@Test
public void test3(){
Product p1 = new Product("HuaweiMate50pro",6299);
Product p2 = new Product("VivoX90pro",5999);
int comapre = p1.compareTo(p2);
if(comapre > 0){
System.out.println("p1大");
}else if(comapre < 0){
System.out.println("p2大");
}else{
System.out.println("p1和p2一样大");
}
}
}
-
定制排序涉及到Comparator
-
compare(Object obj1,Object obj2)
-
实现步骤: ① 创建一个实现了Comparator接口的实现类A ② 实现类A要求重写Comparator接口中的抽象方法compare(Object o1,Object o2),在此方法中指明要 比较大小的对象的大小关系。(比如,String类、Product类) ③ 创建此实现类A的对象,并将此对象传入到相关方法的参数位置即可。(比如:Arrays.sort(..,类A的实例))
-
public class ComparatorTest {
@Test
public 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的大小,其标准就是此方法的方法体要编写的逻辑。
//比如:按照价格从高到低排序
@Override
public 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从低到高排序
@Override
public 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]);
}
}
@Test
public void test2(){
String[] arr = new String[]{"Tom","Jerry","Tony","Rose","Jack","Lucy"};
Arrays.sort(arr,new Comparator(){
@Override
public 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]);
}
}
}