目录
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
探究StringBuffer和StringBulider的高性能拼接
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
1970年01月01日
-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()));