Java学习——Day09:常用类

2.1 字符串相关的类:String

public final class String implements java.io.Serializable,Comparable<String>,CharSequence{
    
    private final char value[];//字符串,底层储存原理,常量,体现了String的不可变性
    
    private int hash;//
}

2.1.1 String的不可变性

package study.javaSenior.commonlyClass;

import org.junit.Test;

/**
 * String的使用
 * @author zhengxu
 * @create 2021-05-31 14:03
 */
public class StringTest {
    /*
    String:字符串,使用一对“”引起来表示
    1.String声明为final类,不可被继承。
    2.String实现了Serializable接口:表示字符串是支持序列化的。
            实现了Comparable接口:表示字符串可以比较大小
    3.String内部定义了final char[] value用于存储字符串数据,长度和内容不可以改变,据此理解4
    4.String:代表不可变的字符序列。简称:不可变性。
         体现:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value赋值。
              2.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有value赋值
              3.当调用String的replace()方法修改指定的字符或者字符串时,也必须重新指定内存区域赋值
    5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
    6.字符串常量池中是不会存储相同内容的字符串的
     */
    @Test
    public void test1(){
        String s1="abc";//字面量定义方式
        String s2="abc";//s1和s2指向同一个地址值

        System.out.println(s1==s2);//比较s1和s2的地址值,true

        s1="hello";//新造hello表示s1地址指向新的hello地址,不影响s2
        System.out.println(s1);//hello
        System.out.println(s2);//abc

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

        String s3="abc";
        s3+="def";//不能在原有abc位置上改变s3的值,而是新造一个地址存放s3的abcdef值
        System.out.println(s3);//abcdef

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

        String s4="abc";
        String s5=s4.replace('a','m');
        System.out.println(s4);//abc
        System.out.println(s5);//mbc
    }
}

2.1.2 String对象的创建

package study.javaSenior.commonlyClass;

import org.junit.Test;

/**
 * String的使用
 * @author zhengxu
 * @create 2021-05-31 14:03
 */
public class StringTest {
       /*
    String的实例化方式:
    方式一:通过字面量定义的方式
    方式二:通过new+构造器的方式
    
    面试题:String s=new String("abc");方式创建对象,在内存中创建了几个对象
    答:创建了两个,一个是堆空间中new结构创建的对象,另一个是char[]对应的常量池中的数据:"abc"
     */
    @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

        Person p1=new Person(10,"Tom");
        Person p2=new Person(10,"Tom");

        System.out.println(p1.name.equals(p2.name));//true,string重写了equals,只比较属性,不比较地址
        System.out.println(p1.name==p2.name);//true

        p1.name="Jerry";
        System.out.println(p1.name==p2.name);//false
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rq9rzagB-1623410126377)(C:\Users\zhengxu\AppData\Roaming\Typora\typora-user-images\image-20210531155817786.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bQ0AuFEB-1623410126381)(C:\Users\zhengxu\AppData\Roaming\Typora\typora-user-images\image-20210531164219054.png)]

2.1.3 String不同拼接操作的对比

package study.javaSenior.commonlyClass;

import org.junit.Test;

/**
 * String的使用
 * @author zhengxu
 * @create 2021-05-31 14:03
 */
public class StringTest {
    /*
        1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
        2.只要其中有一个是变量,结果就在堆中。
        3.如果拼接的结果调用intern()方法,返回值就在常量池中。
     */
    @Test
    public void test3(){
        String s1="javaEE";
        String s2="hadoop";

        String s3="javaEEhadoop";
        String s4="javaEE"+"hadoop";
        String s5=s1+"hadoop";
        String s6="javaEE"+s2;
        String s7=s1+s2;

        System.out.println(s3==s4);//true
        System.out.println(s3==s5);//false
        System.out.println(s3==s6);//false
        System.out.println(s3==s7);//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
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OAXlbcaR-1623410126382)(C:\Users\zhengxu\AppData\Roaming\Typora\typora-user-images\image-20210531170204340.png)]

面试题

package study.javaSenior.commonlyClass;

/**
 * 面试题
 * @author zhengxu
 * @create 2021-06-04 16:38
 */
public class faceTest {
    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) {
        faceTest ex=new faceTest();
        ex.change(ex.str,ex.ch);
        System.out.println(ex.str);//good
        System.out.println(ex.ch);//best
    }
}

2.1.4 String常用方法

  • int length():返回字符串的长度:return value.length

  • char charAt(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 anotherStrig):比较两个字符串的大小,ACSII值,涉及到排序

  • String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串

  • String substring(int beginIndex,int endIndex):返回一个新的字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串

  • 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

  • String replace(char oldChar,char newChar):返回一个新的字符串,它是通过用newChar替换此字符串中出现的所有oldChar得到的。
  • String replace(CharSequence tarage,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个,如果超过了,剩下的全部放到最后一个元素中

2.1.5 String与基本数据类型转换

package study.javaSenior.commonlyClass.string;

import org.junit.Test;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * 涉及到String类和其他结构之间的转换
 * @author zhengxu
 * @create 2021-06-07 9:28
 */
public class stringTest01 {
    /*
    String与基本数据类型、包装类之间的转换:
    1.String——>基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)
    2.基本数据类型、包装类——>String:调用String重载的valueOf(xxx)
     */
    @Test
    public void test01(){
        String str1="123";
        //int num=(int)str1;//错误的
        int num=Integer.parseInt(str1);//123

        String str2=String.valueOf(num);//"123"
    }

    /*
    String与char[]之间的转换:
    1.String——>char[]:调用String的toCharArray()
    2.char[]——>String:调用String的构造器
     */
    @Test
    public void test02(){
        String str1="abc123";

        char[] charArray=str1.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            System.out.println(charArray[i]);
        }

        char[] arr=new char[]{'a','c','d'};
        String str2 = new String(arr);
        System.out.println(str2);
    }

    /*
    String与byte[]之间的转换:
    1.编码:String——>byte[]:调用String的getBytes()
    2.解码:byte[]——>String:调用String构造器
    
    说明:解码时使用的字符集必须和编码时使用的字符集一致,不然会出现乱码
     */
    @Test
    public void test03() 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");//使用gdk字符集编码,一个汉字两个字节(中国设定,只有汉字)
        System.out.println(Arrays.toString(gbks));//[97, 98, 99, 49, 50, 51, -42, -48, -71, -6]

        String str2 = new String(bytes);//使用默认字符集进行解码
        System.out.println(str2);//abc123中国

        String str3 = new String(gbks);
        System.out.println(str3);//abc123�й�,乱码,解码使用的字符集不对应,可以用gbk解码

        String str4 = new String(gbks, "gbk");//使用gbk解码
        System.out.println(str4);//abc123中国,没有出现乱码
    }
}

2.2 字符串相关的类StringBuffer和StringBuilder

2.2.1 三者异同

package study.javaSenior.commonlyClass.stringBufferAndBuilder;

import org.junit.Test;

/**
 * 关于StringBuffer和StringBuilder的使用
 * @author zhengxu
 * @create 2021-06-07 10:09
 */
public class Test01 {
    /*
    String、StringBuffer、StringBuilder三者异同:
    1.String:不可变的的字符序列;底层结构使用char[]存储,加了final所以不可变
    2.StringBuffer:可变的字符序列;线程安全的,效率低;底层结构使用char[]存储,没加final
    3.StringBuilder:可变的字符序列;线程不安全,效率高;jdk5.0新增,底层结构使用char[]存储,没加final

    使用选择:非多线程时用StringBuilder,否则用StringBuffer

    底层源码分析:
    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';
    StringBuffer sb2=new StringBuffer("abc")//char[] value = new char["abc".length()+16];

    //问题1:System.out.println(sb2.length());//3,  value.length()才是16
    //问题2:扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩展底层数组。
            默认情况下,扩容为原来的2倍+2,同时将原有数组复制到新的数组中。
            
            指导意义:在开发过程中建议大家使用:StringBuffer(int capacity)或StringBuilder(int capacity),构造一个一定长度的数组

     */

    @Test
    public void test01(){
        StringBuffer sb1=new StringBuffer("abc");
        sb1.setCharAt(0,'m');
        System.out.println(sb1);//mbc,不像string那样依然是abc,不可变

        StringBuffer sb2=new StringBuffer();
        System.out.println(sb2.length());//长度为0
    }
}

2.2.2 常用方法

常用方法:

package study.javaSenior.commonlyClass.stringBufferAndBuilder;

import org.junit.Test;

/**
 * StringBuffer类常用方法
 * 1.StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
 * 2.StringBuffer delete(int start,int end):删除指定位置内容
 * 3.StringBuffer replace(int start,int end, String str):将[start,end)位置替换为str
 * 4.StringBuffer insert(int offset,xxx):在指定位置插入xxx
 * 5.StringBuffer reverse():把当前字符序列逆转
 * 6.public int indexOf(String str):返回str字符串首次出现的位置
 * 7.public String substring(int start,int end):返回一个从start开始到end结束的左闭右开的子字符串
 * 8.public int length
 * 9.public char charAt(int n)
 * 10.public void setCharAt(int n,char ch):将位置n的字符改为ch
 * 
 * 总结:
 *  增:append(xxx)
 *  删:delete(int start,int end)
 *  改:setChar(int n,char ch)  /  replace(int start,int end, String str)
 *  查:charAt(int n)
 *  插:insert(int offset,xxx)
 *  长度:length();
 *  遍历:for+charAt()  /   toString
 * @author zhengxu
 * @create 2021-06-07 12:05
 */
public class test02 {
    @Test
    public void test1(){
        StringBuffer sb1=new StringBuffer("abc");
        sb1.append(1);
        sb1.append('1');
        System.out.println(sb1);//abc11

        sb1.delete(2,4);
        System.out.println(sb1);//ab1,左闭右开
        sb1.replace(1,2,"hello");
        System.out.println(sb1);//ahello1
        sb1.insert(0,"A");
        System.out.println(sb1);//Aahello1
        sb1.reverse();
        System.out.println(sb1);//1ollehaA
    }
}

2.2.3 练习题

package study.javaSenior.commonlyClass.string;

import org.junit.Test;

/**
 * String课后算法题目1:
 * 将一个字符串反转。将一个字符串中指定的部分进行反转,比如“abcdefg”反转为“abfedcg”
 * @author zhengxu
 * @create 2021-06-09 17:33
 */
public class exercise01 {
    //方式一:转换为char[]
    public String reverse(String str,int startIndex,int endIndex){
        if(str!=null) {
            char[] arr = str.toCharArray();
            for (int x = startIndex, y = endIndex; x < y; x++, y--) {
                char temp = arr[x];
                arr[x] = arr[y];
                arr[y] = temp;
            }
            return new String(arr);
        }
        return null;
    }

    //方式二:使用String的拼接
    public String reverse1(String str,int startIndex,int endIndex){
        if(str!=null){
          String str1=str.substring(0,startIndex);
          for(int i=endIndex;i>=startIndex;i--){
              str1+=str.charAt(i);
          }
          str1+=str.substring(endIndex+1);
          return str1;
        }
        return null;
    }

    //方式三:使用StringBuffer/StringBuilder替换String
    public  String reverse2(String str,int startIndex,int endIndex){
        if(str!=null){
            StringBuilder builder=new StringBuilder(str.length());
            builder.append(str.substring(0,startIndex));
            for(int i=endIndex;i>=startIndex;i--){
                builder.append(str.charAt(i));
            }
            builder.append(str.substring(endIndex+1));
            
            return builder.toString();
        }
        return null;
    }

    @Test
    public void testReverse(){
        String str="abcdefg";
        String reverse=reverse2(str,2,5);
        System.out.println(reverse);//abfedcg
    }
}
package study.javaSenior.commonlyClass.string;

import org.junit.Test;

/**
 * String课后算法题目2:
 * 获取一个字符串在另外一个字符串中出现的次数,比如“ab”在“abddabiiabnnabdd”
 * @author zhengxu
 * @create 2021-06-09 18:03
 */
public class exercise02 {

    public int getCount(String mainStr,String subStr){
        int mainLength=mainStr.length();
        int subLength=subStr.length();
        int count=0;
        int index=0;
            if (mainLength >= subLength) {
                //方式一:
//                while ((index = mainStr.indexOf(subStr)) != -1) {
//                    count++;
//                    mainStr = mainStr.substring(index + subStr.length());
//                }
                //方式二:对方式一的改进
                while ((index=mainStr.indexOf(subStr,index))!=-1){
                    count++;
                    index+=subLength;
                }
                return count;
            }else {
                return 0;
            }
    }

    @Test
    public void testGetCount(){
        String mainStr="abddabiiabnnabdd";
        String substr="ab";
        System.out.println(getCount(mainStr,substr));
    }
}
package study.javaSenior.commonlyClass.string;

import org.junit.Test;

/**
 * String课后算法题目3:
 * 获取两个字符串中最大相同子串。
 * 例如:石头人str1=“abcwerthelloyuiodef";str2="cvhellobnm"
 * @author zhengxu
 * @create 2021-06-09 21:16
 */
public class exercise03 {

    //前提:两个字符串中只有一个最大相同字串
    public String getMaxSameString(String str1,String str2){
        if(str1!=null&&str2!=null) {
            String maxStr = (str1.length() >= str2.length()) ? str1 : str2;
            String minStr = (str1.length() < str2.length()) ? str1 : str2;
            int length = minStr.length();
            for (int i = 0; i < length; i++) {
                for (int x = 0, y = length - i; y <= length; x++, y++) {
                    String subStr = minStr.substring(x, y);
                    if (maxStr.contains(subStr)) {
                        return subStr;
                    }
                }
            }
        }
        return null;
    }

    @Test
    public void testGetMaxSameStr(){
        System.out.println(getMaxSameString("abcwerthelloyuiodef","cvhellobnm"));
    }
}

2.3 Date类

2.3.1 JDK8之前的时间API

2.3.1.1 java.lang.System类
/*
jdk8之前的的时间API:System类中的currentTimeMillis();
System类提供的public static long currentTimeMillis()用来返回当前时
间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
*/
2.3.1.2 java.util.Date类和java.sql.Date类
package study.javaSenior.commonlyClass.date;

import org.junit.Test;

import java.util.Date;

/**
 * date类
 * @author zhengxu
 * @create 2021-06-07 16:41
 */
public class dateTest {
    /*
    java.util.Date类
            |————java.sql.Date类

    1.两个构造器的使用
      >构造器一:Date():创建了一个对应当前时间的Date对象
      >构造器二:创建指定毫秒数的Date对象

    2.两个方法的使用
      >tostring():显示当前的年、月、日、时、分、秒
      >getTime():获取当前Date对象对应的毫秒数。(时间戳)

    3.java.sql.Date对应着数据库中的日期类型的变量
      >如何实例化
      >如何将java.util.Date对象转化为java.sql.Date对象
     */
    @Test
    public void test01() {
        //构造器一:Date():创建了一个对应当前时间的Date对象
        Date date1 = new Date();
        System.out.println(date1.toString());//Mon Jun 07 16:44:48 CST 2021
        System.out.println(date1.getTime());//1623055574212距离1970年的毫秒数

        //构造器二:创建指定毫秒数的Date对象
        Date date2 = new Date(1623055574212L);
        System.out.println(date2.toString());//Mon Jun 07 16:46:14 CST 2021

        //创建java.util.Date对象
        java.sql.Date date3 = new java.sql.Date(323442342342L);
        System.out.println(date3);//1980-04-01

        //如何将java.util.Date对象转化为java.sql.Date对象
        //情况一:
//        Date date4=new java.sql.Date(87675865668567L);
//        java.sql.Date date5=(java.sql.Date)date4;
        //情况二:
        Date date6=new Date();
        java.sql.Date date7=new java.sql.Date(date6.getTime());
    }
}
2.3.1.3 java.text.SimpleDateFormat类
package study.javaSenior.commonlyClass.date;

import org.junit.Test;

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

/**
 * simpleDateFormat测试
 * @author zhengxu
 * @create 2021-06-11 9:25
 */
public class dataTest03 {
    /*
    SimpleDateFormat的使用:SimpleDateFormat对日期Date类的格式化和解析

    1.两个操作
    1.1 格式化:日期——>字符串
    1.2 解析:格式化的逆过程,字符串——>日期。解析一般使用带参构造器,默认构造器不好用

    2.SimpleDateFormat的实例化
     */
    @Test
    public void testSimpleDateFormat() throws ParseException {
        //1.实例化SimpleDateFormat:使用默认的构造器
        SimpleDateFormat sdf = new SimpleDateFormat();
        //格式化日期
        Date date = new Date();
        System.out.println(date);//Fri Jun 11 09:30:22 CST 2021

        String format = sdf.format(date);
        System.out.println(format);//21-6-11 上午9:30

        //解析,格式化的逆过程,字符串——>日期
        String str="21-6-11 上午9:34";
        Date date1 = sdf.parse(str);
        System.out.println(date1);//Fri Jun 11 09:34:00 CST 2021

        //**********************************************//
        //2.实例化SimpleDateFormat:使用有参构造器!!!!!!!!!
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        //格式化
        String format1 = sdf1.format(date);
        System.out.println(format1);//2021-06-11 09:39:02
        //解析:要求字符串必须时符合SimpleDateFormat识别的格式(通过构造器参数体现),否则就会抛异常
        Date date2 = sdf1.parse("2021-06-11 09:39:02");
        System.out.println(date2);//Fri Jun 11 09:39:02 CST 2021
    }
    
    /*
    练习一:字符串“2020-09-08”转换为java.sql.Date
     */
    @Test
    public void testExercise1() throws ParseException {
        String birth="1998-09-28";
        //造SimpleDateFormat有参对象
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        //解析
        Date date = sdf1.parse(birth);
//        System.out.println(date);//Mon Sep 28 00:00:00 CST 1998
        java.sql.Date birthDtae=new java.sql.Date(date.getTime());
        System.out.println(birthDtae);//1998-09-28
    }

    /*
    练习二:“三天打鱼两天晒网” 1990-01-01开始,问之后的某年某月某日是在打鱼还是在晒网
          举例:2020-09-08? 计算总天数, 然后取模5看余数,余数1,2,3在打鱼,余数0,4在晒网
     */
    @Test
    public void testExercise2() throws ParseException {
        String str1="1990-01-01";
        String str2="1998-09-28";

        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = sdf.parse(str1);
        Date date2 = sdf.parse(str2);

        long dateCount=(date1.getTime()-date2.getTime())/(1000*60*60*24)+1;
        if(dateCount%5==1||dateCount%5==2||dateCount%5==3){
            System.out.println("渔夫今天在打鱼");
        }else{
            System.out.println("渔夫今天在晒网");
        }
    }
}
2.3.1.4 java.util.Calendar(日历)类
package study.javaSenior.commonlyClass.date;

import org.junit.Test;

import java.util.Calendar;
import java.util.Date;

/**
 * Calendar日历类(抽象类)的使用
 * @author zhengxu
 * @create 2021-06-11 10:06
 */
public class dateTest04 {
    @Test
    public void testCalendar(){
        //1.实例化:抽象类,不能直接实例化
        //方式一:创建子类的对象(GregorianCalaendar)
        //方式二:调用静态方法:getInstance();
        Calendar calendar = Calendar.getInstance();
//        System.out.println(calendar.getClass());//class java.util.GregorianCalendar

        //2.常用方法
        //get()
        int days = calendar.get(Calendar.DAY_OF_MONTH);//这个月的第几天
        System.out.println(days);//11
        System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//162
        //set()
        calendar.set(Calendar.DAY_OF_MONTH,22);
        days= calendar.get(Calendar.DAY_OF_MONTH);//这个月的第几天
        System.out.println(days);//22
        //add()
        calendar.add(Calendar.DAY_OF_MONTH,3);//减就用负数
        days= calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(days);//25
        //getTime():日历类——>date类
        Date date = calendar.getTime();
        System.out.println(date);//Fri Jun 25 10:58:04 CST 2021
        //setTime():Date——>日历类
        Date date1=new Date();
        calendar.setTime(date1);
        days= calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(days);//11
    }
}

【注意】:

  • 获取月份时:一月时0,二月是1,以此类推
  • 获取星期时:周日是1,周一是2。。。。。。周六是7

2.3.2 JDK8中新日期时间API

2.3.2.1 LocalDate、LocalTime、LocalDateTime
package study.javaSenior.commonlyClass.date;

import org.junit.Test;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * jdk8中时间日期API的测试
 * @author zhengxu
 * @create 2021-06-11 15:49
 */
public class dateTest05 {
    /*
    LocalDate、LocalTime、LocalDateTime的使用
    说明:
        1.LocalDateTime相对来说使用的更多一点
        2.类似于calendar
     */
    @Test
    public void test1(){
        //now():获取当前日期或者时间
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime=LocalDateTime.now();

        System.out.println(localDate);//2021-06-11
        System.out.println(localTime);//15:55:07.952
        System.out.println(localDateTime);//2021-06-11T15:55:07.952

        //of():设置指定的年月日时分秒,没有偏移量
        LocalDateTime localDateTime1 = LocalDateTime.of(2020, 10, 6, 13, 23, 43);
        System.out.println(localDateTime1);//2020-10-06T13:23:43

        //getXxx():获取时间,2021年6月11号16:02
        System.out.println(localDateTime.getDayOfMonth());//11
        System.out.println(localDateTime.getDayOfWeek());//FRIDAY
        System.out.println(localDateTime.getMonth());//JUNE
        System.out.println(localDateTime.getMonthValue());//6
        System.out.println(localDateTime.getMinute());//2

        //withXxx():设置时间,体现了不可变性
        LocalDateTime localDateTime2 = localDateTime.withDayOfMonth(22);
        System.out.println(localDateTime); //2021-06-11T16:05:43.884
        System.out.println(localDateTime2);//2021-06-22T16:05:08.554

        //pluseXxx():在现有时间上增加时间,不可变性
        LocalDateTime localDateTime3 = localDateTime.plusMonths(3);
        System.out.println(localDateTime3);//2021-09-11T16:09:16.560

        //minuxXxx():在现有时间上减少时间,不可变性
        LocalDateTime localDateTime4 = localDateTime.minusDays(6);
        System.out.println(localDateTime4);//2021-06-05T16:12:00.378
    }
}
2.3.2.2 瞬时:Instant
package study.javaSenior.commonlyClass.date;

import org.junit.Test;

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;

/**
 * 瞬时:Instant
 * @author zhengxu
 * @create 2021-06-11 16:16
 */
public class dateTest06 {
    @Test
    public void test(){
        //now():获取本初子午线对应的标准时间
        Instant instant = Instant.now();//有时差,按照格林威治时间为标准
        System.out.println(instant);//2021-06-11T08:18:13.731Z

        //atOffset():添加时间的偏移量
        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime);//2021-06-11T16:21:41.107+08:00

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

        //ofEpochMilli():通过给定的毫秒数,获取Instance实例————>类似于Date类的Date(long millis)
        Instant instant1 = Instant.ofEpochMilli(1623399878991L);
        System.out.println(instant1);//2021-06-11T08:24:38.991Z
    }
}

2.3.2.3 格式化与解析日期或时间
package study.javaSenior.commonlyClass.date;

import org.junit.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;

/**
 * DateTimeFormatter类:格式化或者解析时间,类似于SimpleDateFormat
 * @author zhengxu
 * @create 2021-06-11 16:29
 */
public class dateTest07 {
    @Test
    public void test(){
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yy-MM-dd hh:mm:ss");
        //格式化
        String str = dateTimeFormatter.format(LocalDateTime.now());
        System.out.println(str);//21-06-11 04:33:09
        //解析
        TemporalAccessor accessor = dateTimeFormatter.parse("21-06-11 04:33:09");
        System.out.println(accessor);//{SecondOfMinute=9, MicroOfSecond=0, HourOfAmPm=4, MinuteOfHour=33, MilliOfSecond=0, NanoOfSecond=0},ISO resolved to 2021-06-11
    }
}

2.4 java比较器

  • 在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间 的比较问题。
  • Java实现对象排序的方式有两种:
  • 自然排序:java.lang.Comparable
  • 定制排序:java.util.Comparator
package study.javaSenior.commonlyClass.compare;

import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;

/**
 * 一、说明:Java中的对象,正常情况下,只能进行比较操作:==或!=,不能使用>或者<
 *         但是在开发场景中,需要对多个对象进行排序,言外之意,就需要比较对象的大小
 *         如何实现?使用两个接口中的任何一个:Comparable和Comparator
 *
 * 二、Comparable接口与Comparator接口的对比
 *    1.Comparable接口的方式一旦指定,能够保证Comparable接口实现类的对象在任何位置比较大小,在类里面重写
 *    2.Comparator接口属于临时性的比较。什么时候用,什么时候重写
 * 
 *
 * @author zhengxu
 * @create 2021-06-11 17:54
 */
public class CompareTest {
    /*
    Comparable的使用举例:自然排序
    1.像String、包装类等实现了Comparble接口,重写了compareTo()方法,给出了比较两个对象大小的方法
    2.像String、包装类等重写compareTo()方法义后,进行了从小到大的排列,可以直接用Arrays.sort()方法排序
    3.重写compareTo()的规则:
      如果当前对象this大于形参对象obj,则返回正整数,
      如果当前对象this小于形参对象obj,则返回负整数,
      如果当前对象this等于形参对象obj,则返回零。
    4.对于自定义来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo()方法
      在compareTo()方法中指明如何排序
     */
    @Test
    public void test01() {
        //String
        String[] arr = new String[]{"AA", "CC", "GG", "JJ", "DD", "ZZ", "KK"};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));

    }

    @Test
    public void test02() {
        Goods[] arr = new Goods[5];
        arr[0] = new Goods("lenovoMouse", 34);
        arr[1] = new Goods("dellMouse", 43);
        arr[2] = new Goods("xiaomiMouse", 12);
        arr[3] = new Goods("huaweiMouse", 65);
        arr[4] = new Goods("mircoSoftMouse", 43);

        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));//[Goods{name='xiaomiMouse', price=12}, Goods{name='lenovoMouse', price=34}, Goods{name='dellMouse', price=43}, Goods{name='mircoSoftMouse', price=43}, Goods{name='huaweiMouse', price=65}]
    }

    /*
    Comparator接口的使用:定制排序
    1.背景:
      当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,
      或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,
      那么可以考虑使用 Comparator 的对象来排序
    2. 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
       如果方法返回正整数,则表示o1大于o2;
       如果返回0,表示相等;
       如果返回负整数,表示o1小于o2。
    3.利用Arrays.sort(arr,comparator(){});来实现,第二个参数重写compareTo()方法
     */
    @Test
    public void test03(){
        String[] arr = new String[]{"AA", "CC", "GG", "JJ", "DD", "ZZ", "KK"};
        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);
                }
                throw new RuntimeException("输入的类型数据不一致");
            }
        });
        System.out.println(Arrays.toString(arr));//[ZZ, KK, JJ, GG, DD, CC, AA]
    }

    @Test
    public void test04(){
        Goods[] arr = new Goods[6];
        arr[0] = new Goods("lenovoMouse", 34);
        arr[1] = new Goods("dellMouse", 43);
        arr[2] = new Goods("xiaomiMouse", 12);
        arr[3] = new Goods("huaweiMouse", 65);
        arr[4] = new Goods("mircoSoftMouse", 43);
        arr[5] = new Goods("huaweiMouse", 43);

        Arrays.sort(arr, new Comparator() {
            //指明商品比大小的方式:按照产品名称从低到高排序,再按照价格从高到低排序
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof Goods&&o2 instanceof Goods){
                    Goods g1=(Goods) o1;
                    Goods g2=(Goods) o2;
                    if(g1.getName().equals(g2.getName())){
                        return -Double.compare(g1.getPrice(),g2.getPrice());
                    }else {
                        return g1.getName().compareTo(g2.getName());
                    }
                }
                throw new RuntimeException("数据类型不是Doods");
            }
        });
        System.out.println(Arrays.toString(arr));
    }
}

2.5 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的属性对应的值。系统中常见 的属性名以及属性的作用如下表所示:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RoNVyfb3-1623410126385)(C:\Users\zhengxu\AppData\Roaming\Typora\typora-user-images\image-20210611185942460.png)]

    String javaVersion = System.getProperty("java.version");
    System.out.println("java的version:" + javaVersion);
    

2.6 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) :角度—>弧度

2.7 BigInteger与BigDecimal

BigInteger类

  • Integer类作为int的包装类,能存储的最大整型值为2 31-1,Long类也是有限的, 最大为2 63-1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类 都无能为力,更不用说进行运算了。
  • java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger 提供 所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。 另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、 位操作以及一些其他操作。
  • 构造器:BigInteger(String val):根据字符串构建BigInteger对象
  • 常用方法:
    • public BigInteger abs():返回此 BigInteger 的绝对值的 BigInteger。
    • BigInteger add(BigInteger val) :返回其值为 (this + val) 的 BigInteger
    • BigInteger subtract(BigInteger val) :返回其值为 (this - val) 的 BigInteger
    • BigInteger multiply(BigInteger val) :返回其值为 (this * val) 的 BigInteger
    • BigInteger divide(BigInteger val) :返回其值为 (this / val) 的 BigInteger。整数 相除只保留整数部分。
    • BigInteger remainder(BigInteger val) :返回其值为 (this % val) 的 BigInteger。
    • BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟 (this % val) 的两个 BigInteger 的数组。
    • BigInteger pow(int exponent) :返回其值为 (thisexponent) 的 BigInteger。

BigDecimal类

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

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

  • 构造器:

    • public BigDecimal(double val)
    • public BigDecimal(String val)
  • 常用方法

    • public BigDecimal add(BigDecimal augend)
    • public BigDecimal subtract(BigDecimal subtrahend)
    • public BigDecimal multiply(BigDecimal multiplicand)
    • public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode):scale表示精度
    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));
    }
    

你可能感兴趣的:(Java学习笔记,java)