(十三)java String和Date、Calendar

1. String

1.1 String对象的简介

简介

  • String类:代表字符串,Java程序中的所有字符串字面值(如”abc“)都作为此类的实例实现
  • String是一个final类,代表不可变的字符序列
  • 字符串是常量,用双引号引起来表示,它们的值在创建之后不能更改
  • String对象的字符内容是存放在一个字符数组value[]中的

产生字符串的方式

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

1.2 String的内存结构

请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述

1.3 字符串的拼接

请添加图片描述

  • 常量与常量的拼接结果在常量池中,且常量池中不会出现内容相同发常量
  • 只要其中一个是变量,结果就在堆中
  • 如果拼接的结果调用intern()方法,返回值就在常量池中
  • Strings1 = "a"说明在字符串常量池中创建了一个字面量为”a“的字符串
  • s1 = s1 + “b”; 说明:实际上原来的“a”字符串对象已经丢弃了, 现在在堆空间中产生了一个字符串
    s1+“b”(也就是"ab")。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内
    存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能。
  • String s2 = “ab”; 说明:直接在字符串常量池中创建一个字面量为"ab"的字符串。
  • String s3 = “a” + “b”; 说明: s3指向字符串常量池中已经创建的"ab"的字符串。
  • String s4 = s1.intern(); 说明:堆空间的s1对象在调用intern()之后,会将常量池中已经存在
    的"ab"字符串赋值给s4。

1.4 常用的方法

  • 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(不包含)的一个子字符串。
  • 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
  • boolean endsWith(String suffix): 测试此字符串是否以指定的后缀结束
  • boolean startsWith(String prefix): 测试此字符串是否以指定的前缀开始
  • boolean startsWith(String prefix, int toffset): 测试此字符串从指定索引开始的子字符串是否
    以指定前缀开始
  • 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个, 如果超过了, 剩下的全部都放到最后一个元素中。
@Test
    public void test1() {
        String s = "helloworld";

        //获取字符串的长度
        System.out.println("s的长度为:" + s.length());

        //获取指定索引位置的字符
        System.out.println("s.charAy(0)=" + s.charAt(0));
        System.out.println("s.charAy(4)=" + s.charAt(4));

        //返回指定字符在字符串中首次出现的索引位置
        System.out.println("s.indexOf(l) = " + s.indexOf("l"));

        //返回指定字符串在字符串中首次出现的索引位置
        System.out.println("s.indexOf(orl) = " + s.indexOf("orl"));

        //返回指定字符在此字符串中从指定位置后第一次出现处的索引
        System.out.println("指定位置s.indexOf(l) = " + s.indexOf('l', 4));
        System.out.println("指定位置s.indexOf(k)=" + s.indexOf('k', 0));
        System.out.println("指定位置s.indexOf(l)=" + s.indexOf('l', 20));
        System.out.println("指定位置s.indexOf(llo)=" + s.indexOf("llo", 1));

        //从指定位置开始截取字符串,默认到尾部,即左闭右开
        System.out.println("substring1 = " + s.substring(5));
        System.out.println("substring2 = " + s.substring(5, 7));//包含5不包含7

        //从指定位置开始到指定位置截取字符串,即左闭右开
        System.out.println("substring3 = " + s.substring(3, 8));
        System.out.println("substring4 = " + s.substring(0, s.length()));

        String s3 = "  abc 123  ";
        System.out.println(s3.trim());//取出两端的空格

        String s4 = "a,b,c,d,e,123";
        String[] s5 = s4.split(",");//按逗号将字符串分开成字符数组
        System.out.println(Arrays.toString(s5));
//        for (int i = 0; i < s5.length; i++) {
//            System.out.println(s5[i]);
//        }
    }
    运行结果如下
s的长度为:10
s.charAy(0)=h
s.charAy(4)=o
s.indexOf(l) = 2
s.indexOf(orl) = 6
指定位置s.indexOf(l) = 8
指定位置s.indexOf(k)=-1
指定位置s.indexOf(l)=-1
指定位置s.indexOf(llo)=2
substring1 = world
substring2 = wo
substring3 = lowor
substring4 = helloworld
abc 123
[a, b, c, d, e, 123]

2. StringBuffer和StringBuilder

2.1 简介:

  • 当append和insert时,如果原来value数组长度不够,可扩容
  • 如上这些方法支持方法链操作
  • 方法链原理
    请添加图片描述

2.2 常用的方法

StringBuffer append(xxx):提供了很多的append()方法, 用于进行字符串拼接
● StringBuffer delete(int start,int end):删除指定位置的内容
● StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
● StringBuffer insert(int offset, xxx):在指定位置插入xxx
● StringBuffer reverse() :把当前字符序列逆转 public int indexOf(String str)
● public String substring(int start,int end)
● public int length()
● public char charAt(int n )
● public void setCharAt(int n ,char ch)

2.3 区别

  • StringBuilfer和StringBuffer非常相似但也有区别。
  • 面试题:对比String、StringBuffer、StringBuilder
    • String(jdk1.0)不可变数组final value[]
    • StringBuffer(jdk1.0) 可变数组、效率低、线程安全
    • StringBuilder(jdk5.0) 可变数组、效率高、线程不安全
      不考虑多线程情况下优先使用StringBuilder
探究StringBufferStringBulider的高性能拼接
public class Test1 {
    @Test
    public void test1(){
        //高效率字符串拼接
        StringBuffer sb = new StringBuffer();
        sb.append("hello ").append("world ").append("java ").append("python");
        System.out.println(sb);
    }
    下面是测试三者之间字符串拼接的速度的比较
    @Test
    public void test2(){
        String text = "";
        long t1 = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            text += i;
        }
        long t2 = System.currentTimeMillis();
        System.out.println(t2 - t1);//918
    }
    @Test
    public void test3(){
        StringBuffer stringBuffer = new StringBuffer();
        long t1 = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuffer.append(i);
        }
        long t2 = System.currentTimeMillis();
        System.out.println(t2 - t1);//3
    }
    @Test
    public void test4(){
        StringBuilder stringBuilder = new StringBuilder();
        long t1 = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuilder.append(i);
        }
        long t2 = System.currentTimeMillis();
        System.out.println(t2 - t1);//3
    }
}

3. 传统日期和时间处理

3.1 System类

System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间戳

3.2 Date

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

  • 构造器:

    • Date()使用无参构造器创建对象可以获取本地当前的时间
    • Date(long date)从那天起开始的date毫秒
  • 常用方法

    • getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。即时间戳
    • toString():把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue,Wed, Thu, Fri, Sat), zzz是时间标准。
    • 其它很多方法都过时了。
探究Date的使用
public class Test1 {
    @Test
    public void test1(){
        System.currentTimeMillis();//系统时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");格式化对象
        Date date = new Date();//当前时间
        System.out.println("当前时间为: 北京时间" + sdf.format(date));
//        System.out.println(date);
       
        Date date1 = new Date(100);//从1970-1-1 8:0:0开始的100毫秒后的时间
        System.out.println(sdf.format(date1));
        //时间戳 从某一时间开始到 1970-1-1 8:0:0的毫秒数
        System.out.println(date1.getTime());时间戳
    }
}

3.3 SimpleDateFormat

Date类的API不易于国际化,大部分被废弃了,
常见的格式有;

  • SimpleDateFormat() :默认的模式和语言环境创建对象
  • public SimpleDateFormat(String pattern): 该构造方法可以用参数pattern指定的格式创建一个对象
  • public String format(Date date): 方法格式化时间对象date
  • public Date parse(String source): 从给定字符串的开始解析文本,以生成一个日期。
public class Test2 {
    @Test
    public void test2() throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
//方式一
        String dateStr = "1970-01-01 08:00:00.000";//将文档转换为标砖时间
        Date date1 = sdf.parse(dateStr);
//        System.out.println(date1);
        System.out.println(sdf.format(date1));
        System.out.println(date1.getTime());//打印时间戳
//方式二
        String dateStr2 = "1970年01月01日";
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日");
        Date date2 = sdf1.parse(dateStr2);
//        System.out.println(date2);
        System.out.println(sdf1.format(date2));
        System.out.println(date2.getTime());//打印时间戳
    }
}
运行结果展示
1970-01-01 08:00:00.000
0
19700101-28800000

4. Calender

获取实例的方法:使用Calendar.getInstance()方法
获取字段:

  • public void set(int field,int value) 设置field
  • public void add(int field,int amount) 增加或减少时间
  • public final Date getTime() 获取当前时间(区分上面的getTime())
  • public final void setTime(Date date)
    注意:月份是从0开始
    星期日是0,星期一是1
public class Test3 {
    @Test
    public void test3() throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Calendar c = Calendar.getInstance();//固定搭配,当前时间等价于 new Date()
//        //得到field
//        System.out.println(c.get(Calendar.YEAR));//得到年
//        System.out.println(c.get(Calendar.MONTH));//得到月,传统的月份从零开始
//        System.out.println(c.get(Calendar.DAY_OF_MONTH));
//        System.out.println(c.get(Calendar.HOUR_OF_DAY));
        //设置field
        c.set(Calendar.MONTH,0);//传统日期从0开始
        System.out.println(sdf.format(c.getTime()));//得到date
        //减三个月
        c.add(Calendar.MONTH,-3);
        System.out.println(sdf.format(c.getTime()));


        //创建1970-01-01 08:0:0;0.000;
        //方式一
        String dateStr = "1970-01-01 08:0:0.0";//把字符串解析成日期
        Date date1 = sdf.parse(dateStr);
//        System.out.println(date1.getTime());//显示时间戳
        System.out.println(sdf.format(date1));

        //方法二
        Calendar c2 = Calendar.getInstance();//固定搭配
        c2.set(1970,0,1,8,0,0);
        c2.set(Calendar.MILLISECOND,0);
        System.out.println(sdf.format(c2.getTime()));

        //当前时间四周后
        Calendar c3 = Calendar.getInstance();
        c3.add(Calendar.WEEK_OF_MONTH,5);
        System.out.println(sdf.format(c3.getTime()));
    }
}

5. JDK新日期API

java8中引入了Java.time.API已经纠正了过去的缺陷,将来很长一段时间内它都会为我们服务

5.1 LocalDateTime和 Instant

public class Test4 {
    @Test
    public void test5(){
        //得到当前时间
        LocalDateTime l1 = LocalDateTime.now();//当前时间
        System.out.println("l1 = " + l1);

        //得到field
        System.out.println(l1.getMonth().getValue());
        System.out.println(l1.getYear());
        System.out.println(l1.getDayOfMonth());
        System.out.println(l1.get(ChronoField.HOUR_OF_DAY));//获取时间

        //设置field,支持Chain方法链,
        LocalDateTime l2 = l1.withMonth(1).withDayOfMonth(1);//新API月份从1开始
        System.out.println(l2);

        //加三个月三周
        LocalDateTime l3 = l2.plusMonths(3).plusWeeks(3);
        System.out.println(l3);
        //减四周
        System.out.println(l3.minusWeeks(4));

        //创建1970-01-01 8:0:0
        LocalDateTime l4 = LocalDateTime.of(1970, 1, 1, 0, 0, 0, 0);
        System.out.println(l4);

        //时间戳操作 Instant
        Instant i1 = l4.toInstant(ZoneOffset.UTC);//得到UTC时间的Instant
        System.out.println(i1.toEpochMilli());
        LocalDateTime l5 = LocalDateTime.of(1970, 1, 1, 8, 0, 0, 0);
        Instant i2 = l5.toInstant(ZoneOffset.ofHours(8));//得到东八区的Instant
        System.out.println(i2.toEpochMilli());//时间戳为0
}

5.3 DateTimeFormatter

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒.SSS");
        System.out.println(formatter.format(LocalDateTime.now()));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值