您的位置:首页 > 编程语言 > Java开发

String不可变性、日期时间相关类(Java学习笔记七)

2020-06-05 06:14 453 查看

String类

代表字符串。String是一个final类,代表不可变的字符序列(不可变特性),也不可被继承。

字符串是常量,用双引号引起来表示,它们的值在创建后不能更改。

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
private final byte[] value;
private final byte coder;
}

说明:

  • String类实现了Serializable接口,表示字符串支持序列化。
  • String类实现了Comparable接口,表示字符串支持比较大小。
  • String对象的字符内容是存储在一个不可变字符数组value[]中的。

String的不可变性

  • 通过字面量的方式(不同于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中(String Pool,存在于方法区),且存储在value[]中。
  • String Pool中不会存储相同内容的字符串。当字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value[]赋值(原有value[]不可变)。
  • 当对现有字符串进行连接、String.replace()等任何修改操作时,同样都需要指定内存区域重新赋值。

两种赋值方式:

String str1 = "hello";//String Pool中
String str2 = "hello";//String Pool中
String str3 = new String("hello");//堆空间中开辟内存
String str4 = new String("hello");//堆空间中开辟内存

System.out.println(str1 == str2);//true
System.out.println(str1 == str3);//false
System.out.println(str1 == str4);//false
System.out.println(str3 == str4);//false

不同拼接方式:

常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。

只要其中有一个是变量,结果就在堆中 。

如果拼接的结果调用intern()方法,返回值就在常量池中

String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";//String Pool中
String s4 = "hello"+"world";//String Pool中
String s5 = s1 + "world";//堆中
String s6 = "hello" + 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(s4 == s6);//false
System.out.println(s5 == s6);//false

String常用方法

  • int length():返回字符串的长度: return value.length 。
  • 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 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 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 byte[] getBytes() :使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
  • public byte[] getBytes(String charsetName) :使用指定的字符集将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。
  • 字节数组->字符串
      String(byte[]):通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
    • String(byte[],int offset,int length) :用指定的字节数组的一部分, 即从数组起始位置offset开始取length个字节构造一个字符串对象。
  • 字符串->字符数组
      public char[] toCharArray():将字符串中的全部字符存放在一个字符数组中的方法。
    • public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):提供了将指定索引范围内的字符串存放到数组中的方法
  • 字符数组->字符串
      String 类的构造器:String(char[]) 和 String(char[],int offset,int length) 分别用字符数组中的全部字符和部分字符创建字符串对象。
  • 字符串->基本数据类型、包装类
      Integer包装类的public static int parseInt(String s):可以将由“数字”字符组成的字符串转换为整型。
    • 类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型。
  • 基本数据类型、包装类->字符串
      调用String类的public String valueOf(int n)可将int型转换为字符串
    • 相应的valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(double d)、valueOf(boolean b)可由参数的相应类型到字符串的转换

    StringBuffer和StringBuilder

    String:不可变字符序列,线程安全;底层使用char[]存储。

    StringBuffer:可变的字符序列,线程安全的,内部使用 synchronized 进行同步,但是效率偏低;底层使用char[]存储。

    StringBuilder:可变的字符序列,效率高,但不是线程安全;底层使用char[]存储(JDK5后新增)。

    (多线程需要操作共享数据时建议使用StringBuffer(int capacity);其余情况建议使用StringBuilder(int capacity))

    效率:StringBuilder > StringBuffer > String。

    源码分析:

    String str = new String();// 底层new char[0]
    String str = new String(“abc”);// 底层new char[]{‘a’,‘b','c'};
    StringBuffer sb1 = new StringBuffer();//底层char[] value = new char[16],创建了一个长度为16的数组。建议指定这个容量。
    System.out.println(sb1.length());//0
    sb1.append('a');//value[0] = 'a';
    sb1.append('b');//value[1] = 'b';
    //如果底层数组容量不够,则需要扩容。默认情况下扩容为原来的2倍,同时将原有数组中的元素复制到新的数组中。
    
    StringBuffer sb2 = new StringBuffer("abc");
    //底层char[] value = new char["abc".length()+16],创建了一个长度为"abc".length()+16的数组
    System.out.println(sb2.length());//3

    相关常用方法:

    • 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() :把当前字符序列逆转。
    • (当append和insert时,如果原来value数组长度不够,可扩容。且如上方法支持方法链原理)
    • public int indexOf(String str) :同String。
    • public String substring(int start,int end) :同String。
    • public int length() :同String。
    • public char charAt(int n ) :同String。
    • public void setCharAt(int n ,char ch):将下表为n的元素改为ch。

    日期时间

    JDK8之前

    java.lang.System类:

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

    java.util.Date类:

    表示特定的瞬间,精确到毫秒。子类java.sql.Date,和数据库中的Date类型相应。转换时:

    Date date = new Date();
    
    java.sql.Date dateSql = new java.sql.Date(date.getTime());
    • 构造器: Date():使用无参构造器创建的对象可以获取本地当前时间。
    • Date(long 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是时间标准。
    java.text.SimpleDateFormat类:

    Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat 类是一个不与语言环境有关的方式来格式化和解析日期的具体类。

    两大操作:1.格式化;2.解析。

    • SimpleDateFormat() :默认的模式和语言环境创建对象
    • public SimpleDateFormat(String pattern):该构造方法可以用参数pattern 指定的格式创建一个对象,该对象调用:public String format(Date date):方法格式化时间对象date 解析:public Date parse(String source):从给定字符串的开始解析文本,以生成一个日期。
    Date date = new Date(); // 产生一个Date实例 // 产生一个formater格式化的实例
    SimpleDateFormat formater = new SimpleDateFormat();
    System.out.println(formater.format(date));// 2020/5/31 下午2:30
    
    SimpleDateFormat formater2 = new SimpleDateFormat("yyyy年MM月dd日 EEE HH:mm:ss");
    System.out.println(formater2.format(date));//2020年05月31日 周日 14:30:52
    
    try {
    // 实例化一个指定的格式对象
    Date date2 = formater2.parse("2008年08月08日 星期一 08:08:08");
    // 将指定的日期解析后格式化按指定的格式输出
    System.out.println(date2.toString());//Fri Aug 08 08:08:08 CST 2008
    } catch (ParseException e) {
    e.printStackTrace();
    }
    java.util.Calendar(日历)类

    Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能。

    获取Calendar实例的方法 :

    • 使用Calendar.getInstance()方法
    • 调用它的子类GregorianCalendar的构造器

    一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、 MINUTE、SECOND

    • public void get(int field,int value)
    • public void set(int field,int value)
    • public void add(int field,int amount)
    • public final Date getTime()
    • public final void setTime(Date date)

    注意: 获取月份时:一月是0,二月是1,以此类推,12月是11;获取星期时:周日是1,周二是2 ,以此类推,周六是7

    Calendar c = Calendar.getInstance();
    int day = c.get(Calendar.DAY_OF_MONTH);//今天是这个月的第几天
    int day1 = c.get(Calendar.DAY_OF_WEEK);//今天是这个周的第几天
    int day2 = c.get(Calendar.DAY_OF_YEAR);//今天是这个周的第几天
    
    c.set(Calendar.DAY_OF_MONTH,22);//把这个月第几天这个值,改成22号
    c.add(Calendar.DAY_OF_MONTH,5);//在当前“这个月第几天”这个值的基础上加5天,负数即减几天
    
    Date date = c.getTime();//Calendar转换为Date对象,输出 Wed May 27 21:08:10 CST 2020
    c.setTime(date);//把Date对象转回Calendar对象

    JDK8之后

    新的 java.time 中包含了所有关于本地日期(LocalDate)、本地时间 (LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime) 和持续时间(Duration)的类。历史悠久的 Date 类新增了 toInstant() 方法, 用于把 Date 转换成新的表示形式。这些新增的本地化时间日期API 大大简 化了日期时间和本地化的管理。

    LocalDate、LocalTime、LocalDateTime

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

    • LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储生日、纪念日等日期。
    • LocalTime表示一个时间,而不是日期。
    • LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一
    方法 描述
    now() / * now(ZoneId zone) 静态方法,根据当前时间创建对象/指定时区的对象
    of() 静态方法,根据指定日期/时间创建对象
    getDayOfMonth()/getDayOfYear() 获得月份天数(1-31) /获得年份天数(1-366)
    getDayOfWeek() 获得星期几(返回一个 DayOfWeek 枚举值)
    getMonth() 获得月份, 返回一个 Month 枚举值
    getMonthValue() / getYear() 获得月份(1-12) /获得年份
    getHour()/getMinute()/getSecond() 获得当前对象对应的小时、分钟、秒
    LocalDateTime now = LocalDateTime.now();//实例化对象(现在是2020年5月31日 21:23)
    System.out.println(now.getDayOfMonth());//31
    System.out.println(now.getHour()); //21
    System.out.println(now.getYear()); //2020
    Instant

    时间线上的一个瞬时点。这可能被用来记录应用程序中的事件时间戳。

    java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间 单位。Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。 概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。(类似于Date,返回举例1970年1月1日0时0分0秒的秒数)

    方法 描述
    now() 静态方法,返回默认UTC时区的Instant类的对象
    ofEpochMilli(long epochMilli) 静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒 数之后的Instant类的对象
    atOffset(ZoneOffset offset) 结合即时的偏移来创建一个
    OffsetDateTime toEpochMilli() 返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳
    DateTimeFormatter

    该类提供了三种格式化方法 ,用于格式化与解析日期或时间:

    • 预定义的标准格式。如: ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
    • 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
    • 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
    方法 描 述
    ofPattern(String pattern), 静态方法 , 返回一个指定字符串格式的 DateTimeFormatter
    format(TemporalAccessor t) 格式化一个日期、时间,返回字符串
    parse(CharSequence text) 将指定格式的字符序列解析为一个日期、时间
  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: