常用类与基础API

String类的深入认识

类的声明

1
2
3
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence,
Constable, ConstantDesc

final:String是不可继承的
Serializable:可序列化的接口。凡是实现此接口的类的对象就可以通过网络或本地流进行数据的传输
comparable:凡是实现此接口的类,其对象都可以比较大小

内部声明的属性

jdk8及之前:private final char value[];//存储字符串的容器
final:指明此value数组一旦初始化,其地址就不可变

jdk9开始,为节省内存空间做了优化:private final byte value[]//存储字符串的容器

字符串常量的存储位置

  • 字符串常量都存储在字符串常量池(StringTable)中
  • 字符串常量池不允许存储两个相同的常量
  • 内存上,jdk7之前存放在方法区,jdk7之后存放在堆空间

String的不可变性

  1. 当对字符串进行重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置修改
  2. 当对现有的字符串进行拼接时,需要重新开辟空间以保存拼接以后的字符串,不能在原有位置修改
  3. 当调用字符串的replace()替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有位置修改

String实例化的两种方式

第一种:String s1 = "hello"

第二种:String s2 = new String("hello")

连接符:

  1. 常量+常量,存储在字符串常量池,返回字面量的地址。注:此时的常量可能是字面量,也可能是final修饰的常量
  2. 常量+变量或者变量+变量,通过new创建一个新的字符串,返回堆空间中此字符串对象的地址
  3. 调用字符串的intern()返回的是字符串常量池中字面量的地址
  4. concat():不管是常量还是变量,都返回一个新new的对象

String类构造器

1
2
3
4
5
6
7
8
9
10
11
12
13
// 无参构造(但实际无意义,因为 String 是不可变的)
public String();
// 通过字符串字面量构造(实际很少直接使用)
public String(String original);
// 通过字节数组构造(使用平台默认字符集解码)
public String(byte[] bytes);
// 通过字节数组构造(指定字符集解码)
public String(byte[] bytes, String charsetName);
// 通过字节数组的指定范围构造(offset 起始位置,length 长度)
public String(byte[] bytes, int offset, int length);
// 通过字符数组构造
public String(char[] value);
public String(char[] value, int offset, int count);

Stirng类与常见的其它结构之间的转换

  1. Stirng和基本数据类型之间的转换在包装类中已经写过,在此省略
  2. String和char[]的转换
    • String–>char[]:调用toCharArray(),char[] arr = str.toCharArray()
    • char[]–>String:调用String的构造器
  3. String和byte[]的转换
    • 编码:String–>byte[]:调用getBytes(),()内可以用"字符集名称"指明字符集,不写则使用默认字符集
    • 关于字符集:utf-8中汉字占3个字节,一个字母使用1个字节;gbk中一个汉字占2个字节,一个字母占1个字节。两者都向下兼容ascii码。
    • 解码:byte[]–>String:使用构造器,如果需要也要指定字符集
    • 编码和解码指定字符集要相同,否则会乱码。

String常用的方法

String类包含有查找、截取、字符/字符数组、开头结尾、替换等常用API,内容很多且很啰嗦,建议在使用中学习,在此省略。

StringBuffer和StringBuilder类

对比:

String:不可变的字符序列;

StringBuffer:可变的字符序列;线程安全,效率低

StringBuilder:可变的字符序列;线程不安全,效率高

理解

声明的内部属性:

char[] value 存储的字符序列

int count 记录有效字符的个数

构造器:

StringBuffer str = new StringBuffer()空参构造器则会生成一个容量为16的字符数组

StringBuffer str = new StringBuffer("abc")带字符串的构造器则会生成一个字符串长度+16长度的字符数组

扩容:如果使用append()添加字符串,如果count要超过value.length,就需要扩容,默认扩容为原有容量的2倍+2,并将原有value数组中的元素复制到新的数组中。

如果开发中大题确定需要操作的字符个数,建议使用带int capacity参数的构造器,避免频繁扩容。

常用方法

增:

append(xx)

删:

StringBuffer delete(int start, int end):删除[start,end)之间字符
StringBuffer deleteCharAt(int index):删除[index]位置字符

改:

StringBuffer replace(int start, int end, String str):替换[start,end)范围的字符序列为str

void setCharAt(int index, char c):替换[index]位置字符

查:

char charAt(int index):查找指定index位置上的字符

插:

StringBuffer insert(int index, xx):在[index]位置插入xx

长度:

int length():返回存储的字符数据的长度

日期时间的API

jdk8之前的API:

System.currentTimeMillis():与1970.1.1日0时0分0秒之间的毫秒数
两个Date类:sql和util的两个Data类
SimpleDateFormat类:用于日期时间的格式化和解析
Calendar抽象类: 1.实例化,通过Calendar的静态方法2. 常用方法

jdk8及之后的API

LocalDate、LocalTime、LocalDateTime:

实例化:

now()获取当前时间的实例

of()根据指定日期、时间创建对象

常用方法:getXXX()、withDayOfMonth()、plusXxx()、minusXxx()

瞬时:Instant

实例化:

now()当前时间

ofEpochMilli()指定时间

方法:toEpochMilli()

DateTimeFormatter

用于格式化和解析LocalDate、LocalTime、LocalDateTime

ofPattern(“指定格式”)

Java比较器

自然排序

方式:实现Comparable接口的方式

  1. 具体的类实现Comparable类的接口
  2. 实现Comparable接口中的comparaTo方法,在此方法中指明类A对象的大小的标准
  3. 创建类A的实例,进行大小的比较或排序

定制排序

方式:实现Comparater接口的方式

  1. 创建一个实现了Comparator接口的实现类;
  2. 实现类要求实现Compator接口的抽象方法compara(Object o1,Object o2),在此方法中指明要比较对象的大小关系;
  3. 创建此实现类的对象,并将此对象传递到相应方法的参数位置即可。

对比:

自然排序:单一的;一劳永逸的;Comparable接口、comparaTo

定制排序:灵活的;临时的;Comparater接口、compara

其他常用类

System类

属性:out、in、err

方法:currentTimesMills等

Runtime类

对应着Java进程的内存使用的运行时环境,是单例的

Math类

数学运算

BigInteger、BigDecimal类

BigInteger:可以表示任意长度的整数

BigDecimal:可以表示任意精度的浮点数

Random类

产生随机数,例:nextInt(int bound)获取[0,bound)的随机整数