String
String的特性
- String类:代表字符串,Java中所有字符串字面值都作为此类的实例实现
- String是一个final类,实现了Serializable接口,代表不可变字符串序列
- 实现了Comparable接口:表示String可以比较大小
- 字符串是常量,用双引号表示,值在创建后不能改变
- String对象的字符内容存储在一个字符(char)数组value[]中的。
public final class String
implements java.io.Serializable, Comparable, CharSequence {
/** The value is used for character storage. */
private final char value[];
- 通过字面量的方式(区别于new方式)给一个字符串赋值,此时的字符串值声明在字符串常量池当中。
String a="abc";
String b = "abc";
System.out.println(a==b);// true
- 字符串常量池中不会存储相同内容的字符串。
- 字符串拼接结果
结论:
1. 常量与常量的拼接结果在常量池中。并且常量池中不存在相同内容的常量。
2. 只要有一个是变量,结果就会存在于堆中。
3. 如果拼接结果调用intern()方法,那么这个结果就会存储在常量池中。
System.out.println("--------字符串拼接-----------");
String a1="java";
String a2="Spring";
String b1="javaSpring";
String a3="java"+"Spring";
String a4=a1+"Spring";
String a5="java"+a2;
String a6=a4.intern(); //将这个字符串放在常量池中
System.out.println(a3==b1); //true
System.out.println(a4==b1); //false
System.out.println(a5==b1); //false
System.out.println(a4==a5); //false
System.out.println(a4==a3); //false
System.out.println(a6==a3); //true
- String 实例化方式
方式1:通过字面量定义
方式2:通过new+构造器的方式
方式一:
String n1="java";
String n2="java";
方式二:
String n3=new String(n1);
String n4=new String("java");
System.out.println(n1==n3);//false
System.out.println(n1 == n2);//true
System.out.println(n3 == n4);//false
- 面试题:String s=new String(“abc”);在内存中创建了几个对象
如果常量池中没有abc那么就创建了两个,如果有那么只创建一个。
1.一个是堆空间中new结构
2. 一个是cha[]对应的常量池中的数据"abc";
- 面试题2
public class String01 {
String str=new String("good");
char[] c={'t','e','s','t'};
//String是不可变字符串,参数中的str是一个新的常量,
// c是可变数组,赋给了这个参数,所以就会改变原来的数组
private void change(String str, char[] c) {
str="test ok";
c[0]='b';
}
public static void main(String[] args) {
String01 string01=new String01();
string01.change(string01.str, string01.c);
System.out.println(string01.str); // good
System.out.println(string01.c); //best
}
}
- String类常用方法
- int length():返回字符串长度
- char charAt(int index): 返回某索引处的字符
- boolean isEmpty():判断字符串是否为空
- String toLowerCase():字符串站小写
- String toUpperCase():字符串转大写
- String trim():字符串去空格
- boolean equals(Object obj):比较字符串的内容是否相同
- boolean equalslgnoreCase(String anotherString):与equals方法类似,忽略大小写
- String concat(String str):将指定字符串连接到此字符串的结尾。等价于+
- int compareTo(String anotherString):比较两个字符串的大小
- String subString(int b):返回一个新字符串,从b开始截取到最后一个字符串
- String substring(int b,int e):从b开始到e的新字符串
- boolean endsWith(String suffix):测试此字符串是否以指定的后缀suffix结束
- boolean startsWith(String prefix):是否以前缀prefix开始
- boolean startsWith(String prefix,int toffset):从指定的索引toffset开始的字符串是否以指定的前缀prefix开始
- boolean contains(CharSequence s):当且仅当此字符串包含指定的char值序列时,返回tre;
- int indexOf(String str):返回str第一次出现的索引
- int indexOf(String str,int index);返回str第一次出现的索引,从指定的索引开始
- int lastIndexOf(String str,int index);返回str最后一次出现的索引,从指定的索引开始
注:如果未找到返回-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个,如果超过了,剩下的全部都放到最后一个元素中。
- byte[] getBytes():字符串转byte[]数组。
- byte[] getBytes(String charset):字符串转byte[]数组,设置字符编码。
StringBuffer和StringBuilder
String,StringBuffer和StringBuilder的异同?
1. String:不可变底层用char[]存储
2. StringBuffer:可变字符串,线程安全,效率低下,底层用char[]存储。
3. StringBuilder:可变字符串,线程不安全,效率高,底层用char[]存储。
内存解析:
StringBuffer sb=new StringBuffer(); //char[] value=new char[16];底层创建了一个长度是16的数组。
StringBuffer sb2=new StringBuffer("abc");//char[] value=new char["abc".length+16];
扩容问题:如果添加的数据底层数组盛不下了,那就需要扩容底层的数组。
默认情况下,扩容为原来容器的2倍+2,同时将原数组中的元素复制到新的数组中。
JDK1.8提供的日期类
LocalDate,LocalTime,LocalDateTime
- LocalDate,LocalTime,LocalDateTime类是其较重要的几个类,它们的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期,时间,日期和时间。 它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关信息
- LocalDate代表IOS格式(yyyy-MM-dd) 的日期,可以存储生日,纪念日等日期。
- LocalTime表示一个时间,而不是日期。
- LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。
注意:ISO-8601日历系统是国际标准化组织指定的现代公民的日期和时间的表示法,也就是公历。
方法 |
描述 |
now() /* now(Zoneld zone) |
静态方法,根据当前时间创建对象/指定时区的对象 |
of() |
静态方法,根据指定日期/时间创建对象 |
getDayOfMonth()/getDayOfYear() |
获得月份天数(1-31)/获得年份天数(1-366) |
getDayOfWeek() |
获得星期几(返回一个DayOfWeek枚举值) |
getMonth() |
获得月份,返回一个Month枚举值 |
getMonthValue()/getYear() |
获得月份(1-12)/获得年份 |
getHour()/getMinute()/getSecond() |
获得当前对象对应的小时,分钟,秒 |
withDayOfMonth()/withDayOfYear()/withMonth()/withYear() |
将月份天数,年份天数,月份,年份修改为指定的值并返回新对象。 |
plusDays(),plusWeeks(),plusMonths(),plusYears(),plusHours() |
向当前对象添加天,几周,几个月,几年,几小时 |
minusMonths()/minusWeeks()/minusDays()/minusYears()/minusHours() |
从当前对象减去几月,几周,几天,几年,几个小时 |
- 瞬时:Instant
- Instant:时间线上的一个瞬时点。一般记录程序中的事件时间戳。
- java.time包通过值类型Instant提供机器视图,不提供给处理人类意义上的时间单位。
方法 |
描述 |
now() |
静态方法,返回UTC时区的Install类的对象 |
atOffset(ZoneOffset offset) |
结合及时的偏移来创建一个OffsetDateTime |
toEpochMilli() |
返回1970=01-01 00:00:00到当前时间的毫秒数,即时间戳 |
- 格式化与解析日期或时间
java.time.format.DateTimeFormatter类:该类提供了三种格式化方法
- 预定义的标准格式。如:ISO_LOCAL_DATE_TIME
- 本地化相关的格式.如:ofLocalizedDateTime(FormatStyle.LONG)
-自定义格式。如:ofPattern("yyyy-MM-dd hh:mm:ss")
方法 |
描述 |
ofPattern(String pattern) |
静态方法,返回一个指定字符串格式的DayeTimeFormatter |
format(TemporalAccessor t) |
t是一个LocalDate/LocalDateTime/DateTime 格式化一个日期,时间,返回字符串 |
parse(charSequence text) |
将指定格式的字符序列解析为一个日期,时间 |
- 其他API
- ZoneId:该类包含了所有的时区信息,一个时区的ID,如Europe/Paris
- ZonedDaateTime: 一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T0:15:30+01:00 Europe/Paris
-其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,
- Colck:使用时区提供对当前即时,日期和时间的访问的时钟。
- 持续时间:Duration,用于计算两个"时间"间隔
- 日期间隔:Period,用于计算两个"日期"间隔
- TemporalAdjuster:时间矫正器。有时我们可能需要获取例如:将日期调整到""下一个工作日"等操作。
- TemporalAdjusters:该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用TemporalAdjuster的实现。