6常用类
常用类
1 String类
 1.1 简介
- 
String字符串,使用一堆“”表示 
- 
String声明为final,不可被继承的 
- 
String实现了Serializable接口:表示字符串支持序列化的;实现了Comparable接口:表示String可以比较大小 
- 
String内部定义了final char[] value用于存储字符串数据 
- 
String:代表不可变的字符序列,简称:不可变性  a.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value赋值  b.当对现有字符串进行连接操作时,也要重写指定内存区域赋值,不能使用原有的value 赋值  c.当调用string的replace方法修改字符时,也要重写指定内存区域赋值,不能使用原有的 value赋值 
- 
通过字面量的方式(区别于new)给一个字符串赋值,此时字符串值声明在字符常量池中 
- 
字符串常量池中是不会存储相同内容的字符串的 
//String对象的创建
String str="hello";
//本质上this.value=new char[0]
String s1=new String();
//this.value=original.value
String s2=new String(String original);
//this.value=Arrays.copyOf(value,value.length)
String s3=new String(char[] a);
String s4=new String(char[] a,int startIndex,int count);

    //方式一:字面量方式
	@Test
    public void test1(){
        String s1="abc";//字面量的定义方式
        String s2="abc";
        // s1="hello";变成hello就下面就是false
        System.out.println(s1==s2);//比较s1和s2的地址值 true
        System.out.println(s1);//abc
        System.out.println(s2);//abc
        System.out.println("************");
        String s3="abc";
        s3+="def";
        System.out.println(s3);//abcdef
        System.out.println(s2);//abc
        System.out.println("************");
        String s4="abc";
        String s5=s4.replace('a','m');
        System.out.println(s4);//abc
        System.out.println(s5);//mbc
    }
    /*
    方式二:通过new+构造器方式
    面试题:String s=new String("abc")方式创建对象,在内存中创建了几个对象
            两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据
     */
    @Test
    public void test2(){
        //此时s1和s2数据声明在方法区中的字符串常量中
        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(s3==s4);//false
        System.out.println(s1==s3);//false
        System.out.println(s3.equals(s4));//true
    }
    /*
     常量与常量拼接结果在常量池中,且常量池中不会存在相同内容的常量
     只要其中有一个是变量,结果就在堆中
     */
    @Test
    public void test3(){
        String s1="javaee";
        String s2="hadoop";
        String s3="javaeejadoop";
        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(s5==s6);//false
        System.out.println(s5==s7);//false
        //如果拼接的结果调用inten()方法,返回值就在常量池中
        String s8=s5.intern();//返回得到s8使用的常量池中已经存在的数据
        System.out.println(s3==s8);//true
    }
}
 1.2 String常用方法
- int length():返回字符串的长度
- char charAt(int index):返回某索引出的字符
- boolean isEmpty():判断是否是空字符串
- String toLowerCase():使用默认语言环境,将String中的所有字符转换为小写
- String toUpperCase():使用默认语言环境,将String中的所有字符转换为大写
- String trim():返回字符串的副本,忽略前导空白和尾部空白
- boolean equals(Object obj):比较字符串的内容是否相等
- boolean equalsIgnoreCase(String anotherString):忽略大小写比较内容是否相等
- String concat(String str):将制定字符串连接到此字符串结尾,等价于“+”
- int compareTo(String anotherString):比较两个字符串的大小
- String substring(int beginIndex):返回一个新的字符串,它是此字符串从beginIndex开始截取到最后的一个子字符串
- String substring(int beginIndex,int endIndex):返回一个新的字符串,它是此字符串从beginIndex开始截取到endIndex的一个子字符串,左闭右开
- boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
- boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
- boolean contains(CharSequence s):当前仅当此字符串包含指定的char值序列时,返回true
- int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
- int indexOf(String str, int fromIndex):返回指定字符串在此字符串中第一次出现处的索引,从指定的索引开始
- int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
- inlastdexOf(String str, int fromIndex)::返回指定子字符串在此字符串中最右边出现处的索引,从指定的索引开始反向搜索(注意indexOf和lastIndexOf没找到都返回-1)
- 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个,如果超过了,剩下的全部都放到最后一个元素中
public class G21StringFangFa {
    @Test
    public void test1(){
        String s1="Helloworld";
        System.out.println(s1.length());//10
        System.out.println(s1.charAt(1));//1
        System.out.println(s1.isEmpty());//false
        String s2=s1.toLowerCase(Locale.ROOT);
        System.out.println(s2);//helloworld
        System.out.println(S1);//Helloworld s1还是没变
		
        String s3="  he llo wor ld  ";
        String s4=s3.trim();
        System.out.println(s3);//  he llo wor ld
        System.out.println(s4);//he llo wor ld
    }
    @Test
    public void test2(){
        String s1="hello";
        String s2="Hello";
        System.out.println(s1.equals(s2));//false
        System.out.println(s1.equalsIgnoreCase(s2));//true
        String s3=s2.concat("fao");
        System.out.println(s3);//Hellofao
        String s5="abc";
        String s6=new String("abc");
        System.out.println(s5.compareTo(s6));//0
        String s7="faoahhhhh";
        String s8=s7.substring(3);
        String s9=s7.substring(3,5);//左闭右开
        System.out.println(s8);//ahhhhh
        System.out.println(s9);//ah
    }
    @Test
    public void test3(){
        String s1="helloworld";
        boolean b1=s1.endsWith("ld");
        System.out.println(b1);//true
        boolean b2=s1.startsWith("He");
        System.out.println(b2);//false
        boolean b3=s1.startsWith("ll",2);
        System.out.println(b3);//true
        String s2="world";
        System.out.println(s1.contains(s2));//true
        System.out.println(s1.indexOf("lo"));//3
        System.out.println(s1.indexOf("lol"));//-1
        System.out.println(s1.indexOf("lo",5));//-1
        String s3="hellorworld";
        System.out.println(s3.lastIndexOf("or"));//7
        System.out.println(s3.lastIndexOf("or",6));//4
    }
    @Test
    public void test4(){
        String s1="faozuishuaifao";
        String s2=s1.replace('i','a');
        System.out.println(s2);//faozuashuaafao
        String s3=s1.replace("fao","aoao");
        System.out.println(s3);//aoaozuishuaiaoao
        String s4="fao11aoao22yy33";
        String s5=s4.replaceAll("\\d",",");//将所有数字变成,
        System.out.println(s5);//fao,,aoao,,yy,,
    }
}
 1.3 String类与其他结构之间的转换
 String类与基本类型
- string --> 基本数据类型,包装类: parsrXXX()
- 基本数据类型,包装类 --> string: 调用string重载的valueof()
 String类与char[]数组
- string --> char[]: 调用string的toCharArray()
- char[ ]--> string: 调用string的构造器
 Stirng类与byte[]
- string --> byte[]:调用string的getBytes()
- byte[ ]--> string:调用string的构造器
- 编码:字符串 --> 字节
- 解码:字节 --> 字符串
- 编码解码使用的字符集一定要一致,不然会乱码
public class G22StringZhuanHuan {
    //1 String类与基本类型
    //string-基本类型,包装类之间的转化--parsrXXX()
    //基本数据类型,包装类-string 调用string重载的valueof
    @Test
    public void test1(){
        String s1="123";
        int num = Integer.parseInt(s1);
        System.out.println(num+1);//124
        String s2=String.valueOf(num);
        System.out.println(s2);//123
    }
    /*
    2String类与char[]数组
    string-char[]:调用string的toCharArray()
    char[]-string:调用string的构造器
     */
    @Test
    public void test2(){
        String s1="abc123";
        char[] chars = s1.toCharArray();
        for (int i=0;i<chars.length;i++){
            System.out.println(chars[i]);//a b c 1 2 3 当中是空行 
        }
        char[] arr=new char[]{'h','e'};
        String s2=new String(arr);
        System.out.println(s2);//he
    }
    
    /*
    3string与byte[]之间的转换
    string-byte[]:调用string的getBytes()
    byte[]-string:调用string的构造器
     */
    @Test
    public void test3() throws UnsupportedEncodingException {
        String s1="abc123中国";
        byte[] bytes = s1.getBytes(StandardCharsets.UTF_8);//用默认的字符集
        System.out.println(bytes);//[B@71c7db30
        System.out.println(Arrays.toString(bytes));//[97, 98, 99, 49, 50, 51, -28, -72, -83, -27, -101, -67]
        byte[] gbks = s1.getBytes("gbk");
        System.out.println(Arrays.toString(gbks));//[97, 98, 99, 49, 50, 51, -42, -48, -71, -6]
        String s2=new String(bytes);
        System.out.println(s2);//abc123中国
        String s3=new String(gbks,"gbk");//不是默认的话 一定要指定解码字符集
        System.out.println(s3);//abc123中国
        
        String s4=new String(gbks);
        System.out.println(s4);//abc123�й�
    }
}
 1.4 StringBuffer和StringBuilder
 StringBuffer类
- java.lang.StringBuffer代表可变的字符序列,JDK1.0中声明,可以对字符串进行增删,此时不会产生新的对象
- 很多方法与String相同
- 作为参数传递时,方法内部可以改变值
- 内部定义了char[] value(没有final声明,value可以不断扩容)和Int count(记录有效字符的个数)
 StringBuilder类
- StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样,但是5.0新增,线程不安全的
 StringBuffer新增常用方法
- 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():把当前字符序列逆转
 String, StringBuffer, StringBuilder三者异同
- string:不可变的字符序列,底层用char[]数组
- stringbuffer:可变的字符序列,线程安全的,效率偏低,底层用char[]数组
- stringbuilder:可变的字符序列,5.0新增,线程不安全的,效率高,底层用char[]数组
 内存解析
- String str=new String(); //new char[0]
- String str1=new String("abc"); //new char[]
- StringBuffer sb1=new StringBuffer(); //char[] value=new char[16]
- StringBuffer sb2=new StringBuffer("abc"); //char[] value=new char["abc".length+16]
 注意:
- 扩容问题,如果添加数据底层数组装不下了,需要扩容,默认情况下,扩容为原来容量的2倍+2,同时将原有数组中的元素复制到新的数组中
- 指导意义:建议大家使用StringBuffer(int capacity)指定容量的构造器
- 对比三者效率, 从高到低:StringBuilder>StringBuffer>String
	@Test
    public void test1(){
        StringBuffer sb1=new StringBuffer("abc");
        sb1.setCharAt(0,'m');
        System.out.println(sb1);//mbc
        System.out.println(sb1.length());//3 注意这里还是3
    }
    /*
    StringBuffer/StringBuilder方法(这两个是类似的)
    总结:
        增:append
        删:delete
        改:serCharAt,replace
        查:charAt
        插:insert
        长度:length
        遍历:for+charAt()
     */
    @Test
    public void test2(){
        StringBuffer s1=new StringBuffer("abc");
        s1.append(1);
        s1.append("23");
        System.out.println(s1);//abc123
        s1.delete(2,4);
        System.out.println(s1);//ab23
        s1.replace(2,4,"hello");
        System.out.println(s1);//abhello
        StringBuffer s2=new StringBuffer("abcd");
        s2.insert(2,"fao");
        System.out.println(s2);//abfaocd
        s2.reverse();
        System.out.println(s2);//dcoafba
        String s3=s2.substring(1,3);
        System.out.println(s3);//co
    }
}
1.5 例题
    /*
    将指定区域字符串反转
    方式:先转为char[]
     */
   public String reverse1(String str,int startIndex,int endIndex){
       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);
   }
   @Test
    public void test1(){
       String str="abcdefg";
       String str1=reverse1(str,2,5);
       System.out.println(str2);//abfedcg
   }
/*
获取一个字符串在另一个字符串中出现的次数
 */
public class G26StringTest2 {
    public int getCount(String mainStr,String subStr){
        int mainLength=mainStr.length();
        int subLength=subStr.length();
        if (mainLength>=subLength){
            int num=0;
            int index=0;
            while ((index=mainStr.indexOf(subStr,index))!=-1){
                index+=subLength;
                num++;
            }
            return num;
        }else{
            return 0;
        }
    }
    @Test
    public void test1(){
        String str1="abcdeffgababab";
        String str2="ab";
        int num=getCount(str1,str2);
        System.out.println(num);//4
    }
}
/*
获取两个字符串中最大相同子串
 */
public class G27StringTest3 {
    public String getMaxSameString(String str1,String str2){
        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 test(){
        String str1="abhellosdadadadadad";
        String str2="ahello";
        System.out.println(getMaxSameString(str1,str2));//hello
    }
}
2 JDK8之前的日期时间API
 2.1 System中的currentTimeMills()
- java.lang.System类提供public static long currentTimeMills()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
- 此方法适于计算时间差
- 计算世界时间的主要标准:UTC,GMT,CST
 //1 System类中的crrentTimeMillis()
    @Test
    public void test1(){
        long time=System.currentTimeMillis();
        //称为时间戳
        System.out.println(time);//1630313016832
    }
 2.2 java.util.Date和子类java.sql.Date
- 
java.util.Date表示特定的瞬间,精确到毫秒 
- 
Date()使用无参构造器创建的对象可以获取本地当前时间;Date(long date)这种构造器指定时间 
- 
常用方法: a.getTime():返回自1970年1月1日00:00:00GMT以来此Date对象表示的毫秒数  b.toString():把此Date对象转换为以下形式的String: dow mon dd hh:mm:ss zzz yyyy 其中dow是一周中的买一天(Sun,Mon,Tue,Wed,Thu,Fri,Sat),zzz是时间标准 
    /*
    java.util.Date类
        java.sql.Date类
    1java.util.Date
    1.1两个构造器的使用
        a.Date date1 = new Date();
        b.Date date2=new Date(1550306204104L);
    1.2两个方法的使用
        toString() 显示当前的年、月、日、时、分、秒
        getTime() 获取当前Date对象对应的时间戳
    
    2java.sql.Date 对应数据库中的日期类型的变量
      如何实例化
      如何将util.Date转化为sql.Date:
          Date date6=new Date();
          java.sql.Date date7=new java.sql.Date(date6.getTime());
     */
    @Test
    public void test2(){
        //构造器1 创建一个对应当前时间的Date对象
        Date date1 = new Date();
        System.out.println(date1.toString());//可以省略
        //Mon Aug 30 16:50:04 CST 2021
        System.out.println(date1.getTime());
        //1630313404678
        //构造器2 创建指定毫秒数的Date对象
        Date date2=new Date(1550306204104L);
        System.out.println(date2);
        //Sat Feb 16 16:36:44 CST 2019
        //创建java.sql.Date对象
        java.sql.Date date3=new java.sql.Date(1550306204104L);
        System.out.println(date3);
        //2019-02-16
        //如何将util.Date转化为sql.Date
        //情况1
        Date date4=new java.sql.Date(1550306204104L);
        java.sql.Date date5=(java.sql.Date)date4;
        //情况2
        Date date6=new Date();
        java.sql.Date date7=new java.sql.Date(date6.getTime());
    }
}
 2.3 SimpleDateFormat: 对Date类的格式化和解析
- 
Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat类是一个不与语言环境有关的方式来格式化和解析日期的具体类 
- 
它允许进行格式化:日期->文本/字符串 ;解析:文本/字符串->日期 
- 
格式化: a.SimpleDateFormat():默认的模式和语言环境创建对象 b.public SimpleDateFormat(String pattern):该构造方法可以用参数pattern指定的格式创 建一个对象 c.public String format(Date date):方法格式化时间对象date 
- 
解析 
 a.public Date parse(String source):从给定字符串的开始解析文本,以生成一个日期
  @Test
    public void test1() throws ParseException {
        //实例化使用默认的构造器
        SimpleDateFormat sdf = new SimpleDateFormat();
        //格式化
        Date date = new Date();
        System.out.println(date);//Mon Aug 30 17:03:08 CST 2021
        String format = sdf.format(date);
        System.out.println(format);//2021/8/30 下午5:03 这是默认格式
        //解析
        String str="2021/7/16 上午10:38";//如果是默认,格式要和上面一样
        Date date1=sdf.parse(str);
        System.out.println(date1);//Fri Jul 16 10:38:00 CST 2021
        //指定方式格式化
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String format1 = sdf2.format(date);
        System.out.println(format1);//2021-08-30 05:03:08
        Date date2 = sdf2.parse("2019-02-18 11:48:27");
        System.out.println(date2);//Mon Feb 18 11:48:27 CST 2019
    }
    /*
    例题
    将字符串"2021-07-16"转换为java.sql.Date
     */
    @Test
    public void test2() throws ParseException {
        String birth="2021-07-16";
        SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = sdf1.parse(birth);
        java.sql.Date birthDate=new java.sql.Date(date1.getTime());
        System.out.println(birthDate);
    }
 2.4 Calendar:日历类
- java.util.Calendar是一个抽象基类,主要用于完成日期字段之间相互操作的功能
- 获取Calendar实例的方法 a使用Calendar.getInstance()方法(推荐);b调用它的子类GregorianCalendar的构造器
- 一个Calendar的实例时系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息。比如YEAR,MONTH,DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND
- 注意获取月份时,一月是0...;获取星期时,周日是1,周一是2...
- 此外还有的常用方法
- public void set(int field,int value)
- public void add(int field,int amount)
- public final Date getTime()
- public final void setTime()
 @Test
    public void test3(){
        //1实例化
        //方式1,创建其子类(GregorianCalendar)对象 不常用
        //方式2:调用静态方法getInstance
        Calendar calendar=Calendar.getInstance();
        System.out.println(calendar.getClass());
        //class java.util.GregorianCalendar
        System.out.println(calendar);//太长了
        
        //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);
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//22
        //add
        calendar.add(Calendar.DAY_OF_MONTH,3);
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//25
        //getTime:Calendar-->Date
        Date date = calendar.getTime();
        System.out.println(date);//Wed Aug 25 17:30:49 CST 2021
        //setTime:Date-->Calendar
        Date date1 = new Date();
        calendar.setTime(date1);
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
    }
}
3 JDK8之后的日期时间API
 3.1LocalDate/LocalTime/LocalDateTime
 简介
- Java8创建了新的java.time 包含了所有关于本地日期(LocalDateTime),本地时间(LocalTime),本地日期时间(LocalDateTime),时区(ZonedDateTime),和持续时间(Duration)的类
- LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储生日,纪念日等日期
- LocalTime表示一个时间,而不是日期
- LocalDateTime用来表示日期和时间的,这是一个最常用的类之一
- 上面三者都体现了不可变性
 常用方法
- now()/now(Zoneld zone):静态方法,根据当前时间创建对象/指定时区的对象
- of():静态方法,根据指定日期/时间创建对象
- getDayOfMonth()/getDayOfYear():获取月份天数/获得年份天数
- getDayOfWeek():会的星期几,返回一个DayOfWeek的枚举类
- getMonth():获得月份,返回一个Month枚举值
- getMonthValue():获得月份
- getYear():获得年份
- getHour()/getMinute()/getSecond():获得小时,分钟,秒
- withHour()/withMinute()/withSecond()/withDayOfMonth()/withDayOfYear():修改为指定的值
- plusHour()/plusMinute()/plusSecond()/plusDayOfMonth()/plusDayOfYear():增加指定值
- minusHour()/minusMinute()minusSecond()/minusDayOfMonth()minusDayOfYear():减少指定值
 @Test
    public void test1(){
        //now()
        LocalDate now = LocalDate.now();
        LocalTime now1 = LocalTime.now();
        LocalDateTime now2 = LocalDateTime.now();
        System.out.println(now);//2021-08-31
        System.out.println(now1);//13:59:22.995419400
        System.out.println(now2);//2021-08-31T13:59:22.995419400
        //of 设置指定的年 月 日 时 分秒
        LocalDateTime now3 = LocalDateTime.of(2021, 7, 16, 0, 0, 0);
        System.out.println(now3);//2021-07-16T00:00
        System.out.println();
        
        //getXxx
        System.out.println(now3.getDayOfMonth());//16
        System.out.println(now3.getDayOfWeek());//FRIDAY
        System.out.println(now3.getMonth());//JULY
        System.out.println(now3.getMonthValue());//7
        System.out.println(now3.getMinute());//0
        System.out.println();
        
        //with设置
        LocalDateTime localDate1 = now3.withDayOfMonth(22);
        System.out.println(now3);//2021-07-16T00:00
        System.out.println(localDate1);//2021-07-22T00:00
        LocalDateTime localDate2 = now3.withHour(4);
        System.out.println(localDate2);//2021-07-16T04:00
        System.out.println();
        
        //plus加
        LocalDateTime localDate3 = now3.plusSeconds(200);
        System.out.println(localDate3);//2021-07-16T00:03:20
        //minus减
        LocalDateTime localDate4 = now3.minusSeconds(100);
        System.out.println(localDate4);//2021-07-15T23:58:20
    }
 3.2 Instant
- Instant:时间线上的一个顺时点,这可能被用来记录应用程序中的事件时间戳
- java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间单位,它只是简单的表示自1970年1月1日0时0分0秒开始的秒数
- 1秒=1000毫秒=106微妙=109纳秒
 常用方法
- now():静态方法,返货默认UTC时区的Instant类的对象
- ofEpochMilli():静态方法,返货1970-1-1 00:00:00基础上加上指定毫秒数之后的Instant类的对象
- atOffset(ZoneOffset offset):结合即时的偏移来创建一个OffsetDateTime
- toEpochMilli():返回1970-1-1 00:00:00到当前时间的毫秒数 即为时间戳
 @Test
    public void test2(){
        //实例化
        Instant instant1 = Instant.now();//本初子午线的时间
        System.out.println(instant1);//2021-08-31T06:09:15.441934100Z
        //调整,加8小时
 OffsetDateTime offsetDateTime = instant1.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime);
        //2021-08-31T14:09:15.441934100+08:00
        //获取自1970年1月1日对应毫秒数
        long l1 = instant1.toEpochMilli();
        System.out.println(l1);//1630390155441
        //ofEpochMilli 通过给定毫秒数获取Instant实例
        Instant instant2 = Instant.ofEpochMilli(1626408249844L);
        System.out.println(instant2);//2021-07-16T04:04:09.844Z
    }
 3.3DateTimeFormatter
- 
java.timr.format.DateTimeFomatter类,提供了三种格式化方法 
- 
法1预定义的标准格式如ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME 
- 
法2本地化相关的格式:ofLocalizedDateTime(FormatStyle.LONG) 
- 
法3ofPattern(String pattern):静态方法,返回一个指定字符串格式的DateTimeFormatter 格式化,解析方法 
- 
format(RemporalAccessor()):格式化一个日期,时间,返回字符串 
- 
parse(CharSequence text):将指定格式化的字符序列解析为一个日期,时间 
 @Test
    public void test3(){
        //实例化 方式1 预定义方式
        DateTimeFormatter formatter=DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        
        //格式化 日期-字符串
        LocalDateTime localDateTime = LocalDateTime.now();
        String str1 = formatter.format(localDateTime);
        System.out.println(localDateTime);//2021-08-31T14:19:24.050942600
        System.out.println(str1);//2021-08-31T14:19:24.0509426
        
        //解析 字符串-日期
        TemporalAccessor parse = formatter.parse(str1);
        System.out.println(parse);//{},ISO resolved to 2021-08-31T14:19:24.050942600
        System.out.println();
        
        //实例化 方式2 本地化相关的格式
		DateTimeFormatter formatter1 = 		DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
       
        //格式化
        String str2 = formatter1.format(localDateTime);
        System.out.println(str2);//2021/8/31 下午2:19
        System.out.println();
        
        //实例化 方式3 自定义 最多用!!!
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        
        //格式化
        String str3 = formatter2.format(LocalDateTime.now());
        System.out.println(str3);//2021-08-31 02:19:24
       
        //解析
        TemporalAccessor parse1 = formatter2.parse("2021-6-25 03:52:09");
        System.out.println(parse1);
  //{NanoOfSecond=0, MicroOfSecond=0, MinuteOfHour=52, MilliOfSecond=0, HourOfAmPm=3, SecondOfMinute=9},ISO resolved to 2021-06-25
    }
}
4 Java比较器
 简介
- java实现对象排序的方式有两种
- 自然排序:java.lang.Comparable
- 定制排序:java.util.Comparator
- 两者对比:Comparable接口 一旦指定,保持其实现类在任何位置都可以比较大小;Comparator接口更具有临时性
 自然排序Comparable
- Comparable接口强行对实现它的每个类的对象进行整体排序
- 实现Comparable的类必须实现compareTo(Object obj)方法,两个对象通风该方法比较大小
- 实现Comparable接口的对象列表(或数组)可以通过Collections.sort或Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
- 像String,包装类,实现了Comparable接口,重写了compareTo()方法
- 重写compareTo()规则:当前对象大于形参,返回正整数;相等返回0;小返回负整数
- 对于自定义类,如果需要排序,我们可以让自定义类实现Comparable接口,在comparaTo(obj)方法中指明如何排序
	@Test
    public void test1(){
        String[] arr=new String[]{"aa","cc","mm","gg","zz","dd"};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        //[aa, cc, dd, gg, mm, zz]
    }
    @Test
    public void test2(){
        Goods[] arr=new Goods[4];
        arr[0]=new Goods("lianxiang",34);
        arr[1]=new Goods("dell",43);
        arr[2]=new Goods("xiaomi",12);
        arr[3]=new Goods("huawei",65);
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
 //[Goods{name='xiaomi', price=12.0}, Goods{name='lianxiang', price=34.0}, Goods{name='dell', price=43.0}, Goods{name='huawei', price=65.0}]
    }
//具体实现类
class Goods implements Comparable{
    private String name;
    private double price;
    public Goods(String name, double price) {
        this.name = name;
        this.price = price;
    }
    public Goods() {
    }
    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) {
        if (o instanceof Goods){
            Goods goods=(Goods)o;
            if (this.price>goods.price){
                return 1;
            }else if(this.price<goods.price){
                return -1;
            }else
                return 0;
        }
        //方式二
        //return Double.compare(this.price,goods.price)
        throw new RuntimeException("传入数据不匹配");
    }
}
 定制排序Comparator
- 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Conparable接口的排序规则不适合当前的操作,那就可以考虑使用Comparator的对象来排序,强行对多个对象进行整体的排序的比较
- 重写compare(Object o1,Object o2)方法,比较o1和o2的大小
- 可以将Comparator传递给sort方法(如Collections.sort或Arrays.sort)从而允许在排序顺序上实现精确控制
- 还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供顺序
 @Test
    public void test3(){
        String[] arr=new String[]{"aa","cc","mm","gg","zz","dd"};
        
        //按照字符串从大到小顺序排列
        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, mm, gg, dd, cc, aa]
    }
}
5 其他类






 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号