一、字符串相关的类
一、String的特性
String 类:代表字符串 Java 程序中所有的字符串字面值 (如"abc")都作为此类的实例实现
1、String 是一个 final 类,代表不可变性
2、String实现了 Serializable 接口:表示字符串是支持序列化的
实现了 Compareable 接口:表示 String可以比较大小
3、String 内部定义了 final char[] value 用于存储字符串数据
4、String:代表一个不可变的字符序列。简称:不可变
体现:a.当对字符串重新赋值时,需要重新制定内存区赋值,不能使用原有的 value 赋值
b.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的 value 赋值
c.当调用 String 的 replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值
[外链图片转存中…(img-pIuPaP77-1740715894960)]

package com.Jackson.java;
import org.junit.Test;
/**String 使用
* @author Jackson_kcw
* @Time 2025-02-25 PM4:01
*/
public class StringTest {
@Test
public void test1(){
String s1="abc";//字面量的定义方式
String s2="abc";
// s1="hello";
System.out.println(s1);
System.out.println(s2);
System.out.println(s1==s2);
String s3="abc";
s3+="def";
String s4="abc";
String s5=s4.replace('a','m');
System.out.println(s4); //s4仍为 abc
System.out.println(s5);//s5为 mbc
}
}
5、通过字面量的方式(区别 new)给一个字符串赋值,此时的字符串声明在字符串常量池
6、字符串常量池里面不会存储相同内容的字符串
String 对象的创建
[外链图片转存中…(img-FHUq1Z3R-1740715894960)]
String的实例化方式:
方式一、通过字面量定义的方式
方式二、通过 new+构造器的方式
@Test
public void test2(){
//通过字面量定义的方式;此时 s1和 s2的数据 "javaEE" 声明在方法区中的字符串常量池中
String s1="javaEE";
String s2="javaEE";
//通过 new+构造器的方式:此时的 s3和 s4保存的地址值,是数据在堆空间开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1==s2); //true
System.out.println(s1==s3); //false
System.out.println(s1==s4); //false
System.out.println(s3==s4);//false
}
字符串常量存储在字符串常量池,目的是共享
字符串非常量对象存储在堆中
面试题:String s=new String(“abc”);方式创建对象,在内存中创建了几个对象
答:两个:一个是堆空间中 new 结构,另一个是 char[]对应的常量池中的数据"abc"
关于字符串的拼接
@Test
public void test3(){
String s1="hello";
String s2="world";
String s3="hello"+"world";
String s4="helloworld";
String s5=s1+"world";
String s6="hello"+s2;
System.out.println(s3==s4); //返回结果是 true
System.out.println(s4==s5); //返回结果为 false
System.out.println(s6==s4); //返回结果为 false
}
结论:常量与常量的拼接结果在常量池中。且常量池中不会存在相同内容的常量
只要其中有一个是变量,结果就在堆中
如果拼接的结果调用 intern()方法,返回值就在常量池中
一个例题
这里面为何 test.str 输出的还是 good?
String str=new String("good");
char[] chars={
't','e','s','t'};
public void change(String str,char ch[]){
str="test ok";
ch[0]='b';
}
public static void main(String[] args) {
StringTest test=new StringTest();
test.change(test.str,test.chars);
System.out.println(test.str); //输出 good
System.out.println(test.chars);//输出 best
}
方法内部的执行过程
str = "test ok";
这里str
只是方法内部的局部变量,它指向了"test ok"
,但并没有改变原来的test.str
,因为 Java 的String
是 不可变的(immutable),外部的test.str
仍然指向"good"
。ch[0] = 'b';
ch
是一个数组,修改ch[0]
会影响原来的test.chars
数组,所以test.chars
的第一个字符从't'
变成了'b'
。
test.change(test.str, test.chars);
str
传递的是"good"
的引用拷贝(即地址),但str = "test ok";
只是修改了方法内部的变量,不影响test.str
,所以test.str
依然是"good"
。chars
传递的是数组的引用,ch[0] = 'b'
会直接修改test.chars
数组的内容,所以test.chars
变为{'b', 'e', 's', 't'}
。
System.out.println(test.str);
输出"good"
(因为String
是不可变的,方法中的修改不会影响原来的test.str
)。
System.out.println(test.chars);
输出"best"
(因为char[]
是可变的,方法中的修改影响了原数组)。
String 常用方法
[外链图片转存中…(img-Y1m3VM9h-1740715894960)]
[外链图片转存中…(img-ELS8usbt-1740715894961)]
[外链图片转存中…(img-UPyS6FKI-1740715894961)]
String与 byte[]之间的转换
String—>byte[] :调用 String 的 getBytes()
StringBuffer、String、StringBuilder 三者的异同:
String:不可变的字符序列;底层使用 char[]
StringBuffer:可变的字符序列;线程安全,效率低;底层使用 char[]
StringBuilder:可变的字符序列;JDK5.0 新增的,线程不安全,效率高;底层使用 char[]
[外链图片转存中…(img-6Ri5apv3-1740715894961)]
二、JDK8 之前日期时间 API
一、System类中的 currentTimeMillis()
二、java.util.Date 和子类 java.sql.Date 在如下代码中体现
package com.Jackson.java3;
import org.junit.Test;
import java.util.Date;
/**
* @author Jackson_kcw
* @Time 2025-02-28 AM10:57
*/
public class DateTimeTest {
//1、System类中的 currentTimeMillis()
@Test
public void test(){
long time=System.currentTimeMillis();
//返回当前时间与 1970年一月一日 0h0m0s之间的以毫秒为单位的时间差 也称为时间戳
System.out.println(time);
}
//2、Date 类
//两个构造器的使用,两个方法的使用 >toString():显示当前的年月日时分秒;;;>getTime():获取当前 Date 对象对应的毫秒数(时间戳)
@Test
public void test2(){
//构造器一:Date():创建一个对应当前时间的 Date 对象
Date date1=new Date();
System.out.println(date1.toString());
System.out.println(date1.getTime());
//构造器二:创建指定毫秒数的 Date 对象
Date date2=new Date(1740704575135L);
System.out.println(date2.toString());
//3、java.sql.Date 对应着数据库中的日期类型的变量
java.sql.Date sqlDate=new java.sql.Date(1740704575135L);
System.out.println(sqlDate.toString());
//4、如何将 java.util.Date对象转换为java.sql.Date对象
// 情况一:直接强转
Date date3=new java.sql.Date(1740704575135L);
java.sql.Date date4=(java.sql.Date)date3;
// 情况二:无法强转的情况下
Date date5=new Date();
java.sql.Date date6=new java.sql.Date(date5.getTime());
}
}
三、SimpleDateFormat
package com.Jackson.java3;
import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author Jackson_kcw
* @Time 2025-02-28 AM11:31
*/
public class SimpleDateFormatTest {
/*
两个操作:
格式化:日期--->字符串
解析: 格式化的逆过程
*/
@Test
public void test() throws ParseException {
//实例化 SimpleDateFormat
SimpleDateFormat sdf=new SimpleDateFormat();
//格式化:日期--->字符串
Date date=new Date();
System.out.println(date);
//解析
String format=sdf.format(date);
System.out.println(format);
//格式化:按指定方式格式化:调用带参数的构造器
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str="2025-02-28 上午 11:40:00";
Date date1=sdf.parse(str);
System.out.println(date1);
}
}
四、Calendar
package com.Jackson.java3;
import org.junit.Test;
import java.util.Calendar;
import java.util.Date;
/**
* @author Jackson_kcw
* @Time 2025-02-28 AM11:53
*/
public class CalendarTest {
//Calendar日历类(抽象类)
@Test
public void test(){
//1、实例化
//方式一:创建其子类的对象(GregorianCalendar)
//方式二:调用其静态方法 getInstance()
Calendar calendar= Calendar.getInstance();
System.out.println(calendar.getClass());
/*
二、常用方法
get()、set()、add()、getTime()、setTime()
*/
int days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
calendar.set(Calendar.DAY_OF_MONTH,22);
days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
calendar.add(Calendar.DAY_OF_MONTH,1);
days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
//getTime(): 日历类--->Date
Date date=calendar.getTime();
System.out.println(date);
//setTime():Date--->日历类
Date date1 = new Date();
calendar.setTime(date1);
}
}
LocalDate\LocalTime\LocalDateTime 的使用
[外链图片转存中…(img-88ZnZj8H-1740715894961)]
三、Java 比较器
Java 实现对象排序的两种方式
自然排序:java.lang.Comparable
商品类:
package com.Jackson.java3;
/**
* @author Jackson_kcw
* @Time 2025-02-28 PM12:37
*/
//商品类
public class Goods implements Comparable{
private String name;
private int price;
public Goods() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Goods(String name, int price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
//指明商品比较大小的方式
@Override
public int compareTo(Object o) {
if(o instanceof Goods){
Goods goods = (Goods) o;
if(this.price > goods.price){
return 1;
}else if(this.price < goods.price){
return -1;
}else return 0;
}
throw new RuntimeException("传入数据类型不一致");
}
//指明商品比较大小的方式
}
比较的实现
package com.Jackson.java3;
import org.junit.Test;
import java.util.Arrays;
/**一、说明 Java 中的对象,正常情况下,只能进行==或!= 不能使用>或<
* 但是实际开发场景中,我们需要对多个对象进行排序
* 使用两个接口的任何一个 Comparable或者 Comparator
*
* @author Jackson_kcw
* @Time 2025-02-28 PM12:29
*/
public class CompareTest {
@Test
public void testCompare(){
//1、像 String、包装类等实现了 Comparable 接口,重写了 compareTo()方法,给出了比较两个对象大小 从小到大排列
//2、重写 compareTo()的规则:
//如果当前对象this大于形参对象 obj,则返回正整数;小于返回负整数,等于返回零
//3、对于自定义类来说,如果需要排序,我们可以让自定义类实现 Comparable 接口,重写 CompareTo 方法
String [] arr=new String[]{
"AA","CC","KK","GG","JJ"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
@Test
public void testCompare2(){
Goods [] arr=new Goods[4];
arr[0]=new Goods("lenovoMouse",34);
arr[1]=new Goods("dellMouse",14);
arr[2]=new Goods("macMouse",90);
arr[3]=new Goods("godMouse",123);
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
定制排序:java.util.Comparator
[外链图片转存中…(img-D0n6GCFl-1740715894961)]
@Test
public void testCompare3(){
String [] arr=new String[]{
"AA","CC","KK","GG","JJ"};
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);
}
// return 0;
throw new RuntimeException("输入的数据类型不一致");
}
});
System.out.println(Arrays.toString(arr));
}
Comparable 接口与 Comparator 的使用的对比:
Comparable 接口的方式一旦指定,保证 Comparable 接口实现类的对象在任何位置都可以比较大小
Comparator 接口属于临时性的
总结
这一章的内容属于是比较杂糅的,又臭又长,看视频还是看文档都很难看下去,而且不容易记住,建议等遇到了相关问题,需要这里面的类的时候再来重点研究,这样有目标性可能效果更好
加油
!!!!!