美文网首页
String、Date、对象排序、System、Math、Big

String、Date、对象排序、System、Math、Big

作者: vv_64ce | 来源:发表于2020-04-12 00:57 被阅读0次

    String

    1.String声明为final,表示不可被继承
    2.String实现了Serializable接口:表示字符串支持序列化;实现Comparable接口(比较对象大小),表示String可以比较大小
    3.String内部定义的final char[ ] value用于存储字符串数据
    4.String:表示不可变字符序列。简称:不可变性
    体现(1)对当前字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value赋值
    (2)当对现有字符串进行连接操作时,也需要指定新的内存区域赋值,不能使用原有的value赋值
    (3)当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value赋值
    5.通过字面量方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中
    6.字符串常量池不会存储相同内容的字符串

    String的两种创建方式

    1.字面量方式:String s = "abc";数据在方法区的字符串常量中,共享目的
    2.new + 构造器:String s = new String("abc");数据在堆空间中

            String s1 = new String("abc");
            String s2 = "abc";
            System.out.println(s1==s2);//false比较地址
            System.out.println(s1.equals(s2));//true比较值
    
            Person p1 = new Person("tom",12);
            Person p2 = new Person("tom",12);
    
            System.out.println(p1==p2);//false,比较对象地址
            System.out.println(p1.equals(p2));//false,比较对象值
    
            //new Person("tom",12);,即已字面量方式给name赋值,因此name值相等
            System.out.println(p1.name==p2.name);//true,比较字面量name
            System.out.println(p1.name.equals(p2.name));//true,比较字面量name
    
            p1.name = "jerry";
            System.out.println(p1.name==p2.name);//false,常量池中重新创建了jerry的常量
    
    例题:String s = new String("abc");中创建了几个对象

    两个:一个是堆空间中new结构;另一个是char[ ]对应的常量池中的数据“abc”

    String不同拼接操作的对比

    (1)常量和常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
    (2)只要拼接字符串中有一个是变量(如果该变量前有final,即表示常量,则他不存在于队中,而是存在于方法区的常量池中),就存在于堆中,相当于new了一个对象

            final String str2 = "Web";//表示常量
            String str3 = "javaEEWeb";
            String str4 = "javaEE"+str2;//存在于常量池中
            System.out.println(str3 == str4);//true
    

    (3)若拼接后的结果调用intern()方法,则返回值是位于常量位置的

            String s1 = "javaEE";
            String s2 = "Web";
    
            String s3 = "javaEEWeb";
            String s4 = "javaEE" + "Web";
            String s5 = s1 + "Web";
            String s6 = "javaEE" + s2;
            String s7 = s1 + s2;
    
            String s8 = s7.intern();
            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(s3 == s8);//true
    

    例题:

    public class Test01 {
        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) {
            Test01 t = new Test01();
            t.change(t.str,t.ch);
            System.out.println(t.str);//good
            System.out.println(t.ch);//best
        }
    }
    

    String常用不熟悉方法

            String s = "  He  l l o  ";
            String s1 = s.trim();
            System.out.println(s1);//去除字符串前后空格
    
            String s2 = "java";
            String concat = s2.concat("EE");
            System.out.println(concat);//字符串进行拼接(javaEE)
    
            String s3 = "abc";
            String s4 = "abefghf";
            System.out.println(s3.compareTo(s4));//返回两者比较的差值(-2)
    
            System.out.println(s3.equals(s4));//比较字符串内容是否相同(false)
            System.out.println(s3.contains("e"));//字符串是否包含指定字符(false)
            System.out.println(s4.indexOf("e"));//字符串第一次出现指定字符的位置(2)
            System.out.println(s4.indexOf("g",2));//从指定索引开始查找指定字符串所在索引位置,记录位置从前往后(4)
    
            String s5 ="helloword";
            System.out.println(s5.lastIndexOf("wo"));//指定字符在该字符串最右边出现的索引,但该位置记录仍然是从前往后计数(5)
            System.out.println(s5.lastIndexOf("el",7));//从指定索引反向查找指定字符串所在索引,记录位置从前往后(1)
    
            //什么时候indexOf(str)和lastIndexOf(str)返回值相同
            //1.存在唯一的str(查找的字符只有一个)  2.空字符串时
    
            String s6 = "123";
            String replace = s6.replace('1', '2');
            System.out.println(replace);//将1替换为2,但原字符串仍不改变
    //正则表达式替换,匹配,切片
    //replaceAll(regex,replacement);replaceFirst(regex,replacement);matches(regex);split(regex);split(regex,limit)
    
    String和其他类的转换

    1.String和包装类之间的转换
    2.String和字符数组间(char[ ])的转换

    String s7 = "thanks";
          //String转换为字符数组
          char[] chars = s7.toCharArray();
          for (int i = 0; i < chars.length; i++) {
              System.out.println(i);
          }
    
          char[] c = {'w','o','a'};
          //字符数组转换为String
          String s8 = new String(c);
          System.out.println(s8);
    

    3.String和字节数组(byte[ ])之间的转换
    (1)String-->byte[ ]编码(看得懂--》看不懂二进制数):调用String的getBytes()
    (2)byte[ ]-->String解码(看不懂二进制数--》看得懂):调用String构造器
    解码时,要求解码使用的字符集必须和编码的方式一致,否则乱码

    //String转换为字节数组(编码)
           String s10 = "abc中国";
           byte[] bytes = s10.getBytes();//默认编码方式,此环境默认utf-8,则编码格式也为utf-8
           System.out.println(Arrays.toString(bytes));//[97, 98, 99, -28, -72, -83, -27, -101, -67]一个汉字由3个字节组成
    
           byte[] gbks = s10.getBytes("gbk");//使用gbk进行编码,需要抛出异常
           System.out.println(Arrays.toString(gbks));
           //字节数组转为String(解码)
           String s11 = new String(bytes);//使用默认解码方式解码
           System.out.println(s11);
    
           String s12 = new String(gbks);//使用gbk方式解码,出现乱码,原因是使用gbk编码,却使用utf-8解码
           System.out.println(s12);
    
           String s13 = new String(gbks,"gbk");//使用gbk编码和解码
           System.out.println(s13);
    

    例题:

    StringBuffer

    常用方法:增、删、改、查、插、长度、遍历

     StringBuffer sb = new StringBuffer("abcdefg");
    //        sb.append(1);
    //        sb.append("2");
    //        System.out.println(sb);//abcdefg12 用于字符串拼接;增
    
    //        sb.delete(2,5);
    //        System.out.println(sb);//abfg  删除指定区间[  )位置数据;删
    
    //        StringBuffer s = sb.replace(1, 3, "s");
    //        System.out.println(s);//asdefg 把[start end)位置替换为str
    
    //              StringBuffer insert = sb.insert(2, 3);
    //        System.out.println(insert);//ab3cdefg 在指定位置插入数据;插
    
    //        StringBuffer reverse = sb.reverse();
    //        System.out.println(reverse);//gfedcba 反转顺序
    
    //        int i = sb.indexOf("1");
    //        System.out.println(i);//-1 返回指定字符所在索引位置
    
    //        String substring = sb.substring(1, 3);
    //        System.out.println(substring);//bc 截取[ )的字符
    
    //        char c = sb.charAt(2);
    //        System.out.println(c);//c 获得指定位置字符;查
    
            sb.setCharAt(2,'d');
            System.out.println(sb);//abddefg 将指定位置字符替换,并返回;改
    
    //遍历:for() + charAt()/toString()
    

    StringBuilder

    String、StringBuffer和StringBuilder的异同

    String:不可变字符序列,底层使用char[]存储
    StringBuffer:可变字符序列,线程安全,效率低,底层使用char[]存储
    StringBuilder:可变字符序列,jdk5.0新增,线程不安全,效率高,底层使用char[]存储
    三者效率:StringBuilder > StringBuffer > String

    源码分析:

    String str = new String();//char[] value = new char[0];
    String str = new String("abc");//char[] value = new char[]{'a','b','c'};

    StringBuffer sb1 = new StringBuffer ();//char[] value = new char[16];底层默认创建了长度为16的char[]
    System.out.println(sb1.length());//输出结果为0,原因是虽然默认创建16,但它创建时的实际长度为0
    StringBuffer sb2 = new StringBuffer ("abc");//char[] value = new char[“abc”.length()+16];
    //问题1.System.out.println(sb2.length());//3
    //问题2.扩容问题,若要添加的底层数据盛不下,则需要扩容,默认情况下,扩容为原来容量的2倍加2,同时将原有数据又复制到新数组

    JDK8之前日期时间API

    1.System类中的currentTimeMillis(),返回当前时间和1970年1月1日0时0分0秒之间以毫秒为单位的时间差,称为时间戳(例如并发量不高时订单号生成)
    2.java.util.Date类和java.sql.Date类(同时是java.util.Date的子类)

    (1)两个构造器的使用
    构造器一:Date()创建一个对应当前时间的Date对象
    构造器二:创建指定毫秒数的Date对象
    (2)两个方法的使用
    toString()显示当前年月日时分秒
    getTime()获取当前Date对象对应的毫秒数(时间戳)
    (3)java.sql.Date对应数据库中的日期类型变量
    --》如何实例化
    --》java.util.Date和java.sql.Date的相互转化

    java.util.Date
    //构造器一: 创建一个对应当前时间的Date对象
            Date date = new Date();
            System.out.println(date.getTime());//1586622502908L 返回当前毫秒数
            System.out.println(date.toString());//Sun Apr 12 00:29:02 CST 2020
    
            //构造器二:
            Date date2 = new Date(1586622542111L);
            System.out.println(date2.toString());//Sun Apr 12 00:29:02 CST 2020
    
    java.sql.Date

    java.sql.Date--》java.util.Date:多态
    java.util.Date--》java.sql.Date:

     //创建java.sql.Date对象
            java.sql.Date date3 = new java.sql.Date(1586622542111L);
            System.out.println(date3);//2020-04-12
    
    //将java.util.Date对象转换为java.sql.Date
            //方式一:使用多态创建util的Date对象,再进行强转
            Date date4 = new java.sql.Date(1586622542111L);//多态
            System.out.println(date4.toString());//2020-04-12,但丢失了时分秒,原因是sql下没有时分秒
            java.sql.Date date5 = (java.sql.Date) date4;//强转
            System.out.println(date5);//2020-04-12
            //方式二:先创建util的Date对象,再创建Sql的Date对象的方式
            Date date6 = new Date();//new的父类
            java.sql.Date date7 = new java.sql.Date(date6.getTime());
            System.out.println(date7);//2020-04-12
            //错误方式
            Date d = new Date();//new的父类
            java.sql.Date d1 = (java.sql.Date) d;//强转为子类,报错java.util.Date cannot be cast to java.sql.Date
            System.out.println(d1);
    
    例题
            String s = null;
            StringBuffer sb = new StringBuffer();
            sb.append(s);
    
            System.out.println(sb.length());//4
            System.out.println(sb.toString());//"null"
    
            StringBuffer sb1 = new StringBuffer(s);
            System.out.println(sb1);//java.lang.NullPointerException
    
    3.java.text.SimpleDateFormat

    (1)两个操作
    格式化:日期---》字符串:String format1 = sdf1.format(d1);
    解析:字符串---》日期: Date date1 = sdf1.parse(str);
    (2)SimpleDateFormat的实例化
    使用默认构造器实例化:SimpleDateFormat sdf1 = new SimpleDateFormat();
    使用带参构造器实例化: SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    //1.使用默认构造器实例化SimpleDateFormat
            SimpleDateFormat sdf1 = new SimpleDateFormat();
    
            Date d1 = new Date();
            System.out.println(d1);//Sun Apr 12 10:32:13 CST 2020
            //日期---》字符串
            String format1 = sdf1.format(d1);
            System.out.println(format1);//20-4-12 上午10:31
    
            //字符串---》日期
            String str = "20-4-10 下午20:31";
            Date date1 = sdf1.parse(str);
            System.out.println(date1);//Sat Apr 11 08:31:00 CST 2020
    
            //2.使用带参构造器实例化SimpleDateFormat
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            //日期---》字符串
            String format2 = sdf2.format(d1);
            System.out.println(format2);//2020-04-12 10:31:03
            //字符串---》日期,此时的参数格式需要和带参构造器sdf2对象格式一样,否则报异常
            Date parse = sdf2.parse("2020-04-12 10:31:03");
            System.out.println(parse);
    

    例题:将字符串"2020-02-03"转换为java.sql.Date

     /*
            * 将字符串"2020-02-03"转换为java.sql.Date
            * 1.将字符串转化为util的Date
            * 2.将util的Date转化为sql的Date
            * */
            String s = "2020-02-03";
    
            //1.将字符串转化为util的Date
    
            //错误方式
            //SimpleDateFormat sdf = new SimpleDateFormat();
            // Date d = sdf.parse(s);//字符串---》日期(此种格式固定20-4-10 下午20:31)因此会出错
    
            //正确方式
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date d = sdf.parse(s);//转换成util下的Date
            System.out.println(d);//Mon Feb 03 00:00:00 CST 2020
    
            //2。将util的Date转为sql的Date
            java.sql.Date date = new java.sql.Date(d.getTime());
            System.out.println(date);
    

    例题:"三天打渔两天晒网" 1990-01-01开始,xxxx-xx-xx:打渔?晒网
    思路:毫秒数之差/一天毫秒数+1
    总天数 % 5 == 1,2,3打渔;总天数 % 5 == 4,0晒网;

    4.Calendar(抽象类)日历类的使用

    创建方式:

            //方式一:创建子类(GregorianCalendar)对象
            GregorianCalendar g = new GregorianCalendar();
            System.out.println("方式一"+g);
            //方式二:调用静态方法
            Calendar calendar = Calendar.getInstance();
            System.out.println("方式二"+calendar);
    

    常用方法:

            System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//12当前几号
            //set()将Calendar.属性的值设置为定义的值(改变原有calendar值)
            calendar.set(Calendar.DAY_OF_MONTH,6);
            System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//6  将12号设为6号
            //add()将Calendar.属性的值加或减定义的值(改变原有calendar值)
            calendar.add(Calendar.DAY_OF_MONTH,-1);
            System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//5 将6号减1
    
            //getTime():日历类--》Date
            System.out.println(calendar.getTime());//Sun Apr 05 11:59:53 CST 2020 获得Date
    
            //setTime():Date--》日历类
            Date d = new Date();//获取Date
            calendar.setTime(d);//将Date--》日历类
            System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//12  当前定义Date几号
    

    注意:获取月份:1月-->0 2月-->1 ........ 12月-->11
    获取星期:周日-->1 周一-->2 ...... 周六-->7

    JDK8中新日期时间API(java.time和java.time.format下)不是1.8版本时,可以导入Joda-Time的jar包

    图片.png

    新API产生原因列举两:

            //问题之一:Date:年是从1900年开始,月从0开始,即有偏移,需要减去偏移量
            //问题二:Calendar日期时间可变,如 calendar.set(Calendar.DAY_OF_MONTH,6);
    
            Date d1 = new Date(2020,2,5);//(2020-2-5)
            Date d2 = new Date(2020-1900,2-1,5);//(2020-2-5)
            System.out.println(d1);//Fri Mar 05 00:00:00 CST 3920  (3920-3-5)
            System.out.println(d2);//Wed Feb 05 00:00:00 CST 2020  (2020-2-5)
    
    LocalDateTime(使用频率高)、LocalTime、LocalDate(使用类似于Calendar,方法获取格式很相似)
            //两种方式获取时间,一:当地时间    二:自定义时间
            //now()获取当前时间
            LocalDateTime ldt = LocalDateTime.now();
            LocalDate localDate = LocalDate.now();
            LocalTime localTime = LocalTime.now();
    
            System.out.println(ldt);//2020-04-12T12:39:14.022
            System.out.println(localDate);//2020-04-12
            System.out.println(localTime);//12:39:14.022
            //设置自定义时间
            LocalDateTime of = LocalDateTime.of(2015, 3, 5, 12, 24, 3);
            System.out.println(of);//2015-03-05T12:24:03
    
            //获取
            System.out.println(ldt.getDayOfMonth());//12 获取本月的几号
    
            //设置,不改变原有值,即不可变性
            LocalDateTime ldt1 = ldt.withDayOfMonth(10);
            System.out.println(ldt);//2020-04-12T12:40:35.898
            System.out.println(ldt1);//2020-04-10T12:40:35.898
    
            //加减
            LocalDateTime localDateTime = ldt1.plusMonths(2);//向当前时间加2月
            System.out.println(localDateTime);//2020-06-10T12:47:15.422
    
    Instant瞬时(使用类似于java.util.Date)两者都能获得毫秒数
     //now()获取本初子午线对应的标准时间
            Instant instant = Instant.now();
            System.out.println(instant);//2020-04-12T05:03:40.537Z
    
            //atOffset(偏移参数)添加偏移量
            OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
            System.out.println(offsetDateTime);//2020-04-12T13:03:40.537+08:00
    
            //toEpochMilli()获取自1970开始的毫秒数---》类似于Date类的getTime()
            long l = instant.toEpochMilli();
            System.out.println(l);//1586667820537
    
            //ofEpochMilli(给定毫秒数)--》类似于Date(Long millis)
            Instant instant1 = Instant.ofEpochMilli(1586667739483L);
            System.out.println(instant1);//2020-04-12T05:02:19.483Z
    
    格式化java.time.Format.DateTimeFormatter(使用类似于SimpleDateFormat)

    方式一:预定义标准格式;
    方式二:本地化相关的格式;
    方式三:自定义格式

    //方式一:预定义标准格式ISO_LOCAL_DATE_TIME 、ISO_LOCAL_TIME 、ISO_LOCAL_DATE
            DateTimeFormatter dtf= DateTimeFormatter.ISO_LOCAL_DATE_TIME;
    
            //格式化:日期--》字符
            //1.创建需要格式化的对象
            LocalDateTime localDateTime = LocalDateTime.now();
            //2.格式化
            String format = dtf.format(localDateTime);
    
            System.out.println(localDateTime);//2020-04-12T13:27:19.652
            System.out.println(format);//2020-04-12T13:27:19.652
    
            //解析:字符串--》日期(预定义标准格式化时,转为日期,其参数格式必须和预定义格式一致)
            TemporalAccessor parse = dtf.parse("2020-04-12T13:27:19.652");
            System.out.println(parse);//{},ISO resolved to 2020-04-12T13:27:19.652
    
    //方式二:本地化相关的格式
            //1.适用于LocalDateTime,参数如:FormatStyle.SHORT
            DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
            //格式化
            String format1 = formatter.format(localDateTime);
            System.out.println(format1);//20-4-12 下午1:35
    
            //2.适用于LocalDate,参数和上述参数一致如:FormatStyle.FULL
            DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
            LocalDate ld = LocalDate.now();
            //格式化
            String format2 = formatter1.format(ld);
            System.out.println(format2);//2020年4月12日 星期日
    
            //方式三:自定义格式 如:ofPattern()
            DateTimeFormatter dt = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
            //格式化
            String format3 = dt.format(LocalDateTime.now());
            System.out.println(format3);//2020-04-12 01:57:26
    
            //解析
            TemporalAccessor parse1 = dt.parse("2020-04-12 01:57:26");
            System.out.println(parse1);//{SecondOfMinute=26, HourOfAmPm=1, MilliOfSecond=0, NanoOfSecond=0, MicroOfSecond=0, MinuteOfHour=57},ISO resolved to 2020-04-12
    
    

    对象排序:两种接口

    自然排序:java.lang.Comparable

    使用举例:
    1.像String、包装类等实现了Comparable接口,重写了Comparable(obj)方法,给出了比较两个对象的大小,默认进行了从小到大的排序

    String[] s = new String[]{"aa","bb","ff","cc","dd"};
            Arrays.sort(s);
    //Arrays.toString(s):将s类型的数组以字符串格式返回
            System.out.println(Arrays.toString(s));//[aa, bb, cc, dd, ff]
    

    2.重写CompareTo(obj)规则:
    当前对象this大于形参对象obj,返回正整数;当前对象this小于形参对象,返回负整数;两者相等,返回0
    3.对于自定义类来说,若需要排序,则让该类实现Comparable接口,重写CompareTo(obj)方法,在该方法中指明如何排序

    public class Person implements Comparable{
        private String name;
        private int age;
     //此方法中比较对象,对象按照一定的属性进行比较
        @Override
        public int compareTo(Object o) {
            //方式一:
            //按照name属性进行比较
            if(o instanceof Person){//instanceof测试该对象是否为一个类的实例
                Person p = (Person) o;//将该对象向上转型为父类的实例,即转为同一类对象进行比较
                if(this.age > p.age){//按照从小到大排序
                    return 1;
                }else if(this.age < p.age){//按照从大到小排序
                    return -1;
                }else{
    //                return 0;//只按照age排序
                    return this.name.compareTo(p.name);//按照age排序的同时按照name排序
                }
    //            //方式二
    //            return -Integer.compare(this.age,p.age);//按照从大到小排序
            }
    
            throw new RuntimeException("传入数据类型不一致异常");
        }
    }
    
    //对人进行排序
            Person[] p = new Person[4];
            p[0] = new Person("wangqu",24);
            p[1] = new Person("zhangsan",14);
            p[2] = new Person("xiaohong",12);
            p[3] = new Person("angqu",24);
    
            Arrays.sort(p);//在未对Person实现Comparable接口时,异常cannot be cast to java.lang.Comparable
            System.out.println(Arrays.toString(p));
    

    定制排序:java.util.Comparator

    重写Compare(Object o1,Object o2)方法,比较o1和o2大小

     String[] s = new String[]{"aa","bb","ff","cc","dd"};
            Arrays.sort(s, 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(s));
    

    说明:Comparable接口和Comparator接口的对比
    Comparable接口方式一旦指定,可以保证Comparable接口实现类的对象在任何位置都可以比较大小
    Comparator接口属于临时性比较

    System

    System.exit(0);表示正常退出程序;负数表示异常退出
    System.gc();要求系统进行垃圾回收,但不一定立刻回收
    System.getProperty(String key);获取系统中属性名为key的值

    Math

    相关文章

      网友评论

          本文标题:String、Date、对象排序、System、Math、Big

          本文链接:https://www.haomeiwen.com/subject/jguumhtx.html