java常用类

一、字符串相关的类

String类及常用方法

1.1String的使用

1.String:字符串,使用一对“”引起来表示。

2.String声明为final,不可被继承。

3.String实现了Serializable接口,表示字符串是支持序列化的。

    实现了Comparable接口,表示String可以比较大小

4.String:代表不可变的字符串序列。简称:不可变性

  体现:①当对字符串重新赋值时,需要重新指定内存区域,然后进行赋值,不能使用原有的value进行赋值。

    ②当对现有字符串拼接操作时,也需要重新指定区域,然后进行赋值,不能使用原有的value进行赋值。

    ③当调用String的replace方法修改指定的字符或字符串时,也需要重新指定区域进行赋值,不能使用原有的value进行赋值。

5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。

6.字符串常量池中是不会存储相同内容的字符串的。

1.2String对象的创建

String 的实例化方式
方式一:通过字面量定义的方式
方式二:通过new+构造器的方式

/*
    String 的实例化方式
    方式一:通过字面量定义的方式
    方式二:通过new+构造器的方式

    面试题:String s = new String("abc");方式创建对象,在内存中创建了几个对象?
    两个:一个是堆空间中new的结构,另一个是char[]对应的常量池中的数据"abc"
     */
    @Test
    public void test2(){
        //字面量的方式:此时的s1和s2的数据“abc”声明在方法去中的字符串常量池中
        String s1 = "abc";
        String s2 = "abc";

        //通过new + 构造器的方式:此时的s3和s4保存的是地址值,是数据在堆空间中开辟空间以后对应的地址值。
        String s3 = new String("abc");
        String s4 = new String("abc");

        Person p1 = new Person("Tom",12);
        Person p2 = new Person("Tom",13);

        System.out.println(s1==s2); //true
        System.out.println(s1 ==s3); //false
        System.out.println(s1 ==s4); //f
        System.out.println(s2 == s3);//f
        System.out.println(s3 ==s4); //f
        System.out.println(s1.equals(s3)); //t
        System.out.println("****************************");
        System.out.println(p1.name == p2.name); //注意这里为啥是true,因为通过字面量的方式都是存放在字符串常量池中
        System.out.println(p1.name.equals(p2.name));//true

    }

String不同拼接操作的对比:

内存方面的结构要清楚。

结论:

1.常量与常量的拼接结果在常量池.且常量池中不会存在相同内容的常量 。
2.只要其中有一个是变量 结果就在堆中.
3.如果拼接的结果调用 intern() 方,返回值就在常量池中。

/*
    结论:
    1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量 。
    2.只要其中有一个是变量结果就在堆中
    3.如果拼接的结果调用 intern(),返回值就在常量池中
     */

@Test
public void test4(){
  String s1 = "javaEEhadoop";
  String s2 = "javaEE";
  String s3 = s2 + "hadoop";
  System.out.println(s1 == s3); //false

  final String s4 = "javaEE"; //s4是常量
  String s5 = s4 + "hadoop"; //常量与常量拼接还是常量
  System.out.println(s1 == s5)//true  

}
@Test public void test3(){ String s1 = "javaEE"; String s2 = "hadoop"; String s3 = "javaEEhadoop"; String s4 = "javaEE" + "hadoop"; //常量与常量拼接还在常量池 String s5 = s1 + "hadoop"; //有变量参与相当于new ,在堆空间中 String s6 = "javaEE" + s2; String s7 = s1 +s2; System.out.println(s3 == s4); //t System.out.println(s3 == s5); //f System.out.println(s3 == s6); //false System.out.println(s5 == s6); //false System.out.println(s5 == s7); //false System.out.println(s6 == s7); //false String s8 = s5.intern(); //返回值得到的s8使用的常量池中已经存在的“javaEEhadoop” System.out.println(s3 == s8); //true }

 

一道面试题:

/**
 * 一道面试题
 * @author ldbstart
 * @create 2021-03-06 23:49
 */
public class StringTest {
  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) {
        StringTest ex = new StringTest();
        ex.change(ex.str,ex.ch);
        System.out.println(ex.str); //"good"
        System.out.println(ex.ch); //best
    }
}

 

JVM中涉及到字符串的内存结构

三种JVM

Sun公司的HotSpot(默认的。不用说)

BEA公司的JRockit

IBM公司的J9 VM

 

 String常用类:

int length() 返回字符串的长度: return value length
char charAt(int index) 返回某索引处的字符 return value[index
boolean isEmpty() 判断是否是空字符串: return value length 0
String toLowerCase() 使用默认语言环境 将 String 中的所有字符转换为小写
String toUpperCase() 使用默认语言环境 将 String 中的所有字符转换为大写
String trim() 返回字符串的副本 忽略前导空白和尾部 空白
boolean equals(Object obj) 比较字符串的 内容 是否相同
boolean equalsIgnoreCase(String anotherString) 与 equals 方法类似 忽略大小写
String concat(String str) 将指定字符串连接到此字符串的结尾 。 等价于用
int compareTo(String anotherString) 比较两个字符串的 大小
String substring(int beginIndex) 返回一个新的字符串 它是此字符串的从
beginIndex 开始截取到最后的一个子字符串 。
String substring(int beginIndex, int endIndex) 返回一个新字符串 它是此字符串从 beginIndex 开始截取到 endIndex( 不包含 的一个子字符串 。

public class StringMethodTest {

    @Test
    public void test(){
        String s1 = "HelloWrold";
        System.out.println(s1.length());
        System.out.println(s1.charAt(0));
        System.out.println(s1.charAt(9));
        System.out.println(s1.isEmpty());

        String s2 = s1.toLowerCase(); //s1是不可变的,仍然是原来的字符串
        System.out.println(s1);
        System.out.println(s2);

        String s3 = "  he  llo World  ";
        String s5 = s3.concat("abc");
        System.out.println(s5);
        String s4 = s3.trim();
        System.out.println("-----"+s3+"-----");
        System.out.println("-----"+s4+"-----");

        String s6 = "abc";
        String s7 = "abd";
        System.out.println(s6.compareTo(s7)); //涉及到字符串的排序

        String s8 = "北京尚硅谷教育";
        String s9 = s8.substring(2);
        System.out.println(s9);

        s7.substring(2,5);


    }

}

 

boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结束
boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开始
boolean startsWith(String prefix, int toffset) 测试此字符串从指定索引开始的子字符串是否以指定前缀开始
boolean contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true
int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的 索引
int indexOf(String str, int fromIndex) 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引 开始
int lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的 索引
int lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向 搜索
注:
indexOf 和 lastIndexOf 方法如果未找到都是返回 1

@Test
    public void test3(){
        String str1 = "helloworld";
        boolean b1 = str1.endsWith("ld");
        System.out.println(b1);

        boolean b2 = str1.startsWith("he");
        System.out.println(b2);

        //boolean contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true
        boolean b3 = str1.contains("wor");
        System.out.println(b3);

        int b4 = str1.indexOf("lol");
        System.out.println(b4);

        System.out.println(str1.indexOf("lo",5));

        String str2 = "helorworld";
        System.out.println(str2.lastIndexOf("or"));
        
        //什么情况下,indexOf(str)和lastIndexOf(str)返回值相同?
        //情况一:存在唯一的str(只有一个字符)   情况二:不存在str
    }

 

替换:
String replace(char oldChar, char newChar) 返回 一个新的字符串 它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的 。
String replace(CharSequence target, CharSequence replacement) 使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串 。
String replaceAll(String regex, String replacement) 使用 给定的replacement 替换此字符串所有匹配给定的正则表达式的子字符串 。
String replaceFirst(String regex, String replacement) 使用 给定的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串 。

涉及到正则表达式:

匹配:
boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式 。

切片:
String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串 。
String[] split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串 最多不超过 limit 个 如果超过了 剩下的全部都放到最后一个元素中

 

涉及到String类与其它结构之间的转换

复习::

String 与基本数据类型、包装类之间的转换。

String ---> 基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)

基本数据类型 ---> String:调用String重载的valueOf(xxx)

============奥里给=================

String 与 char[ ]之间的转换

String ---> char[ ] :调用String的toCharArray()

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

@Test
    public void test5(){
        String str = "abc";
        char[] charArray = str.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            System.out.println(charArray[i]); //a    b    c
        }

        char[] chars = {'h', 'e', 'l', 'l', 'o'};
        String str2 = new String(chars);
        System.out.println(str2); //hello
    }

 

String 与 byte[ ]之间的转换

String byte[]
编码:String ---> byte[]:调用String的getBytes()
解码:byte[] ---> String:

编码:字符串----> 字节【看得懂的 -----> 看不懂的】
解码:编码的逆过程

说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致

@Test
    public void test6() throws UnsupportedEncodingException {
        String str1 = "abc123中国";
        byte[] bytes = str1.getBytes(); //使用默认的字符集(一般是utf-8)进行转换
        System.out.println(Arrays.toString(bytes));


            byte[] gbks = str1.getBytes("gbk"); //使用gbk字符集进行编码
            System.out.println(Arrays.toString(gbks));

        System.out.println("****************************");

        String str2 = new String(bytes);//使用默认的字符集,进行解码
        System.out.println(str2); //abc123中国
        String str3 = new String(gbks);
        System.out.println(str3); //abc123�й� 原因:编码UTF-8,解码gbk,所以乱码

        String str4 = new String(gbks, "gbk");
        System.out.println(str4);

    }

 

String 常见算法题:字符串、数组

1.模拟一个trim方法,去除字符串两端的空格

2.将一个字符串进行反转。将字符串中指定部分进行 反转 。比如 abcdefg 反转为 abfedcg

 

3.获取一个字符串在另一个字符串中出现的次数。

比如:获取“ ab 在 abkkcadkabkebfkabkskab ”中出现的次数

 

4.获取两个字符串中最大相同子串。比如:str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"

提示:将短的那个串进行长度依次递减的子串与较长的串比较。

 

5. 对字符串 中字符 进行自然顺序排序 。

提示:

字符串变成字符数组。

对数组排序,选择,冒泡 Arrays.sort

将排序后的数组变成字符串。

 

StringBuffer和StringBuilder的使用

 

面试题:String、StringBuffer、StringBuilder三者的异同?
String、StringBuffer、StringBuilder三者的异同?
String:不可变的字符序列;底层使用char[]存储;
StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储;
StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全,效率高;底层使用char[]存储;

源码分析:
String str = new String(); //底层 :char[] value = new char[0]
String str1 = new String("abc"); //char[] value = new char[]{'a','b','c'};

StringBuffer sb1 = new StringBuffer(); //char[] value = new char[16];底层创建了一个长度是16的数组
sb1.append('a'); //value[0] = 'a';
sb1.append('b'); //value[1] = 'b'; //往sb1中添加数据而不是重新创建,sb1不变,所以StringBuffer才是可变的

StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];

//问题一System.out.println(sb2.length()); //3
问题二:扩容问题(StringBuffer、StringBuilder相同),如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
默认情况下扩容为原来情况的2倍+2【int newCapacity = (value.length << 1) + 2;】,同时将原有数组中
的元素复制到新的数组中。

指导意义:开发中建议大家使用StringBuffer(int capacity) 或者 StringBuilder(int capacity),避免扩容
和复制,效率高一些

 

StringBuffer类的常用方法

StringBuffer的常用方法:【StringBuilder方法一样,】
StringBuffer append ( xxx):提供了很多的 append() 方法 用于进行字符串拼接
StringBuffer delete (int start,int end)end):删除指定位置的内容
StringBuffer replace (int start, int end, String str)str):把 [start, 位置替换为 str
StringBuffer insert (int offset, xxx)xxx):在指定位置插入 xxx
StringBuffer reverse ():把当前字符序列逆转

public int indexOf (String)
public String substring (int start,int end)
public int length
public charcharAt (int n)
public voidsetCharAt (int n ,char)

/*
    StringBuffer的常用方法:【StringBuilder方法一样,StringBuffer同步,StringBuilder不同步】
    StringBuffer append ( xxx):提供了很多的 append() 方法 用于进行字符串拼接
    StringBuffer delete (int start,int end):删除指定位置的内容
    StringBuffer replace (int start, int end, String str)str):把 [start, 位置替换为 str
    StringBuffer insert (int offset, xxx):在指定位置插入 xxx
    StringBuffer reverse ():把当前字符序列逆转

    public int indexOf (String)
    public String substring (int start,int end):返回一个从start开始,到end结束的左闭右开的字符串,需要接收返回值
    public int length
    public char charAt (int n)
    public void setCharAt (int n ,char):将指定位置的字符改为新的

    总结:
    增:append(xxx)
    删:delete(int start, int end)
    改:replace (int start, int end, String str) / setCharAt (int n ,char)
    查:charAt (int n)
    插:insert (int offset, xxx)
    长度:length
    *遍历:for() + charAt() / toString()


     */
    @Test
    public void test2(){

        StringBuffer sb1 = new StringBuffer("abc");
        sb1.append(1);
        sb1.append("1");
        System.out.println(sb1);
        //sb1.delete(2,4);
        //sb1.replace(2,4,"hello"); //abhello1
        //sb1.insert(2,false);//abfalsec11
        //sb1.reverse();//11cba

        String sb2 = sb1.substring(1, 3);
        System.out.println(sb1);
        System.out.println(sb2);
    }

三者效率的对比:

@Test
    public void test3(){
        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));
    }

StringBuffer的执行时间:9
StringBuilder 的执行时间:3
String 的执行时间:1187

效率从高到低:StringBuilder > StringBuffer > String

二、JDK8之前的日期时间API

1.System类中的currentTimeMillis( );

2.java.util.Date 和 java.sql.Date

java.util.Date类
|---java.sql.Date类

1.两个构造器的使用
>构造器一:Date():创建了一个对应当前时间的Date对象
>构造器二:创建指定毫秒数的Date对象
2.两个方法的使用
>toString();显示当前的年月日时分秒
>getTime():获取当前Date对象对应的时间戳

3.java.sql.Date对应数据库中的日期类型的变量
>如何实例化
>java.sql.Date ---->如何转化 java.util.Date
 @Test
    public void test2(){
        //构造器一:Date():创建了一个对应当前时间的Date对象
        Date date1 = new Date();
        System.out.println(date1); //Mon Mar 08 13:09:24 CST 2021

        System.out.println(date1.getTime()); //1615179651635


        //构造器二:创建指定毫秒数的Date对象
        Date date2 = new Date(1615179651635L);
        System.out.println(date2.toString());

        //创建java.sql.Date对象
        java.sql.Date date3 = new java.sql.Date(35235325345L);
        System.out.println(date3.toString()); //1971-02-13

        //如何将java.util.Date对象转换为java.sql.Date对象
        //情况一:
//        java.util.Date date4 = new java.util.Date(2343243242323L);
//        java.sql.Date date5 = (java.sql.Date) date4;//硬转的化运行会报错

        //情况二:
        java.util.Date date6 = new java.util.Date(); //要想把util下的时间塞到数据库中
        java.sql.Date date7 = new java.sql.Date(date6.getTime()); //毫秒数是共通的

    }

    //1.System类提供的currentTimeMillis()
    @Test
    public void test1(){
        long time = System.currentTimeMillis();
        //返回距离1970年1月1日0时0分0秒到现在的毫秒数
        //时间戳
        System.out.println(time);
    }

 3.SimpleDateFormat

SimpleDateFormat的使用:SimpleDateFormat对日期Date类的格式化和解析

1.两个操作:

1.1格式化:日期 ----> 字符串

1.2解析:格式化的逆过程,字符串 ---> 日期

2.SimpleDateFormat的实例化

 @Test
    public void testSimpleDateFormat() throws ParseException {
        //实例化SimpleDateFormat:使用默认的构造器
        SimpleDateFormat sdf = new SimpleDateFormat();

        //格式化:日期 ---> 字符串
        Date date = new Date();
       System.out.println(date); //Mon Mar 08 16:20:39 CST 2021

        String format = sdf.format(date);
        System.out.println(format); //21-3-8 下午4:20

        //解析:格式化的逆过程, 字符串 ---> 日期
        String str = "20-3-8 下午4:23";
            Date date1 = sdf.parse(str);
            System.out.println(date1);


        System.out.println("*******************************");

        //按照指定的方式格式化和解析:调用带参的构造器

        //SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        //格式化
        String format1 = sdf1.format(date);
        System.out.println(format1);
        //解析:要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器体现)
        Date date2 = sdf1.parse("2019-02-18 11:48:27");
        System.out.println(date2);
    }

 

练习一需要掌握哦:字符串"2019-09-08"转换为java.sql.Date

 @Test
    public void testExer() throws ParseException {
        String birth = "2020-08-08";

        //解析
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf1.parse(birth);
        //System.out.println(date); //这里还是util下的Date

        java.sql.Date birthDate = new java.sql.Date(date.getTime()); //传入毫秒数
        System.out.println(birthDate); //2020-08-08
    }

 

练习二:“三天打鱼两天晒网” 1990-01-01开始,问xxxx-xx-xx 是在打鱼?晒网?

举例:2020-09-08这一天是在打鱼还是在晒网?

总天数的计算?

总天数 % 5 == 1,2,3打鱼

总天数 % 5 == 4,0晒网

天数,

方式一:date2.getTime() - date1.getTime()  / (1000 * 60 *60 24)+ 1  //注意整数除以整数,可能除不尽

方式二:1990-01-01 距离2019-12-31 多少天,几个闰年加几,+ 2020-01-01 到2020-09-08这一天是当年的多少天

 

4.Calendar

java.util.Calendar

 /*
    Calendar日历类的使用
     */

    @Test
    public void testCalendar(){
        //1.实例化
        //方式一:创建其子类(GregorianCalendar)的对象
        //方式二:调用其静态方法getInstance() 【其实方式一和二是一样的】
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar.getClass());//java.util.GregorianCalendar

        //2.常用方法:
        //get():获取一些常用的属性信息
        int days = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(days);
        System.out.println(calendar.get(Calendar.DAY_OF_YEAR)); //今天是今年的第几天

        //set()
        calendar.set(Calendar.DAY_OF_MONTH,22);
        days = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(days);

        //add():【注意减去3天的话是-3】
        calendar.add(Calendar.DAY_OF_MONTH,3);
        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);
        days = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(days);
    }

注意:

获取月份时:一月是0,二月是1,三月是2,以此类推,12月是11

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

三、JDK8中的新日期时间API

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

可变性:像日期和时间这样的类应该是不可变的。
偏移性:Date 中的年份是从 1900 开始的,而月份都从 0 开始。
格式化:格式化只对Date 有用, Calendar 则不行。
此外,它们也不是线程安全的;不能处理闰秒等。

 

第三次引入的 API 是成功的, 并且 Java 8 中引入的 java.time API 已经纠正了过去的缺陷,将来很长一段时间内它都会为我们服务。

Java 8 吸收了 Joda Time 的精华,以一个新的开始为 Java 创建优秀的 API 。新的 java.time 中包含了所有关于 本地日期( LocalDate )、本地时间(LocalTime )、本地日期时间 LocalDateTime )、时区 ZonedDateTime和持续时间( Duration )的类 。历史悠久的 Date 类新增了 toInstant() 方法,用于把 Date 转换成新的表示形式。这些新增的本地化时间日期 API 大大简化了日期时间和本地化的管理。

java.time包含值对象的基础包
java.time.chrono提供对不同的日历系统的访问
java.time.format格式化和解析时间和日期
java.time.temporal包括底层框架和扩展特性
java.time.zone包含时区支持的类

 

LocalDate 、 LocalTime 、 LocalDateTime 类是其中较重要的几个类,它们的实例是不可变的对象 ,分别表示使用 ISO 8601 日历系统的日期、时间、日期和时间。它们提供了简单 的本地日期 或时间,并不包含当前的时间 信息,也 不包含与时区相关的信息 。

LocalDate 代表 IOS 格式( yyyy MM dd )的日期 可以存储 生日、纪念日等日期。
LocalTime 表示一个时间,而不是 日期 。
LocalDateTime 是用来表示日期和时间的, 这是一个最常用的类之一 。

 

 /*
    LocalDate 、 LocalTime 、 LocalDateTime
    说明:
    1.LocalDateTime相较于其他两个类用的多一些。
    2.类似于Calendar
     */

    @Test
    public void test(){
        //now()获取当前的日期、时间、日期+时间
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.now();

        System.out.println(localDate);
        System.out.println(localTime);
        System.out.println(localDateTime);

        //of():设置指定的年月日时分秒。没有偏移量
        LocalDateTime localDateTime1 = LocalDateTime.of(2020, 10, 06, 21, 8, 56);
        System.out.println(localDateTime1);

        //getXxx()获取相关的属性
        System.out.println(localDateTime.getDayOfYear());
        System.out.println(localDateTime.getDayOfMonth());
        System.out.println(localDateTime.getDayOfWeek());
        System.out.println(localDateTime.getMonth());
        System.out.println(localDateTime.getMonthValue());
        System.out.println(localDateTime.getMinute());

        //withXxx()设置相关的属性
        //体现不可变性,修改该以后返回值是修改过的,原来的值还是不变
        LocalDate localDate1 = localDate.withDayOfMonth(22);
        System.out.println(localDate);
        System.out.println(localDate1);

        LocalDateTime localDateTime2 = localDateTime.withHour(4);
        System.out.println(localDateTime);
        System.out.println(localDateTime2);

        //添加
        LocalDateTime localDateTime3 = localDateTime.plusMonths(3);
        System.out.println(localDateTime);
        System.out.println(localDateTime3);//增加3个月

        //减少
        LocalDateTime localDateTime4 = localDateTime.minusDays(6);
        System.out.println(localDateTime); //原来的不变
        System.out.println(localDateTime4); //减少6天


    }

 

瞬时:Instant

 

 

/*
    Instant的使用:
    类似于 java.util.Date类
     */
    @Test
    public void test2(){
        //now()获取本初子午线对应的标准时间
        Instant instant = Instant.now();
        System.out.println(instant); //2021-03-08T13:26:04.893Z

        //添加时间的偏移量 【北京时间东八区,+8】
        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime);

        //toEpochMilli():获取距离1970年1月1日0时0分0秒对应的毫秒数   类似于  Date类中getTime()
        long milli = instant.toEpochMilli();
        System.out.println(milli);

        //ofEpochMilli():通过给定的毫秒数,获取Instant实例  类似于   Date(long millis)
        Instant instant1 = Instant.ofEpochMilli(1615210315916L);
        System.out.println(instant1);
    }

 

java.time.format.DateTimeFormatter类:用来格式化或者解析日期、时间

类似于SimpleDateFormat

@Test
    public void test3(){

//        方式一:预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
        //格式化:日期 ----> 字符串
        LocalDateTime localDateTime = LocalDateTime.now();
        String str1 = formatter.format(localDateTime);
        System.out.println(localDateTime);//2021-03-08T21:45:41.420
        System.out.println(str1);//2021-03-08T21:45:41.42

        //解析:字符串 ----> 日期
        TemporalAccessor parse = formatter.parse("2021-03-08T21:45:41.420");
        System.out.println(parse);

//        方式二:本地化相关的格式。如: ofLocalizedDateTime()
          //FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT:适用与LocalDateTime //三者格式上不太一样
        DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
        //格式化
        String str2 = formatter1.format(localDateTime);
        System.out.println(str2);

        //本地化相关的格式。如:ofLocallizeDate()
          //FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDate
        DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
        //格式化
        String str3 = formatter2.format(LocalDate.now());
        System.out.println(str3);

//        重点掌握:方式三:自定义的格式。如: ofPattern(“yyyy MM dd hh:mm:ss”)
        DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        //格式化
        String str4 = formatter3.format(LocalDateTime.now());
        System.out.println(str4); //2021-03-08 10:01:21
        //解析
        TemporalAccessor accessor = formatter3.parse("2021-03-08 10:01:21");//注意格式对应
        System.out.println(accessor);

    }

 

其他API:

 

 

 

 

 

四、Java比较器(重要)

一、说明:Java中的对象,正常情况下,只能进行比较:== 或  != 。不能使用 > 或 < ,但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。如何实现?使用两个接口中的任意一个:Comparable 、Comparator

二、自然排序:Comparable接口的使用  ,自定义一个类,实现Comparable接口【拿调这个方法的对象和形参去比大小】

* 1.像String、包装类、日期等实现了Comparable接口,重写了compareTo()方法,给出了比较两个对象大小的方式
* 2.像String、包装类重写compareTo()方法以后,进行了从小到大的排序
* 3.重写compareTo(obj)的规则:
* 如果当前对象 this 大于形参对象 obj 则返回正整数,
* 如果当前对象 this 小于 形参对象 obj 则返回负整数,
* 如果当前对象 this 等于 形参对象 obj 则返回零

4.对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写comparableTo(),在comparableTo(obj)中指明如何排序

public class Goods implements Comparable{
    private String name;
    private double price;

    public Goods() {
    }

    public Goods(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    //指明商品比较大小的方式:按照价格从低到高排序
    @Override
    public int compareTo(Object o) {
        System.out.println("***");
        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 this.name.compareTo(goods.name);
         }
         //方式二:
           // return Double.compare(this.price,goods.price);
        }
        throw new RuntimeException("传入的数据类型不一致");
    }
}

 

三、Comparator接口的使用:【临时用的】 定制排序
* 1.背景:
* 当元素的类型没有实现 java.lang.Comparable 接口而又不方便修改代码,
* 或者实现了 java.lang.Comparable 接口的排序规则不适合当前的操作,那
* 么可以考虑使用 Comparator 的对象来排序强行对多个对象进行整体排序的比较。
* 2.重写compare(Object o1, Object o2) 【形参两个对象比较大小】
* 如果返回正数,则表示o1 大于 o2;
* 如果返回0,表示相等;
* 如果返回负数,o1 小于 o2。

 

 

四、Comparable接口和Comparator接口的使用对比:

Comparable接口的方式一旦确定,保证Comparable接口实现类的对象在任何位置都可以比较大小

Comparator接口属于临时性比较。

 

五、System类

 

六、Math类

七、BigInteger与BigDecimal

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

一般的 Float 类和 Double 类可以用来做科学计算或工程计算,但在 商业计算中,要求数字精度比较高,故用到 java.math.BigDecimal 类 。

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

posted @ 2021-03-07 00:07  我tm爱死java了  阅读(93)  评论(0编辑  收藏  举报