一、String类
1.1.String
表示字符串。
在Java中的所有字符串都是实现它的子类
1.1.1.String特征
不可变长的字符序列。
在底层的存储状态是pubilc final byte[] value(jdk11版本)
pubilc final char[] value (jdk8版本)
1.1.2.String的使用
方式一:直接传入一个字符串给一个String 类型的变量
//String(String original)
String s = "nihao"; //1个对象 "nihao" ->字符串常量池中
注意:
使用这种方式创建的字符串只能传入字符串
方式二:通过new关键字来创建字符串
//String() 初始化新创建的 String对象,使其表示空字符序列。
String str1 = new String();
System.out.println(str1);
//String() 初始化新创建的 String对象,使其表示一个自定义的字符序列。
String str2 = new String("nihao"); ///1个对象 new ->堆中
System.out.println(str2);//nihao
注意:
使用new关键字创建字符串时,可以通过传递不同类型的数据,也可以得到我们想要的字符串
char数组
//String(char[] value)
String str3 = new String(new char[]{'q','w','e','r','d','f'});
System.out.println(str3);//qwerdf
//String(char[] value, int offset, int count)
String str4 = new String(new char[]{'q','w','e','r','d','f'},2,3);
System.out.println(str4);//erd
总结:
char[] value 传入的字符数组,根据字符数组中的元素创建字符串
int offset 从char数组的哪个位置开始----->起始索引
int count 放入几个字符。
也就是说,从字符数组的offset索引位置开始,往后的count个元素当作字符串中的字符,以此创建一个字符串对象。
byte数组
//String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组构造新的 String 。
byte[] arr = "你好".getBytes("gbk");
//String str5 = new String(arr); //在utf-8一个中文3个字节 在gbk一个中文2个字节
//String(byte[] bytes, String charsetName)
String str5 = new String(arr,"gbk");
System.out.println(str5);//你好
System.out.println(arr.length);//4
//String(byte[] bytes, int offset, int length)
//String(byte[] bytes, int offset, int length, String charsetName)
String str6 = new String(arr,2,2,"gbk");
System.out.println(str6);//的
总结:
getBytes() 通过使用平台的默认字符集解码指定的字节数组构造新的 String 。
通俗的讲,就是指定特定的编码集合(字符串的相关方法)
byte[] bytes 传入的byte数组,根据byte数组元素创建字符串
int offset 从char数组的哪个位置开始----->起始索引
int length 放入几个字符。
String charsetName 指定字符集合,(new String时使用)
1.2.StringBuilfer和StringBuffer
StringBuilfer:可变长的字符序列,线程不安全[不同步的]
StringBuffer :可变长的字符序列,线程安全[同步的]
1.2.1.同步和不同步
同步:多个用户可以同时访问字符串,但是用户之间是不可见的。假设,有多个用户想要对字符串进行删除操作,但是,由于他们不可见,在用户的观念里,仅仅删除了字符串的一个字符,但是实际却删除了整整三个,这就会导致数据的不安全。
不同步:多个用户之间必须按照顺序访问字符,当存在一个用户访问字符串的时候,其他用户就不允许再访问字符串进行操作。只有这个用户操作完毕,其他用户才会被允许访问。这样,当前操作的用户看到的一定是最新的字符串数据,操作完毕后,下一个用户看到的,也一定是,前一用户更改后的最新数据,由此保证了数据的安全性。
1.2.2.和String的底层区别
StringBuilfer和StringBuffer两者在底层的存储也是一个byte[] value,但是,相较于String,他们在底层的存储并不是由private final修饰符修饰的
1.2.3.StringBuilfer和StringBuffer的本质
1.本质上,通过StringBuilfer和StringBuffer是创建了一个固定容量的byte数组来存放字符,不是依据我们提供的参数来创建对应长度数组存放的。
默认情况下,通过StringBuilfer和StringBuffer 创建的数组长度是我们提供的字符长度+16。
当我们使用通过StringBuilfer和StringBuffer 创建的可变数组的时候,我们会不断添加字符,假设,我们添加的长度超出创建的数组范围了,就会进行扩容。
每次扩容的大小为:原容量的2倍 + 2
2.我们也可以通过提供一个int类型的字面值作为参数,可以人为的指定创建的数组的长度。
1.3.常用的String方法
1.3.1.前提准备
String str = "jintiantianqibucuo";
String str2 = "Jintiantianqibucuo";
1.3.2.实例
char charAt(int index) 返回指定索引处的 char值。
字符串中该索引位置是哪个字符。输出结果就是哪个
int codePointAt(int index) 返回指定索引处的字符(Unicode代码点)。
字符串中该索引位置的字符在Uicode表中对应的那个数值
System.out.println(str.charAt(8));//i
System.out.println(str.codePointAt(8));//105
int compareTo(String anotherString) 按字典顺序比较两个字符串。
int compareToIgnoreCase(String str) 按字典顺序比较两个字符串,忽略大小写差异。
返回值:
根据this anotherString做判断
0 ---> this == anotherString
<0 ---> this < anotherString
>0 ---> this > anotherString
计算结果:
是从前往后,当遇到两个字符不一致时,this中的字符在Uicode表中对应的那个数值减去anotherString中字符在Uicode表中对应的那个数值【只计算遇到的第一个不同的字符】
System.out.println(str.compareTo(str2));//32
System.out.println(str.compareToIgnoreCase(str2));//0
String concat(String str) 将指定的字符串str连接到此字符串的末尾。
System.out.println(str.concat("haha"));//jintiantianqibucuohaha
System.out.println(str);//jintiantianqibucuo
boolean contains(CharSequence s) 判断字符串中是否包含某个字串
当且仅当此字符串包含指定的char值序列时,才返回true。
System.out.println(str.contains("tian"));
static String copyValueOf(char[] data)
获取一个字符串,字符串中的值和传入的char数组中的值相同
相当于 valueOf(char[]) 。
static String copyValueOf(char[] data, int offset, int count)
获取一个字符串,字符串中的值通过传入的char数组以及指定的索引,字符个数确定
相当于 valueOf(char[], int, int) 。
注意:
char[] data 传入的char类型数组
int offset 起始位置
int count 字符个数
String s = String.copyValueOf(new char[]{'a','b','c','d'});
System.out.println(s);
boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结尾。boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开头。
是 true
否 false
System.out.println(str.startsWith("j"));
boolean equals(Object anObject)
将此字符串与指定的对象进行比较。
boolean equalsIgnoreCase(String anotherString)
将此 String与另一个 String比较,忽略了大小写。
相同 true
不同 false
System.out.println(str.equals(str2));
System.out.println(str.equalsIgnoreCase(str2));
byte[] getBytes()
返回一个 byte类型数组,
使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。byte[] getBytes(String charsetName)
使用命名的字符集将此 String编码为字节序列,将结果存储到新的字节数组中。
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将此字符串中的字符复制到目标字符数组中。
通过字符串.getChars来使用了该方法后,会从传入参数中的起始索引和结束索引来从字符串中取出我们想要的值,将这些值按顺序从参数中的目标数组起始位置开始依次放入到目标字符数组中。
注意:
String charsetName 指定的字符集合
int srcBegin 起始索引
int srcEnd 结束索引
char[] dst 目标字符数组
int dstBegin 目标数组从哪里开始存放
char[] arr = new char[10];
str.getBytes("gbk");
System.out.println(Arrays.toString(bt));
str.getChars(3,6,arr,1);
System.out.println(Arrays.toString(arr));
int indexOf(String str)
返回指定子字符串第一次出现的字符串中的索引。
int indexOf(String str, int fromIndex)
从指定的索引处开始,返回指定子字符串第一次出现的字符串中的索引。
int lastIndexOf(String str)
返回指定子字符串最后一次出现的字符串中的索引。
int lastIndexOf(String str, int fromIndex)
返回指定子字符串最后一次出现的字符串中的索引,从指定索引开始搜索。从后往前
注意:
String str 被搜索的字符串
int fromIndex 指定开始位置的索引
System.out.println(str.indexOf("a"));
System.out.println(str.indexOf("a",6));
System.out.println(str.lastIndexOf("a"));
System.out.println(str.lastIndexOf("a",6));
String intern() 返回字符串对象的规范表示。
String s1 = new String("abc");
String s2 = new String("abc");
String s3 = "haha";
String s4 = "haha";
System.out.println(s1==s2);//false
System.out.println(s3==s4);//true
System.out.println(s1.intern() == s2.intern());//true
boolean isBlank()
如果字符串为空或仅包含 white space代码点,则返回 true ,否则 false 。
System.out.println("".isBlank());//true
System.out.println(" ".isBlank());//true
System.out.println(" sf ".isBlank());//false
int length() 返回此字符串的长度。 *****
System.out.println(str.length());//18
String repeat(int count) 返回一个字符串,其值为此字符串的串联重复 count次。
System.out.println("xixi".repeat(3));//xixixixixixi
String replace(CharSequence target, CharSequence replacement) ***
将字符串中的所有的target所代表的字符都换成replacement代表的字符
String replaceFirst(String regex, String replacement)
将字符串中的第一个regex所代表的字符换成replacement所代表的字符
System.out.println(str.replace("a","A"));//将字符串中的a都换成A
System.out.println(str.replaceFirst("q","Q"));//将字符串中的第一个q换成Q
String[] split(String regex)
将此字符串拆分为给定 regular expression的匹配 项 。 *****
将字符串以给定的字符进行分割,给定的字符当作分隔符,不计入最终形成的数组中
System.out.println(Arrays.toString(str.split("a")));
String strip()
返回一个字符串,其值为此字符串,并删除了所有前导和尾随 white space 。 去除全角空格,去除半角空格
String stripLeading()
返回一个字符串,其值为此字符串,并删除了所有前导 white space 。
String stripTrailing()
返回一个字符串,其值为此字符串,并删除所有尾随 white space 。
String trim()
返回一个字符串,其值为此字符串,删除了所有前导和尾随空格,不能去除全角空格,只能去除半角空格 ***
System.out.println(" 123haha ".trim());
System.out.println(" 123haha ".strip());
System.out.println(" 123haha ".stripLeading());
System.out.println(" 123haha ".stripTrailing());
String substring(int beginIndex)
返回一个字符串,该字符串是此字符串的子字符串。 *****
String substring(int beginIndex, int endIndex)
返回一个字符串,该字符串是此字符串的子字符串。
注意:
int beginIndex 开始位置
int endIndex 结束位置
System.out.println(str.substring(5));
System.out.println(str.substring(5,8));
char[] toCharArray() 将此字符串转换为新的字符数组。 *****
将字符串中的每个字符都当作字符数组中的一个元素
System.out.println(Arrays.toString(str.toCharArray()));
String toLowerCase()
使用默认语言环境的规则将此 String所有字符转换为小写。 ***
String toUpperCase()
使用默认语言环境的规则将此 String所有字符转换为大写。 ***
System.out.println(str.toUpperCase());
System.out.println(str2.toLowerCase());
static String valueOf(boolean b) 返回 boolean参数的字符串表示形式。
System.out.println(String.valueOf(false));
1.3.使用选择
1.3.1.执行效率
三者的执行效率的先后顺序:StringBuilder > StringBuffer > String
从执行效率的角度讲,我们应该选择StringBuilder,所以我们尽量使用StringBuilder。
但是,前面也说了,StringBuilder对数据的安全性并不高。
1.3.2.安全性
如果是单线程的情况下,就使用StringBuilder;这是因为单线程本身就不会出现多用户同时使用某块内容的情况。
如果是多线程的情况下,就使用StringBuffer;这是因为多线程可能会出现上述情况,处于安全性问题,就建议使用StringBuffer,当然了,如果不考虑安全性的情况下,肯定是StringBuilder优于StringBuffer。
1.3.3.String什么时候使用
前面从两个方面看出了,在什么时候使用StringBuilder > StringBuffer ,但是,这并不包括String的使用情况。
事实上,StringBuilder和StringBuffer相较于String有各种各样的优点,比如,可变长;那么为什么还要使用String。这是因为,String 和StringBuilder 与 StringBuffer 相比,使用方式较为简单
代码量要少很多,并且会省内存。
因此,当我们使用的字符串是不可变的时候,使用String是最合适的。
二、包装类
2.1.基本数据类型的包装类
2.2.为什么要使用包装类?
1.包装类中提供了一些成员方法,更适合一些复杂的情况
2.类似容器中,只能存储引用数据类型,需要包装类
3.基本数据类型与引用数据类型的默认值是不同的
2.3.为什么要使用基本数据类型?
1.有利于节省内存
2.使用更简单方便
2.4.自动拆装箱
2.4.1.自动装箱
基本 -----> 引用
int i = 1; //基本
//自动装箱
Integer in = i; //Integer.valueOf(i)
2.4.2.自动拆箱
引用 -----> 基本
//自动拆箱
int i2 = in; //in.intValue()
2.5.总结(重点)
int,Integer,new Integer数据比较问题(前提:数据值相等;考虑类型,地址等问题)
2.5.1.前提准备
Integer num3 = 127;
Integer num4 = 127;
2.5.2.实例
1.两个new 比较 肯定不相等,堆内存中地址不同
Integer num5 = new Integer(127);
Integer num6 = new Integer(127);
System.out.println(num5==num6); //false
2.两个int 比较 值相等就相等
int num1 = 127;
int num2 = 127;
System.out.println(num1==num2); //true
3.int与Integer比较 无论是否通过new,只要数据值相等就相等
会先自动拆箱成基本数据类型比较
int num1 = 127;
Integer num3 = 127;
System.out.println(num1==num3); //true
4.一个Integer,一个new Integer 肯定不相等,new 就是堆内存地址,地址肯定不同
Integer num3 = 127;
Integer num5 = new Integer(127);
System.out.println(num5==num3); //false
5.两个Integer比较 看数值的范围是否在[-128,127]之间
在之间相等,不在之间返回new Integer不相等
Integer num3 = 127;
Integer num4 = 127;
System.out.println(num3==num4); //true
Integer num7 = 128;
Integer num8 = 128;
System.out.println(num7==num8); //false
三、Enum类
枚举类型就是一种事物的所有可能,一种类型的所有实例
通俗的讲,实例只能有我自己掌握,不管是实例的创建还是实例的使用方式都是;其他人不允许越过我来自己创建。
3.1.enum定义枚举
enum WeekDay{
//public static final WeekDay MON = new WeekDay();
MON("星期一"),THUS("星期二"),SUN;
private String name;
private WeekDay() {
}
WeekDay(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.2.枚举类的特性
1.枚举类中的字段都作为当前枚举类型的实例存在,默认public static final修饰
2.枚举类中可以根据需求定义成员,成员变量,成员方法,构造器...
3.枚举类型中的构造器默认私有的
4.所有的枚举类型默认隐式的继承自java.lang.Enum类型
3.3.枚举的使用
3.3.1.前提准备
WDay day1 = WDay.day1;
WeekDay sun = WeekDay.SUN;
sun.setName("周天");
3.3.2.常用方法
getset方法
System.out.println(sun.getName());
System.out.println(WeekDay.MON.getName());
String name() 返回此枚举常量的名称,与其枚举声明中声明的完全相同。
System.out.println(sun.name());
int ordinal()
返回此枚举常量的序数(它在枚举声明中的位置,其中初始常量的序数为零)。
System.out.println(sun.ordinal());
values() 获取枚举类型的所有实例
System.out.println(Arrays.toString(sun.values()));
switch() byte short int char String(jdk1.7) 枚举(jdk1.5)
switch (sun) {
case MON:
System.out.println("今天是周一好桑!!!");
break;
case SUN:
System.out.println("明天周一...");
break;
}
四、Math类
数学类 静态工厂
包含用于执行基本数学运算的方法。
4.1.常用的Math方法
static double random()
返回带有正号的 double值,大于或等于 0.0且小于 1.0 。
[0.0,1.0) 随机小数
随机整数 : [min,max) (int)(Math.random()*(max-min)+min)
随机整数 : [min,max] (int)(Math.random()*(max-min+1)+min)
//[3,7]
System.out.println((int)(Math.random()*(7-3+1)+3));
static double abs(double a)
返回 double值的绝对值。
System.out.println(Math.abs(-1.3));
static double ceil(double a) 向上取整
返回大于或等于参数且等于数学整数的最小值(最接近负无穷大) double
System.out.println(Math.ceil(3.1));
System.out.println(Math.ceil(-1.8));
static double floor(double a) 向下取整
返回小于或等于参数且等于数学整数的最大值(最接近正无穷大) double 。
System.out.println(Math.floor(3.1));
System.out.println(Math.floor(-1.8));
static int max(int a, int b) 返回两个 int值中较大的 int 。
static int min(int a, int b) 返回两个 int值中较小的 int 。
System.out.println(Math.max(1.1,2.2));
static double pow(double a, double b)
返回第一个参数的值,该值是第二个参数的幂。
System.out.println(Math.pow(2,3));
static long round(double a)
返回与参数最接近的 long ,并将关系四舍五入为正无穷大。
System.out.println(Math.round(1.3));
System.out.println(Math.round(1.6));
System.out.println(Math.round(1.49));
static double sqrt(double a) 返回 double值的正确舍入正平方根。
System.out.println(Math.sqrt(2));
五、Date时间类
表示特定的时刻、精确到毫秒
在java.util包下的date,表示一个时间日期精确到ms数
5.1.常用的Date方法
Date()
分配一个 Date对象并初始化它,以便它代表它被分配的时间,测量到最接近毫秒。
Date date1 = new Date();
System.out.println(date1);
System.out.println(date1.getTime());
Date(long date) 参数为ms数 标准基准时间(称为“纪元”)以来的指定毫秒数,
即1970年1月1日00:00:00 GMT。
System.out.println(new Date(1637054973415L));
boolean after(Date when) 测试此日期是否在指定日期之后。
boolean before(Date when) 测试此日期是否在指定日期之前。
Date date2 = new Date();
System.out.println(date1.after(date2));
System.out.println(date1.before(date2));