JAVA高级-常用类和常用方法

14 篇文章 0 订阅
11 篇文章 1 订阅

常用类

String类

  • **String****类:代表字符串。**Java 程序中的所有字符串字面值(如 “abc” )都作

    为此类的实例实现。

  • String是一个final类,代表不可变的字符序列。

  • 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。

https://i.loli.net/2021/06/12/Ps7AnfxNqwKQc8h.png

  • String对象的字符内容是存储在一个字符数组value[]中的。

  • implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
    
  • 以上可见,在String类里,我们实现里两个接口,Serializable:这表示字符串是可以序列化的,Comparable:表示字符串是可以比较的

字面量实例化

package com.hyb.usualClass;

import org.junit.Test;

/**
 * @program: StringTest
 * @description:常用类,String
 *
 *
 * @author: Huang Yubin
 * @create: 2021-06-08 12:35
 **/

public class StringTest {
    @Test
    public void test1(){
//        字面量赋值
        String s1="abc";
        s1+="1";
        System.out.println(s1);
        /*可见我们可以给字符串更改值,但是从内存结构来讲,abc是没有被改变的,只是将abc1这个值赋值给了s1
        * 但是abc1从哪来的呢?只是从常量池里找来的,并不是在原来的abc上加过来的*/

        /*--------------------------------*/
        String s2="abc";
        String s3=s2.replace("a","c");
        System.out.println(s3);
//      cbc
        /*在这里原理也是一样,我们将a用c代替,只是创造了一个新的常亮cbc,而不是将原来abc修改了*/

        /*在这里我们便能总结出一个道理:
        * 字符串本质上是不可变的    */

    }
}

new关键字实例化

@Test
public void test2(){
    String s1="abc";
    String s2="abc";
    String s3=new String("abc");
    String s4=new String("abc");
    System.out.println(s1==s2);//true,因为常量值是一定的,不可改变,当然,地址可能不一样
    System.out.println(s1==s3);//false,对象存储在堆中,abc存在常量池中,地址可能改变
    System.out.println(s3 == s4);//false,对象比较是地址
    System.out.println(s1 == s4);//false

    /*但是这里可说明一点,当我们用同一个类new两个对象比较两个相等的字符串时,==符号便可以比较的
    * 因为我们new了两个对象在堆空间中造了两个地址,但是这两个相等的字符串是在常量池里的,不可改变*/
    
    /*---------------*/
    
    /*面试题里,一般都会问String s3=new String("abc");创建了几个对象?
    * 可知,有两个。
    * 一个是堆空间里的,一个是常量池里的*/

}

https://i.loli.net/2021/06/12/ONm7hq2HW1I6uAY.png

https://i.loli.net/2021/06/12/jreEBhJbDmH62lC.png

https://i.loli.net/2021/06/12/VQms7Nonctwhqpv.png

区别

@Test
public void test3(){
        String s1="abc";
        String s2="abc";
        String s3=s1+s2;
        String s4="abcabc";
        String s5=s1+"abc";
        System.out.println(s1 == s2);//true常量池的常量不可变
        System.out.println(s1 == s3);//false内容都不等
        System.out.println(s3 == s4);//false s4在常量池里,而s3在堆里创建了一个对象,让s1+s2
        System.out.println(s4 == s5);//false 也一样

        String s6=(s3).intern();
        System.out.println(s6==s4);//ture,intern()返回常量池
        /*我们就此可以总结出:
        * 1.常亮与常亮的拼接是返回常亮池的,且常量池里没有相同的常亮
        * 2.只要其中有一个是变量,结果就在堆中
        * 3.如果用intern方法,结果会返回常量池*/
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yMdbNMLb-1647786099625)(C:\Users\黄渝斌\Desktop\5.png)]

面试题1

package com.hyb.usualClass;

/**
 * @program: InterviewProblem
 * @description:
 * @author: Huang Yubin
 * @create: 2021-06-08 13:43
 **/

public class InterviewProblem1 {
    String str = new String("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) {
        InterviewProblem1 ex = new InterviewProblem1();
        ex.change(ex.str, ex.ch);
        System.out.println(ex.str);//good
        System.out.println(ex.ch);//best
    }
    /*good是一个字符串,字符串是无法改变的,所以输出good,也可以这样理解,java是值传递的,改变不了str
    * ch是一个数组,数组是可变的,自然可以改变*/
}

常用方法

https://i.loli.net/2021/06/12/bS7ZalCqFNMjOnG.png

https://i.loli.net/2021/06/12/MnAPZ5Rgu3TbUla.png

https://i.loli.net/2021/06/12/AluWXjTYt7KLiI3.png

String与基本数据类型的转换

  • 字符串 -> 基本数据类型、包装类

    1. Integer包装类的public static int parseInt(String s):可以将由“数字”字

      符组成的字符串转换为整型。

    2. 类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应

      的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型。

  • 基本数据类型、包装类 -> 字符串

    1. 调用String类的public String **valueOf(int n)**可将int型转换为字符串

    2. 相应的valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(double

      d)、valueOf(boolean b)可由参数的相应类型到字符串的转换

  • 字符数组 -> 字符串

    1. String 类的构造器:String(char[]) String(char[]int offsetint

      length) 分别用字符数组中的全部字符和部分字符创建字符串对象。

    String s2=new String(Arry);
    System.out.println(s2);//abc
    
  • 字符串->转为为字符数组

    1. **public char[] toCharArray()**将字符串中的全部字符存放在一个字符数组

      中的方法。

    2. public void getChars(int srcBegin, int srcEnd, char[] dst,

      **int dstBegin)**提供了将指定索引范围内的字符串存放到数组中的方法。

    String s1="abc";
    char[] Arry=s1.toCharArray();
    for (int i = 0; i < s1.length(); i++) {
        System.out.println(Arry[i]);
    }
    
  • 字符串->字符数组

    1. public byte[] getBytes() **:**使用平台的默认字符集将此 String 编码为

      byte 序列,并将结果存储到一个新的 byte 数组中。

    2. public byte[] getBytes(String charsetName) **:**使用指定的字符集将

      此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。

    String s1="abc中国";
    byte[] s2=s1.getBytes();
    
  • 字节数组 -> 字符串

    1. String(byte[]int offset,**int length) **用指定的字节数组的一部分,

      即从数组起始位置offset开始取length个字节构造一个字符串对象。

    2. String(byte[],int offsetint length) 用指定的字节数组的一部分,

      即从数组起始位置offset开始取length个字节构造一个字符串对象。

    String s = new String(s2);
    
@Test
public void test5() throws UnsupportedEncodingException {

//        编码
        String s1="abc中国";
        byte[] s2=s1.getBytes();
        System.out.println(Arrays.toString(s2));
//        [97, 98, 99, -28, -72, -83, -27, -101, -67]UTF_8

        byte[] s3=s1.getBytes("gbk");
        System.out.println(Arrays.toString(s3));
//        [97, 98, 99, -42, -48, -71, -6]jbk

//        解码

        String s = new String(s2);
        System.out.println(s);
//      abc中国

        String gbk = new String(s3, "gbk");
        System.out.println(gbk);
//        abc中国


    }
}

StringBuffer

  • 可变的字符序列
//API
public final class StringBuffer
   extends AbstractStringBuilder
   implements java.io.Serializable, CharSequence
String s = new String("我喜欢学习"); 
StringBuffer buffer = new StringBuffer("我喜欢学习"); 
buffer.append("数学");
//我喜欢学习数学

请点击图片链接

https://i.loli.net/2021/06/12/mT6SBo4LcyHfCFN.png

  • JDK1.0中声明,可以对字符

    串内容进行增删,此时不会产生新的对象。

  • 很多方法与String相同。

  • 作为参数传递时,方法内部可以改变值。

  • StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接

  • StringBuffer delete(int start,int end):删除指定位置的内容

  • StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str

  • StringBuffer insert(int offset, xxx):在指定位置插入xxx

  • StringBuffer reverse() :把当前字符序列逆转

  • public String substring(int start,int end):把[start,end)位置替换为str

  • public void setCharAt(int n ,char ch):将指定位置字符改变

  • public char charAt(int n ):获取某一个位置字符

  • 增:append(xxx)

  • 删: delete(int start,int end)

  • 改: replace(int start, int end, String str):把[start,end)位置替换为str。

    substring(int start,int end):把[start,end)位置替换为str

    setCharAt(int n ,char ch):将指定位置字符改变

  • 查:charAt(int n ):获取某一个位置字符

  • 插: insert(int offset, xxx):在指定位置插入xxx

  • 长度:length()

  • 遍历:for+查

StringBuilder

  • StringBuilder StringBuffer 非常类似,均代表可变的字符序列,而且

    提供相关功能的方法也一样

面试题2

对比String、StringBuffer、StringBuilder
  • String(JDK1.0):不可变字符序列

  • StringBuffer(JDK1.0):可变字符序列、效率低、线程安全

  • StringBuilder(JDK 5.0):可变字符序列、效率高、线程不安全

  • 作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder

    会改变其值。

  • 底层都使用char数组存储。

    String S1=new String();//value =new char[0]
    String s1=new String("abc")//value new char[]{'a','b','c'}
        
    StringBuffer s1=new StringBuffer();//value =new char[16]底层创建了一个长度为16的数组
    s1.append('a');//value[0]='a';
    
    StringBuffer s1=new StringBuffer("abc")//value =new char["abc".length()+16]扩容
    
  • 输出三者的长度时:

    String:就是当前length

    StringBuffer:也是当前length,虽然底层创建了16长度的数组,但是返回的length是根据当前length返回的

    StingBuffer都一样

  • 扩容问题:

    如果添加的数据底层装不下,那么需要将底层的数组扩容,默认下,每次扩容两倍,将原来的数组赋值到新的数组里

    **StringBuffer(int)**可指定底层数组容量

  • 关于三者执行时间的比较:StringBuilder<StringBuffer<String

    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));
    

JDK8之前日期时间API

点击图片链接:https://i.loli.net/2021/06/12/7kdIqz4jSFRX325.png

java.lang.System

  • System类提供的public static long currentTimeMillis()用来返回当前时

    间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差,俗称时间戳

  • 计算世界时间的主要标准有:

    1. UTC(Coordinated Universal Time)

    2. GMT(Greenwich Mean Time)

    3. CST(Central Standard Time)

java.util.Date

  • 表示特定的瞬间,精确到毫秒

  • **Date()**使用无参构造器创建的对象可以获取本地当前时间。

  • Date(long date)

  • **getTime()😗*返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象

    表示的毫秒数。

  • **toString()😗*把此 Date 对象转换为以下形式的 String: dow mon dd

    hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue,

    Wed, Thu, Fri, Sat),zzz是时间标准。

  • 其它很多方法都过时了。

import java.util.Date;
Date date = new Date();
System.out.println(date);
System.out.println(System.currentTimeMillis());
System.out.println(date.getTime());
Date date1 = new Date(date.getTime());
System.out.println(date1.getTime());
System.out.println(date1.toString());
  • 子类java.sql.Date,一般方法如父类一样。

  • 其子类转化为父类,直接强转,多态便可以进行

    但是父类转化为子类,要用到中间值,也就是时间戳(毫秒数)。

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

java.text.SimpleDateFormat类(日期格式化)

  • Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat

    类是一个不与语言环境有关的方式来格式化和解析日期的具体类

  • 格式化:将一个日期转化为字符串

    1. SimpleDateFormat() :默认的模式和语言环境创建对象

    2. **public SimpleDateFormat(String pattern)**该构造方法可以用参数pattern

      指定的格式创建一个对象,该对象调用:

    3. **public String format(Date date)**方法格式化时间对象date

package com.hyb.usualClass;

import javafx.scene.input.DataFormat;
import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @program: StringBuffter
 * @description:
 * @author: Huang Yubin
 * @create: 2021-06-08 14:46
 **/

public class DateTest {
    @Test
    public void test1() throws ParseException {
        Date date = new Date();


        /*默认格式化*/
        SimpleDateFormat sdf1 = new SimpleDateFormat();
        System.out.println(sdf1.format(date));
//        21-6-8 下午4:27

        /*解析*/
        System.out.println(sdf1.parse("21-6-8 下午4:27"));
//        Tue Jun 08 16:27:00 CST 2021

        /*API自定义格式化*/

        SimpleDateFormat syf2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        System.out.println(syf2.format(date));
//        2021-06-08 04:32:57

        /*解析*/
        System.out.println(syf2.parse("2021-06-08 04:32:57"));
//        Tue Jun 08 04:32:57 CST 2021
    }
}

**java.util.Calendar(**日历类)

  • 抽象类,无法直接实例化

  • 使用子类GregorianCalendar实例化,或者调用方法用Calendar.getInstance()

  • 常用方法

    1. 通过get(int field)方法来取得想

      要的时间信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、

      MINUTE、SECOND

    2. public void set(int field,int value)

    3. public void add(int field,int amount)

    4. public final Date getTime()

    5. public final void setTime(Date date)

package com.hyb.usualClass;

import javafx.scene.input.DataFormat;
import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @program: StringBuffter
 * @description:
 * @author: Huang Yubin
 * @create: 2021-06-08 14:46
 **/

public class DateTest {
    @Test
    public void test2(){
        GregorianCalendar date1 = new GregorianCalendar();

//        get,获取日历信息
        System.out.println(date1.get(Calendar.DAY_OF_MONTH));//六月份第八天

//        set改变时间

        date1.set(Calendar.DAY_OF_MONTH,9);
        System.out.println(date1.get(Calendar.DAY_OF_MONTH));//变成六月份第九天

//        getTime

        System.out.println(date1.getTime());//Wed Jun 09 17:04:37 CST 2021

//        setTime
        Date date = new Date();
        date1.setTime(date);
        System.out.println(date1.get(Calendar.DAY_OF_MONTH));//这个月第八天
    }
}
  • 注意
  1. 获取月份时:一月是0,二月是1,以此类推,12月是11

  2. 获取星期时:周日是1,周二是2 , 。。。。周六是7

JDK8中新日期时间API

问题引入

  • 如果我们可以跟别人说:“我们在1502643933071见面,别晚了!”那么就再简单不

    过了。但是我们希望时间与昼夜和四季有关,于是事情就变复杂了。JDK 1.0中包含了

    一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用

    了。而Calendar并不比Date好多少。它们面临的问题是:

    可变性:像日期和时间这样的类应该是不可变的。

    偏移性:Date中的年份是从1900开始的,而月份都从0开始。

    格式化:格式化只对Date有用,Calendar则不行。

    此外,它们也不是线程安全的;不能处理闰秒等。

    总结:对日期和时间的操作一直是Java程序员最痛苦的地方之一。

  • java.time – 包含值对象的基础包

    java.time.chrono – 提供对不同的日历系统的访问

    java.time.format – 格式化和解析时间和日期

    java.time.temporal – 包括底层框架和扩展特性

    java.time.zone – 包含时区支持的类

    说明:大多数开发者只会用到基础包和format包,也可能会用到temporal包。因此,尽

    管有68个新的公开类型,大多数开发者,大概将只会用到其中的三分之一。

LocalDate、LocalTime、LocalDateTime 类

  • LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例

    是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。

    它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区

    相关的信息。

    1. LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。

    2. LocalTime表示一个时间,而不是日期。

    3. LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。

  • now() / * now(ZoneId zone) 静态方法,根据当前时间创建对象/指定时区的对象

    LocalDateTime now = LocalDateTime.now();//不可变
    
  • of() 静态方法,根据指定日期/时间创建对象,无偏移量

    LocalDateTime of=LocalDateTime.of(2021,6,8,19,15);
            System.out.println(of);
    //      021-06-08T19:15
    
  • getDayOfMonth()/getDayOfYear() 获得月份天数(1-31) /获得年份天数(1-366)

  • getDayOfWeek() 获得星期几(返回一个 DayOfWeek 枚举值)

  • getMonth() 获得月份, 返回一个 Month 枚举值

  • getMonthValue() / getYear() 获得月份(1-12) /获得年份

  • getHour()/getMinute()/getSecond() 获得当前对象对应的小时、分钟、秒

  • withDayOfMonth()/withDayOfYear()/

    withMonth()/withYear()

    将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象

  • plusDays(), plusWeeks(),

    plusMonths(), plusYears(),plusHours()

    向当前对象添加几天、几周、几个月、几年、几小时

instant

  • 时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间

    戳。

  • (1 ns = 10-9 s) 1秒 = 1000毫秒 =106微秒=109纳秒

  • now() 静态方法,返回默认UTC时区的Instant类的对象

    Instant now = Instant.now();
            System.out.println(now);
    //       2021-06-08T11:22:25.183Z伦敦时间
    

    可见我们得到的是伦敦时间,那么就要转变为北京时间,得了解世界的时区分布。

    https://i.loli.net/2021/06/12/FlLirNt8xk6n1Oh.png

    ​ 我们在东八区,那么就要将偏移量算上去。

  • atOffset(ZoneOffset offset) 结合即时的偏移来创建一个 OffsetDateTime

    OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
            System.out.println(offsetDateTime);
    //        2021-06-08T11:28:57.438Z
    //        2021-06-08T19:28:57.438+08:00
    
  • ofEpochMilli(long epochMilli) 静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象

     Instant instant = now.ofEpochMilli(100002L);
            System.out.println(instant);
    //        1970-01-01T00:01:40.002Z
    
  • toEpochMilli() 返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳

    System.out.println(now.toEpochMilli());
    //        1623152010594
    
    

java.time.format.DateTimeFormatter

  • 该类提供三种格式化:

  • 预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME

    该定义不会改变原来LocalDate、LocalTime、LocalDateTime的格式,只是一个标准格式,改成了字符串类型而已。

            DateTimeFormatter formater=DateTimeFormatter.ISO_DATE_TIME;
            LocalDateTime now = LocalDateTime.now();
    //        格式化
            System.out.println(now);
            System.out.println(formater.format(now));
    //        2021-06-08T19:45:13.776
    //        2021-06-08T19:45:13.776
    
    //        解析
            System.out.println(formater.parse("2021-06-08T19:45:13.776"));
    //        {},ISO resolved to 2021-06-08T19:45:13.776
    
  • 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)

  • 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)重点

    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
            System.out.println(dateTimeFormatter.format(LocalDateTime.now()));
    //        2021-06-08 07:59:00
    

请点击链接查看图片:https://i.loli.net/2021/06/12/VyqMbuYwozEZspG.png

其他API

  • ZoneId**:**该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris

  • ZonedDateTime**:**一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30+01:00 Europe/Paris。 其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等

  • Clock**:**使用时区提供对当前即时、日期和时间的访问的时钟。

  • 持续时间:Duration,用于计算两个“时间”间隔

  • 日期间隔:Period,用于计算两个“日期”间隔

  • TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。

  • TemporalAdjusters : 该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用TemporalAdjuster 的实现。

//ZoneId:类中包含了所有的时区信息
// ZoneId的getAvailableZoneIds():获取所有的ZoneId

Set<String> zoneIds = ZoneId.getAvailableZoneIds();
for (String s : zoneIds) {
	System.out.println(s);
}

// ZoneId的of():获取指定时区的时间
LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(localDateTime);

//ZonedDateTime:带时区的日期时间
// ZonedDateTime的now():获取本时区的ZonedDateTime对象
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);

// ZonedDateTime的now(ZoneId id):获取指定时区的ZonedDateTime对象
ZonedDateTime zonedDateTime1 = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime1);

//9.3 JDK8中新日期时间API
//Duration:用于计算两个“时间”间隔,以秒和纳秒为基准
LocalTime localTime = LocalTime.now();
LocalTime localTime1 = LocalTime.of(15, 23, 32);

//between():静态方法,返回Duration对象,表示两个时间的间隔
Duration duration = Duration.between(localTime1, localTime);
System.out.println(duration);
System.out.println(duration.getSeconds());
System.out.println(duration.getNano());

LocalDateTime localDateTime = LocalDateTime.of(2016, 6, 12, 15, 23, 32);
LocalDateTime localDateTime1 = LocalDateTime.of(2017, 6, 12, 15, 23, 32);
Duration duration1 = Duration.between(localDateTime1, localDateTime);
System.out.println(duration1.toDays());
//Period:用于计算两个“日期”间隔,以年、月、日衡量
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = LocalDate.of(2028, 3, 18);

Period period = Period.between(localDate, localDate1);
System.out.println(period);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());

Period period1 = period.withYears(2);
System.out.println(period1)
// TemporalAdjuster:时间校正器
// 获取当前日期的下一个周日是哪天?
        TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(DayOfWeek.SUNDAY);
        LocalDateTime localDateTime = LocalDateTime.now().with(temporalAdjuster);
        System.out.println(localDateTime);
// 获取下一个工作日是哪天?
        LocalDate localDate = LocalDate.now().with(new TemporalAdjuster() {
            @Override
            public Temporal adjustInto(Temporal temporal) {
                LocalDate date = (LocalDate) temporal;
                if (date.getDayOfWeek().equals(DayOfWeek.FRIDAY)) {
                    return date.plusDays(3);
                } else if (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) {
                    return date.plusDays(2);
                } else {
                    return date.plusDays(1);
                } }
        });
        System.out.println("下一个工作日是:" + localDate);
    }

请点击链接:https://i.loli.net/2021/06/12/5FUdwORe1jMv7iY.png

JAVA比较器

自然排序

  • Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称

    为类的自然排序。

  • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即

    通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大

    于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回

    负整数,如果当前对象this等于形参对象obj,则返回零。

  • 实现Comparable接口的对象列表(和数组)可以通过 Collections.sort

    Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有

    序集合中的元素,无需指定比较器。

  • 对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与

    e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals

    一致。建议(虽然不是必需的)最好使自然排序与 equals 一致。

  • Comparable 的典型实现:(默认都是从小到大排列的) :

    1. String:按照字符串中字符的Unicode值进行比较

    2. Character:按照字符的Unicode值来进行比较

    3. 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值

      大小进行比较

    4. Boolean:true 对应的包装类实例大于 false 对应的包装类实例

    5. Date、Time等:后面的日期时间比前面的日期时间大

class Goods implements Comparable {
    private String name;
    private double price;
    //按照价格,比较商品的大小
    @Override
    public int compareTo(Object o) {
        if(o instanceof Goods) {
            Goods other = (Goods) o;
            if (this.price > other.price) {
                return 1;
            } else if (this.price < other.price) {
                return -1;
            }
            return 0;
        }
        throw new RuntimeException("输入的数据类型不一致");
    }
    //构造器、getter、setter、toString()方法略
}
public class ComparableTest{
    public static void main(String[] args) {
        Goods[] all = new Goods[4];
        all[0] = new Goods("《红楼梦》", 100);
        all[1] = new Goods("《西游记》", 80);
        all[2] = new Goods("《三国演义》", 140);
        all[3] = new Goods("《水浒传》", 120);
        Arrays.sort(all);
        System.out.println(Arrays.toString(all));
    } 
}

定制排序

  • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,

    或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那

    么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排

    序的比较。

  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返

    回正整数,则表示o1大于o2**;如果返回0,表示相等;返回负整数,表示**

    o1小于o2。

  • 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),

    从而允许在排序顺序上实现精确控制。

  • 还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的

    顺序,或者为那些没有自然顺序的对象 collection 提供排序。

Goods[] all = new Goods[4];
all[0] = new Goods("War and Peace", 100);
all[1] = new Goods("Childhood", 80);
all[2] = new Goods("Scarlet and Black", 140);
all[3] = new Goods("Notre Dame de Paris", 120);
Arrays.sort(all, new Comparator() {
    @Override
    public int compare(Object o1, Object o2) {
        Goods g1 = (Goods) o1;
        Goods g2 = (Goods) o2;
        return g1.getName().compareTo(g2.getName());
    }
});
System.out.println(Arrays.toString(all));

System类

  • System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。

    该类位于java.lang包。

  • 由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实

    例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便

    的进行调用。

  • 成员变量:

    • System类内部包含in、out和err三个成员变量,分别代表标准输入流

      (键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。

  • 成员方法:

    • native long currentTimeMillis():该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时

      间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。

    • void exit(int status):该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表

      异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。

    • void gc():该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则

      取决于系统中垃圾回收算法的实现以及系统执行时的情况。

    • String getProperty(String key)

    该方法的作用是获得系统中属性名为key的属性对应的值。系统中常见

    的属性名以及属性的作用如下表所示:

    https://i.loli.net/2021/06/12/tHanPeMzOKCAoSd.png

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);

Math类

  • java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回

    值类型一般为double型。

    abs 绝对值

    acos,asin,atan,cos,sin,tan 三角函数

    sqrt 平方根

    pow(double a,doble b) a的b次幂

    log 自然对数

    exp e为底指数

    max(double a,double b)

    min(double a,double b)

    random() 返回0.0到*1.0的随机数

    long round(double a) double型数据a转换为long型(四舍五入)

    toDegrees(double angrad) 弧度—>角度

    toRadians(double angdeg) 角度—>弧度

BigInteger与BigDecimal

  • Integer类作为int的包装类,能存储的最大整型值为2 31-1,Long类也是有限的,

    最大为2 63-1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类

    都无能为力,更不用说进行运算了。

  • java.math包的BigInteger****可以表示不可变的任意精度的整数。BigInteger 提供

    所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。

    另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、

    位操作以及一些其他操作。

  • 构造器 BigInteger(String val):根据字符串构建BigInteger对象

  • 常用方法:

    1. public BigInteger abs():返回此 BigInteger 的绝对值的 BigInteger。

    2. BigInteger add(BigInteger val) :返回其值为 (this + val) 的 BigInteger

    3. BigInteger subtract(BigInteger val) :返回其值为 (this - val) 的 BigInteger

    4. BigInteger multiply(BigInteger val) :返回其值为 (this * val) 的 BigInteger

    5. BigInteger divide(BigInteger val) :返回其值为 (this / val) 的 BigInteger。整数

      相除只保留整数部分。

    6. BigInteger remainder(BigInteger val) :返回其值为 (this % val) 的 BigInteger。

    7. BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟

      (this % val) 的两个 BigInteger 的数组。

    8. BigInteger pow(int exponent) :返回其值为 (thisexponent) 的 BigInteger。

BigDecimal

  • 一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,

    要求数字精度比较高,故用到java.math.BigDecimal类。

  • BigDecimal类支持不可变的、任意精度的有符号十进制定点数。

  • 构造器

    1. public BigDecimal(double val)

    2. public BigDecimal(String val)

  • 常用方法

    1. public BigDecimal add(BigDecimal augend)

    2. public BigDecimal subtract(BigDecimal subtrahend)

    3. public BigDecimal multiply(BigDecimal multiplicand)

    4. public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

public void testBigInteger() {
    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));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值