22、Java 常用类

一、字符串相关的类


一、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()方法修改指定字符或字符串时,也需要重新指定内存区域赋值

CleanShot 2025-02-25 at 16.11.19

[外链图片转存中…(img-pIuPaP77-1740715894960)]

扫描二维码关注公众号,回复: 17570889 查看本文章
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 接口属于临时性的


总结

这一章的内容属于是比较杂糅的,又臭又长,看视频还是看文档都很难看下去,而且不容易记住,建议等遇到了相关问题,需要这里面的类的时候再来重点研究,这样有目标性可能效果更好
加油
!!!!!