Java进阶:08.Java常用类
一、String类
1 String类的概述
String:字符串,使用一对“ ”引起来表示。
- String声明为final的,不可被继承
- String实现了Serializable接口:表示字符串是支持序列化的。
 实现了Comparable接口:表示String可以比较大小
- String内部定义了final char[] value用于存储字符串数据
- String:代表不可变的字符序列。简称:不可变性。
2 理解String类的不可变性
通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在方法区(字符串常量池)字符串常量池中,字符串常量池中是不会存储相同内容的字符串。所谓的不可变性用通俗的话讲就是,有操作想改变一个String变量,可以是可以,但别连带着把别人也变了。
- 当对字符串重新赋值时,需要重写指定内存区域赋值,不能改动原有的value值。
下面这句代码是通过字面量的方式给一个字符串赋值,此时的字符串值创建在字符串常量池中。然后在栈区创建一个变量,指向字符串的地址。
String s1 = "abc";
如果再创建一个字符串变量也赋值为"abc",并不会在常量池再创建一个"abc",而是将新的变量也指向以前创建好的"abc",即字符串常量池中是不会存储相同内容的字符串的。
String s2 = "abc";
验证方法可以使用等号,查看两个变量地址是否相同
| 1 |  | 
当写下句代码对字符串重新赋值时,需要在字符串常量池中重新建立一个字符串"hello",然后让s1指向它
String s1 = "hello";
- 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能改动原有的value值。 - 下面的代码也是在字符串常量池中新建一个区域赋值为“abcdef” 
| 1 |  | 
- 当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能改动原有的value值。
| 1 |  | 
3 String实例化的区别
- 实例化方法的区别。String类有下面不同的实例化方式,一般常用的只有前两种
| 1 |  | 
方式一:通过字面量定义的方式,将字符串常量"abc"存储在字符串常量池,目的是共享。
方式二:通过new + 构造器的方式,字符串非常量对象存.储在堆中,堆中的对象又有一个value的字段,其指向常量池中的字符串
 
| 1 |  | 
面试题:String s = new String(“abc”); 方式创建对象,在内存中创建了几个对象?
回答:两个,一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:”abc”
4 String不同拼接操作的对比
常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
final定义的变量是常量,所以final String s1 = "java";  s2 = s1 + "se";   s2也是定义在字符串常量池中的
只要其中有一个是变量,结果就在堆中
如果拼接的结果调用intern()方法,返回值一定是取自字符串常量池中的字符串
String字符串拼接时候的使用陷阱:不能多次执行变量+字符串的操作,否则会在堆中创造大量字符串副本,降低效率
5 String的常用方法
- 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 equals IgnoreCase(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个,如果超过了,剩下的全部都放到最后一个元素中。 
6 String类型的转换
6.1 String与基本数据类型包装类的转换
String –> 基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)
基本数据类型、包装类 –> String:调用String重载的:valueOf(xxx)
6.2 String 与 char[]之间的转换
String –> char[ ]:调用String的 toCharArray() 方法
char[ ] –> String:调用String的构造器
6.3 String与byte[]之间的转换
编码:String –> byte[]:调用String的getBytes()      字符串 –>字节  (看得懂 —>看不懂的二进制数据)
解码:byte[] –> String:调用String的构造器             字节 –> 字符串 (看不懂的二进制数据 —> 看得懂)
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码。
二、StringBuffer、StringBuilder
1. String、StringBuffer、StringBuilder对比
三者的异同?
- String:不可变的字符序列;
- StringBuffer:可变的字符序列;线程安全的,效率低;
- StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;
- 底层都使用char[]存储,String定义的是final char[ ],后两个没有final
因此不涉及到多线程可以用StringBuilder
2. StringBuffer的分析
| 1 |  | 
问题1 System.out.println(sb2.length());//3
问题2 扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组.
 默认情况下,扩容为原来容量的2倍+2,同时将原有数组中的元素复制到新的数组中。
StringBuilder同上类似
意义:开发中建议大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity),即初始化时指定容量。
3. StringBuffer的方法
- 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):返回一个从start开始到end索引结束的左闭右开区间的子字符串
- public int length()
- public char charAt(int n )
- public void setCharAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setCharAt(int n ,char ch) / replace(int start, int end, String str)
查:charAt(int n )
插:insert(int offset, xxx)
长度:length();
遍历:for() + charAt() / toString()
StringBuilder同上类似
4. String、StringBuffer、StringBuilder转换
- String –> StringBuffer/StringBuilder : 调用 StringBuffer/StringBuilder 构造器,传入String
| 1 |  | 
- StringBuffer/StringBuilder –> String : - 调用String构造器 
- 调用 StringBuffer/StringBuilder的 toString()方法 
 
| 1 |  | 
5. String、StringBuffer、StringBuilder效率对比
从高到低排列:StringBuilder > StringBuffer > String
三、日期时间常用类
JDK8之前:
1. System.currentTimeMillis()
时间类:
System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差,称为时间戳。
| 1 |  | 
2. java.util.Date()
日期时间类:
java.util.Date类
- 无参构造器:Date():创建一个对应当前时间的Date对象 
- 有参构造器:Date(arg):创建自己指定毫秒数的Date对象 
3. java.sql.Date()
java.sql.Date类
对应着数据库中的日期类,是util.Date类的子类
| 1 |  | 
4. java.text.SimpleDateFormat
Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat类是一个不与语言环境有关的方式来格式化和解析日期的具体类。
它允许进行
- 格式化:日期 –> 文本
- 解析:文本 –> 日期
| 1 |  | 
5. java.util.Calendar
Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能
一个Calendar的实例是系统时间的抽象表示,获取Calendar实例的方法有
- 使用 - Calendar.getInstance()方法,常用- 1 - Calendar calendar = Calendar.getInstance();
- 调用它的子类 - GregorianCalendar的构造器
常用方法:
- get(intfield)方法来取得想要的时间信息。比如- YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、MINUTE、SECOND
- public void set(intfield,intvalue)设置时间信息
- public void add(intfield,intamount)对时间信息加减
- public final Date getTime()日历类—> Date
- public final void setTime(Date date)Date —> 日历类
| 1 |  | 
注意:
- 获取月份时:一月是0,二月是1,以此类推,12月是11
- 获取星期时:周日是1,周二是2,。。。。周六是7
JDK8
JDK8新增的时间包:
java.time–值对象的基础包,含了所有关于本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类
java.time.chrono–提供对不同的日历系统的访问
java.time.format–格式化和解析时间和日期
java.time.temporal–包括底层框架和扩展特性
java.time.zone–包含时区支持的类
说明:大多数开发者只会用到基础包和format包,也可能会用到temporal包。因此,尽管有68个新的公开类型,大多数开发者,大概将只会用到其中的三分之一。
1. LocalDate、LocalTime、LocalDateTime
LocalDate、LocalTime、LocalDateTime是java.time几个常用的类,它们的实例是不可变的对象,
- LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储生日、纪念日等日期。
- LocalTime表示一个时间,而不是日期。
- LocalDateTime是用来表示日期和时间的,这是最常用的类之一
常用方法:

| 1 |  | 
2. Instant
Instant:时间戳,表示自1970年1月1日0时0分0秒(UTC)开始的秒数,因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。

| 1 |  | 
3. DateTimeFormatter
格式化时间日期类,类似于上文的java.text.SimpleDateFormat
它允许进行
- 格式化:日期 –> 文本
- 解析:文本 –> 日期
创建实例有三种方式,见下文代码,开发中主要使用第一种自定义方式,其它方法还有:

| 1 |  | 
4. 其它
用到再看
- ZoneId:该类中包含了所有的时区信息,一个时区的ID,如Europe/Paris
- ZonedDateTime:一个在ISO-8601日历系统时区的日期时间,如2007-12-03T10:15:30+01:00Europe/Paris。
 其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等
- Clock:使用时区提供对当前即时、日期和时间的访问的时钟。
- 持续时间:Duration,用于计算两个“时间”间隔
- 日期间隔:Period,用于计算两个“日期”间隔
- TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。
- TemporalAdjusters : 该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用TemporalAdjuster 的实现。
四、Java比较器
Java中的对象,正常情况下,只能进行比较:==或 != 。不能使用 >或<的,但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。 如何实现?使用两个接口中的任何一个:Comparable或 Comparator
Java实现对象排序的方式有两种:
- 自然排序:java.lang.Comparable
- 定制排序:java.util.Comparator
1. Comparable
像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式,一般都是从小到大的排列
**因此想要对自定义对象进行排序,需要继承Comparable接口,然后重写compareTo(obj)方法,在compareTo(obj)方法中指明如何排序 **
一般排序的规则是:
- 如果当前对象this大于形参对象obj,则返回正整数,
- 如果当前对象this小于形参对象obj,则返回负整数,
- 如果当前对象this等于形参对象obj,则返回零。
| 1 |  | 
Comparable 的典型实现:
- BigDecimal、BigInteger以及所有的数值型对应的包装类:按它们对应的数值大小进行比较
- Character:按字符的unicode值来进行比较
- Boolean:true 对应的包装类实例大于false 对应的包装类实例
- String:按字符串中字符的unicode 值进行比较
- Date、Time:后边的时间、日期比前面的时间、日期大
2. Comparator
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator的对象来排序,
需要重写compare(Object o1,Object o2)方法,比较o1和o2的大小,如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。注意compare方法是比较两个形参,和Comparable的compareTo方法是不同的
Comparable接口与Comparator的使用的对比:
- Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小。 
- Comparator接口属于临时性的比较,临时构造了一个比较器 
| 1 |  | 
五、System类
System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包
由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用
成员变量:
- System类内部包含- in、out和- err三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)
成员方法:
- native long currentTimeMillis():该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。 
- void exit(int status):该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。 
- void gc():该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。 
- String getProperty(String key):该方法的作用是获得系统中属性名为key的属性对应的值。系统中常见的属性名以及属性的作用如下表所示:  
六、Math类
java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型。
abs 绝对值
acos,asin,atan,cos,sin,tan 三角函数
sqrt 平方根
pow(double a,doble b) a的b次幂
log 自然对数
exp e为底指数
max(double a,double b)
min(double a,double b)
random() 返回0.0到1.0的随机数
long round(double a) double型数据a转换为long型(四舍五入)
toDegrees(double angrad) 弧度—>角度
toRadians(double angdeg) 角度—>弧度
七、大数类
1. BigInteger
Integer类作为int的包装类,能存储的最大整型值为2^31 -1,Long类也是有限的,最大为2^63 -1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。
java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger提供所有Java 的基本整数操作符的对应物,并提供java.lang.Math 的所有相关方法。另外,BigInteger还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
构造器:
- BigInteger(String val):根据字符串构建- BigInteger对象
常用方法:

2. BigDecimal
一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。BigDecimal类支持不可变的、任意精度的有符号十进制定点数
构造器:
- public BigDecimal(double val)
- public BigDecimal(String val)
常用方法:
- public BigDecimal add(BigDecimal augend)
- public BigDecimal subtract(BigDecimal subtrahend)
- public BigDecimal multiply(BigDecimal multiplicand)
- public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
| 1 |  |