【Java_Senior】二、常用类

常用类

String

String的定义与特性

String的定义

string内部使用char型数组存储String的数据,属于顺序表
private final char[] value
由于时final定义的,所以String型变量在初次定义后就不能更改,即String具有不可变性。

String实现了Serizeable接口、故其是可序列化的,即可以作为对象进行传输(IO或网络传输)
其也实现了Compareable接口,即可以比较大小

注:String作为对象,可以不new对象直接进行赋值。

String型变量的内存存储结构:
在这里插入图片描述

若新建两个String型变量其值相同,则会使用方法区中字符串常量池中的同一个地址上的数据,若改变其值不会在原有的基础上改变,而是会在字符串常量池中新增一个数据,并使其指向新数据。

无论对String内容进行任何修改,都会重新创建,不会在原有内存上修改。

通过字面量定义的String型变量,其都存放在字符串常量池中。String str = "a"

String str = new String("abc")创建了两个对象,一个是new的str在堆空间中、另一个是在字符串常量池中的char[]型数组,

字符串的拼接
拼接中只有右边有String型变量的变量名,该拼接完的String就会存在堆空间中。

String s1 = "Java" + "hadoop";  //s1直接指向字符串常量池中的的地址
Strhins3 = "Java";
String s2 = s3 + "hadoop";      //s2指向堆空间中的地址,堆空间中存有具体的char[]型数组。

sout("s1 == s2");   //false

String s4 = s2.intern();
sout("s4 == s1");   //true

注:.intern()方法会将无论在哪里的字符串,返回为一个在堆空间中的字符串。

注:final 修饰的字符串属于常量,其与类似"JavaEE"的字面量进行拼接时仍然存储在常量池中

String的常用方法

常用方法一

  1. .length()输出String的长度,即底层char[]的长度。
    @Test
    public void test1(){
        String s1 = "Hello World!";
        System.out.println(s1.length());
    }
}
  1. .charAt(int),返回指定位置的索引,从0开始
System.out.println(s1.charAt(0));    //输出索引位置0号位置的元素
  1. .isEmpty()判断字符串是否为空,根据value.length()是否为0
System.out.println(s1.isEmpty());   
//false
  1. .toLowerCase();将字符串中所有字符变为小写,由另一个字符接收
    .toUpperCase();全部转换为大写由另一个字符接收
  2. .trim();祛除字符串首尾两端的所有空格,由另一个字符接受,本身不改变
String s1 = "    He l lo Wo rl  d!    ";
String s2 = s1.trim();
System.out.println("---------" + s1 + "----------")
System.out.println("---------" + s2 + "----------");
/*
---------    He l lo Wo rl  d!    ----------
---------He l lo Wo rl  d!----------
*/
  1. .equals(),比较是否相等
    .equalsIgnoreCase();在忽略大小写的情况下比较是否相等
  2. .cancat(String);拼接,一般使用"+"
  3. a.compareTo(String b);ASCII码比较,从左往右第一个不相同的字符,a - b;
  4. .substring(int BeginIndex, int EndIndex);切片、从BeginIndex索引到EndIndex索引钱一个位置的切片,也可以指传入BeginIndex代表切片从索引BeginIndex直接到字符串末尾

常用方法二

  1. .endWith(String); 是否以指定字符串结尾
  2. .startWith(String a, int toffSet); 若只传入一个变量,则判断是否以字符串a为开始,若传入两个变量,则判断从索引位置toffSet开始,是否以a为开始。
  3. .contains(String a);判断a是否在字符串中(模式匹配)
  4. .IndexOf(String a, int fromIndex); 判断a是否在字符串中,且返回a在字符串中起始位置的索引,若不在,则返回-1,若添加了int型的形参,则从fromIndex索引位置开始找。
  5. .lastIndexOf(String a, int fromIndex); 从后往前找,并返回其顺序的索引位置。

常用方法三

  1. .replace(String OldChar, String NewChar);将原字符串中的OldChar一样的字符串全部更换成NexChar内容的字符串。

正则表达式。。。

String与Char[]、byte[]之间的转换

String与char[]的转换

String -> char[]调用.toCharArray()方法

String str1 = "123";
char[] c = str1.toCharArray();

char[] -> String 调用String的构造器

char[] arr = new char[]{'Q','W','E','R'};
String str2 = new String(arr);

String与Byte[]的转换

在字节流中会经常使用

String -> Byte[] 调用String的getBytes()方法,会相应的返回ASCII码

编码:从字符串信息编写成字节码。
解码:从字节码转换成可以看懂的字符串信息。

    @Test
    public void Test2() throws UnsupportedEncodingException {
        String str1 = "abc123中国";
        byte[] bytes = str1.getBytes();     //默认使用UTF-8编码集编写汉字
        System.out.println(Arrays.toString(bytes));
        /*
        * [97, 98, 99, 49, 50, 51, -28, -72, -83, -27, -101, -67]
        * */

        byte[] gbks = str1.getBytes("GBK");     //给getBytes()方法传入具体的字符集,使其按照规定字符集进行编码
        System.out.println(Arrays.toString(gbks));
        /*
        * [97, 98, 99, 49, 50, 51, -42, -48, -71, -6]
        * */
    }

byte[] -> String 调用String的构造器。

        String str1 = "abc123中国";
        byte[] bytes = str1.getBytes();

        String s = new String(bytes);
        System.out.println(s);
        /*
        abc123中国
         */

StringBuffer与StringBuilder

String:不可变的字符序列
StringBuffer:可变的字符序列,线程安全、效率偏低
StringBuilder:可变的字符序列,线程不安全,效率较高
三者的底层存储都是char[]型数组

直接在原字符串的基础上可以进行修改,StringBuffer的可变性。

    @Test
    public void test(){
        StringBuffer sb1 = new StringBuffer("abc");
        sb1.setCharAt(0, 'm');
        System.out.println(sb1);
        /*
        mbc
         */
    }

StringBuffer底层:

  1. 在创建时,会默认创建字符串多16个位置的char[]。例如创建StringBuffer str = new StringBuffer("abc");则会创建一个3+16位的char型数组。
  2. StringBuffer可以通过.append()方法一点点往字符串中压入字符,且压入在原字符串中。(可变性)
        /*可变性的体现*/
        StringBuffer sb1 = new StringBuffer("abc");
        sb1.setCharAt(0, 'm');
        System.out.println(sb1);
        /*
        mbc
         */
  1. 若底层char型数组满,则会创建一个原有数组容量两倍+2的容量的数组,并将原数组复制给新数组,若扩容后还不够,则直接以需要的容量作为大小新建数组。

注:若String频繁修改则优先使用StringBuffer或StringBuilder方法。
注:建议使用new StringBuffer(int); 的构造器直接指定底层char型数组的容量。

StringBuffer常用方法

  1. sb.append();向字符串中添加字符或其他数据类型的元素,有很多重载的方法,可以添加很多类型的数据。

         StringBuffer sb1 = new StringBuffer("abc");
         sb1.append(1);  //可以添加int
         sb1.append("1");    //也可以添加String
         sb1.sout;
         /*
         abc11
         */
    
  2. sb.delete(int start, int end);左闭右开的删除对应位置的元素,例如删除(2, 4)位置的元素会对应删除2,3位置上的元素,4处属于开区间,不被删除。

         StringBuffer sb1 = new StringBuffer("abc");
         sb1.setCharAt(0, 'm');
         System.out.println(sb1);
    
         sb1.append(1);
         sb1.append("1");
         sb1.delete(2, 4);
         System.out.println(sb1);
         /*
         mb1
         */
    
  3. sb.replace(int start, int end, String str);左闭右开的选择start到end的元素,并替换为str字符串

        sb1.replace(2, 4, "hello");
        System.out.println(sb1);
        /*
        mbhello1
         */
    
  4. sb.insert(int offset, Xxx);在索引为offset位置上插入Xxx,其类型被重载。

         sb1.insert(2, 888);
         System.out.println(sb1);
         /*
         mb888hello1
         */
    

日期与时间

System中提供的API

System.currentTimeMillis()返回一个long型数据,表示时间戳(1970.1.0,00:00:00到现在的毫秒数)

        long l = System.currentTimeMillis();
        System.out.println(l);
        /*
        1661651529984
         */

Java中Date类的使用

Java.util.Date

构造器一:
Date date = new Date(); //创建对应当前时间的Date对象
方法:
date.toString(); //返回具体信息
date.getTime(); //返回时间戳

        Date date = new Date();     //创建对应当前时间的Date对象
        System.out.println(date.toString());    //返回具体信息
        System.out.println(date.getTime());     //返回时间戳
        /*
        Sun Aug 28 10:01:03 CST 2022
        1661652063244
         */

构造器二:
Date date1 = new Date(1661652063244L); //根据时间戳创建任意时间点的Date对象。

        Date date1 = new Date(1661652063244L);
        System.out.println(date1.toString());
        /*
        Sun Aug 28 10:01:03 CST 2022
         */

Java.sql.Date

sql.Date专门为数据库中的date提供的对象,其可以保存数据库中的Date对象。其可以通过时间戳来赋值,利用util.Date中的getTime()获取时间戳再赋值给sql.Date的构造器来达成util.Date与sql.Date之间的转换。

java.sql.Date date2 = new java.sql.Date(date.getTime());

SimpleDateFormat

创建SimpleDateFormat对象并将其转换为字符串(日期—>字符串)。调用.format()方法。

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
        Date date = new Date();
        //转换为字符串。
        String format = simpleDateFormat.format(date);
        System.out.println(format);
        /*
        22-8-28 上午10:39
         */

字符串转化为日期对象:
.parse(String)方法

        //字符串转换为Date对象
        String format1 = "22-11-25 下午6:38";
        Date parse = simpleDateFormat.parse(format1);
        System.out.println(parse);
        /*
        Fri Nov 25 18:38:00 CST 2022
         */

按照指定格式进行格式化:
要求格式化的字符串以SimpleDateFormat的指定格式输出,则也可以用该方式进行解析。

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String f1 = sdf.format(date);
        System.out.println(f1);
        /*
        2022-08-28 10:52:15
        */

Calender日历类

Calender 是一个抽象类。不能直接调用构造器,一般使用getInstance()静态方法创建Calender的实现类.

以及get(),set(),getTime(),setTime()四个常用方法。

    public void test3(){
        Calendar c = Calendar.getInstance();
        //  get()方法用于获取一些常用数据。
        //例如获取一年的第几天、一周的第几天等等
        int i = c.get(Calendar.DAY_OF_MONTH);
        System.out.println(i);

        //set()方法可以更改c中的属性,例如下面面就更改了月中的信息
        c.set(Calendar.DAY_OF_MONTH, 20);

        //相当于该月加了三天
        c.add(Calendar.DAY_OF_MONTH, 3);

        //.getTime()将Calendar对象转换为Date对象
        Date d = c.getTime();

        //.setTime()将Date类的对象转化为Calendar类的对象
        Date d1 = new Date();
        Calendar c1 = Calendar.getInstance();
        c1.setTime(d1);
    }

Calander类的缺点

  1. 日期作为不可变量,定义之后应该是不可修改的,但Calander仍提供了可以更改日期的方法。
  2. 其有偏移量,若要显示真实日期还需要年份-1900以及月份-1的操作来纠正偏移量
  3. Calander没有提供格式化的方法,若要格式化只能转换为Date再进行格式化。
  4. 无法处理闰秒

Java 8中的新增API(强大)

LocalDate、LocalTime、LocalDateTime

初始化,调用.now()方法创建现在。

        LocalDate l1 = LocalDate.now();
        LocalTime l2 = LocalTime.now();
        LocalDateTime l3 = LocalDateTime.now();

        System.out.println(l1);
        System.out.println(l2);
        System.out.println(l3);
        /*
        2022-08-28
        12:57:44.571
        2022-08-28T12:57:44.571
         */

调用.of()方法声明某时刻,没有偏移量

        LocalDateTime l4 = LocalDateTime.of(2023, 02, 10, 23, 50, 58);
        System.out.println(l4);
        /*
        2023-02-10T23:50:58
         */

一些常用方法

        //一些get方法
        System.out.println(l3.getDayOfMonth());     //月中的日期
        System.out.println(l3.getDayOfWeek());      //一周的第几天
        System.out.println(l3.getMonth());          //String类型的月
        System.out.println(l3.getMonthValue());     //int类型的月
        System.out.println(l3.getMinute());         //获得分钟
        /*
        28
        SUNDAY
        AUGUST
        8
        6
         */

日期的更改,需要进行接收返回值,因为Local具有不可变性,其本身的日期是不会更改的。.withXxx()

        LocalDateTime l5 = l4.withMonth(12);     //设置月份
        System.out.println(l5);
        /*
        2023-12-10T23:50:58v
         */

.plusXxx()时间的增加,或也可以减少等

        LocalDateTime l6 = l3.plusMonths(3);
        System.out.println(l6);
        /*
        2022-11-28T13:13:13.680
         */

Instant(瞬时点)

调用.now()方法进行创建,但默认不在本时区,则应该调用atOffset()方法调整时区。

        Instant instant = Instant.now();
        System.out.println(instant);    //本初子午线时区、差八个小时
        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));        //调整时区
        System.out.println(offsetDateTime);
        /*
        * 2022-08-28T05:22:44.723Z
            2022-08-28T13:22:44.723+08:0
        * */

使用.toEpochMilli()方法获取时间戳

System.out.println(instant.toEpochMilli()); //  获取时间戳

DateTimeFormatter

用来格式化或解析时间的工具,创建方式以及格式化如下:(不常用)

        DateTimeFormatter d1 = DateTimeFormatter.ISO_DATE_TIME;     //创建一个d1用来进行格式化,其仅仅是一个工具
        LocalDateTime l1 = LocalDateTime.now();
        String str = d1.format(l1);

        /*
        2022-08-28T13:33:13.334
         */

自定义的时间格式(常用),使用.ofPattern(“”)方法。
以及,格式化与解码

        DateTimeFormatter D = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        System.out.println(D.format(LocalDateTime.now()));
        /*
        * 2022-08-28 01-44-12
        * */
        TemporalAccessor t = D.parse("1999-05-10 10:30:55");
        System.out.println(t);
        /*
        {NanoOfSecond=0, MicroOfSecond=0, SecondOfMinute=55, MilliOfSecond=0, HourOfAmPm=10, MinuteOfHour=30},ISO resolved to 1999-05-10
         */

对象的比较

Comparable接口(自然排序)

实现了Comparable或Comparator接口的类可以对对象进行比较
Array.sort()方法中的比较是因为String类实现了Comparable接口,进而重写了Comparable接口中的compareTo()方法,所以可以对对象进行比较并且排序。

        String[] str = new String[]{"AA", "BB", "KK", "GG", "CC"};
        Arrays.sort(str);
        System.out.println(Arrays.toString(str));
        /*
        [AA, BB, CC, GG, KK]
         */

若自定义类要进行排序,则需要在自定义类中实现Comparable接口并重写CompareTo()方法。

其实现大致为:若调用方法的对象大于传入形参的对应对象,则返回1,若小于则返回-1,若等于则返回0;

    public int compareTo(Object o) {
        if(o instanceof Goods){
            Goods g = (Goods)o;
            if(this.price > g.price) {return 1;}
            else if(this.price < g.price){ return -1;}
            else{ return 0;}
//            return Double.compare(this.price, g.price);
        }
        throw new RuntimeException("数据类型不一致");
    }

重写CompareTo()方法之后就可以在主方法中调用sort()方法进行对象的排序了

Comparator接口(自定义排序)

当不方便修改代码中的CompareTo()方法或其排序方法不合适时、可以实现CompareTo()接口,进而重写Compare()方法对其进行自定义排序
Compare(Object o1, Object o2);若o1大于o2,则返回一个正整数,若o1小于o2则返回一个负整数,相等则返回0;

一个举例:

        String[] str = new String[]{"AA", "BB", "KK", "GG", "CC"};
        Arrays.sort(str, new Comparator(){
            @Override
            public int compare(Object o1, Object o2){
                if(o1 instanceof String && o2 instanceof String){
                    String str1 = (String)o1;
                    String str2 = (String)o2;
                    return -str1.compareTo(str2);
                }
                throw new RuntimeException("输入的类型不正确");
            }
        });
        System.out.println(Arrays.toString(str));

Comparator更倾向于一个临时性的比较,一般只使用一次。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值