目录
Sting.intern()方法简介:(最终返回的是常量池中的地址(对象))
String、StringBuffer、StringBuilder的比较
String、StringBuffer、StringBuilder的选择
包装类
包装类分类:Wrapper
1、根据八种基本数据类型相应的引用类型-----包装类
2、有了类的特点,就能够调用类中的方法
基本数据类型 | 包装类 |
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
父类:Number
包装类与基本数据转换:(装箱与拆箱)
1)jdk5 前的手动装箱与拆箱方式,装箱:基本类型-》包装类型,反之,即为拆箱
以int 与 Integer 为例:
//手动装箱
int n1 = 100;
Integer integer = new Integer(n1);
Integer interger1 = integer.valueOf(integer);
//Integer integer = new Integer(n1).valueOf(n1);
//上两句合成一句写
//手动拆箱
int n2 = integer.intValue();
2)jdk5 以后(含jdk5)的自动装箱与拆箱方式
//自动装箱
int n1 = 100;
Integer integer = n1;//其底层还是使用的是Integer.valueOf(n1)
//自动拆箱
int n2 = integer;//其底层仍然使用为 .intValue();
3)自动装箱底层调用的是valueOf方法,比如 Integer.valueOf()
注意:三元运算符为一个整体,会优先继承精度高的一个类
String与包装类型的相互转换
以int 与 String 为例
//包装类(Integer)-》String
Integer i = 100;
//方式一:
String str1 = i + "";
//方式二:
String str2 = i.toString();
//方式三:
String str3 = String.valueOf(i);
//String -》 Integer
String str1 = "123";
//方式一:
Integer integer1 = Integer.parseInt(str1);//自动装箱
//方式二:
Integer integer2 = new Integer(str1);//利用构造器
包装类的常用方法
Integer 与 Character的常用方法
System.out.println(Integer.MAX_VALUE);//返回最大值 2147483647
System.out.println(Integer.MIN_VALUE);//返回最小值 -2147483648
System.out.println(Character.isDigit('a'));//判断字符是否为数字 false
System.out.println(Character.isLetter('a'));//判断字符是否为字母 true
System.out.println(Character.isUpperCase('a'));//判断字符是否为大写字母 false
System.out.println(Character.isLowerCase('a'));//判断字符是否为小写字母 true
System.out.println(Character.isWhitespace('a'));//判断字符是否为空格 false
System.out.println(Character.toUpperCase('a'));//将字符转换为大写 A
System.out.println(Character.toLowerCase('A'));//将字符转换为小写 a
例题:
只要有基本数据类型出现 ”==“ 判断的是值是否相等
Integer m = 1;//这里是一个装箱的操作
Integer n = 1;//valueOf();
System.out.Println(m == n);
//true
//当装箱值在 -128 到 127 之间不会新建对象直接返回
//反之会新建对象
String类
其实现了 Serializable 接口,说明String 可以串行化 (即能够在网络中进行传输)
实现了Comparable 接口,说明String 对象能够比较大小
1)String对象用于保存字符串,也就是一组字符序列
2)字符串常量对象是用双引号括起来的字符序列 例如:"123" "nfdsah" ”你是?“
3)字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节
4)String类较常用的构造器(有许多构造器,实现构造器重载)
String str1 = new String();
String str2 = new String(String original);
String str3 = new String(char[] a);
String str4 = new String(char[] a,int startIndex,int count);
String str5 = new String(byte[] b);
5)String是一个final 类,不能被其他类继承
6)String 有属性 private final char value[]; 用于存放字符串内容
7)注意:value 是一个final 类型数据,不可被修改((地址)【即不能指向新的地址】) 非其中的单个字符内容是可以进行修改的)
创建String 对象的两种方式:
//方式一:直接赋值
String str1 = "str";
//str1指向常量池中的地址
//方式二:利用构造器
String str2 = new String("str");
//str2先指向堆中的地址,堆的地址再指向常量池中的地址
A:方式一:先从常量池查看是否有"str" 数据空间,如果有,直接指向;如果没有则重新创建,然后指向。str最终指向的是常量池的空间地址
B:方式二:先在堆中创建空间,里面维护了value属性,指向常量池的 str 空间。如果常量池没有 “str”,则重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址
C:内存分布图
Sting.intern()方法简介:(最终返回的是常量池中的地址(对象))
String的特性
1)String 是一个final类,代表不可变的字符序列
2)字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的
例题:
下列语句创建了几个对象 --创建了2个对象
String s1 = "hhh";
s1 = "shit";
下列语句创建了几个对象 --创建了1个对象
String a = “hello” + “abc”;
//编译器会进行优化为:String a = "helloabc";
//编译器会自行判断创建的常量池对象,是否有引用指向
下列语句创建了几个对象 --创建了3个对象
String a = “hello”;
String b = "abc";
String c = a + b;
//1、先创建一个 StringBuilder sb = new StringBuilder();
//2、执行 sb.append("hello");
//3、执行 sb.append("abc");
//4、String c = sb.toString(); 注意这里是new 出来的一个对象
//最后的c 指向堆中的对象(String) value[] -> 池中的"helloabc"
规则:常量相加,看的是池(String str = "a"+"b");变量相加,是在堆中(String str = a+b)
综合例题:
class T1{
String str = new String("abc");
final char[] ch = {'j','a','v','a'};
public void change (String str , char[] ch){
//当程序运行至此时,str仍指向value
str = "jqk";
//运行至此时,断开先前指向,重新指向常量池中的jqk
ch[0] = 'a';
//修改数组首元素
}
}
public static void main(String [] args){
T1 t = new T1();
t.change(t.str,t.ch);
System.out.println(t.str + "and");
//执行这句回到主栈,依然通过str寻找数据,
//仍然是通过对象t 查找属性str为 ”abc“
System.out.println(t.ch);
}
//最终输出:
abcand
aava
String类的常见方法
第一组:
String类是保存字符串常量的。每次更新都需要重新开辟空间,效率极低,因此java 设计者还提供了StringBuffer 与 StringBuilder 来增强String 的功能,并提高效率
equals 区分大小写,判断内容是否相等
equalsIgnorCase 忽略大小写进行判断内容是否相等
length 获取字符的个数,字符串的长度
indexOf 获取字符在字符串中第一次出现的索引,索引从零开始从前往后配置,找不到返回-1 Str.indexOf('字符');
lastIndexOf 获取字符在字符串中最后一次出现的索引,索引从零开始且仍是从前往后配置索引,找不到返回-1
subString 截取指定范围的子串 当参数只给一个数字时,以该数字为索引截取出包括它自己以及后面的子串,当参数给出两个数字并以逗号隔开时,由前者的数字索引(包括)开始截取到后者的索引(不包括)结束作为子串
trim 去掉前后空格
charAt 获取某索引处的字符,注意不能使用 Str[index] 这种方式应该用 Str.charAt(0)
第二组:
toUpperCase 转换为大写
toLowerCase 转换为小写
concat 拼接方法,参数为需要在对象后面拼接的字符串
replace 替换字符串中的字符,两个参数将前者替换为后者,返回的结果才是替换过的内容,本身对调用者没有任何改变
split 分割字符串,对于分割字符,我们需要转义 比如 | \\等 以后面的参数为字符串,查找到目标字符串后,将字串删除并以数组的形式返回
compareTo 比较两个字符串大小,字符串长度相等按字符进行比较,Str1.compareTo(Str2),如果前者大,则返回整数,后者大,则返回负数,如果相等,返回0,长度不等或相等且前面部分字段不相同则使用第一个字符相减得到返回值,前面从索引零开始若有与之相等的字符,则返回前者字符数量减去后者字符数量的差
toCharArray 转换为字符数组
format 格式字符串(占位符),s%字符串 %c字符 %d整形 %.2f浮点型替换后,只会保留两位小数,并且进行四舍五入,Str.format("字符串(用占位代替变量)",变量1,变量2。。。)
StringBuffer类
简介:
java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删
很多方法与String相同,但StringBuffer是可变长度的
StringBuffer是一个容器
摘要:
1、StringBuffer 的直接父类 是 AbstractStringBuilder
2、StringBuffer 实现了 Serializable, 即StringBuffer 的对象可以串行化
3、在父类中, AbstractStringBuilder 有属性 char[] value,注意不是final类型,该value 数组存放 字符串内容,因此数据存放在堆中
4、StrngBuffer 是一个final类,不能被继承
5.因为StringBuffer 字符内容是存在 char[] value ,所以在变化(删除/修改)时,不用每次都更换地址(即不是每次都创建新对象),所以效率高于 String
String 与 StringBuffer
A:String 保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低 private final char value[]
B:StringBuffer 的更新实际上可以更新内容,不用每次更新地址,效率较高 //char[] value //这个放在堆内
StringBuffer构造器:
String 与 StringBuffer 相互转换
String str = "Hello tom";
//方式一:使用构造器
//(注意返回的才是StringBuffer对象 , 对str本身没有影响)
StringBuffer ab = new StringBuffer(str);
//方式二:使用append()
StringBuffer ab1 = new StringBuffer();
ab1 = ab1.append(str);
//StringBuffer -> String
//方式一:使用StringBuffer提供的 toString方法
StringBuffer ab2 = new StringBuffer("a");
String s = ab2.toString();
//方式二:使用构造器直接创建
String s1 = new String(ab2);
StringBuffer类常用方法
1)增 append("str") 在末尾处增加,返回值为StringBuffer
2)删 delete(start,end) 删除索引为>=start && <end 处的字符
3)改 replace(start,end,string):将start 到 end 之间的内容替换掉,不包含end即[start,end)
4)查 indexOf("str") 查找子串在字符串第一次出现的索引,找不到返回-1
5)插 insert(索引,"str") 在索引处插入str,原索引处及后续字符串向后移
6)获取长度 length
StringBuilder类
介绍
A:一个可变的字符序列。此类提供一个与 StringBuffer 兼容的API,但不保证同步(StringBuilder 不是线程安全的)。该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候,如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer要快
B:在StringBuffer 上的主要操作是 append 与 insert 方法,可重载这些方法,以接收任意数据类型的数据
StringBuilder常用方法
StringBuilder 与 StringBuffer 均代表可变字符序列,方法是一样的,所以使用和StringBuffer 一样
注意:
1、StringBuilder 是final修饰的,不能被继承
2、继承了 AbstractStringBuilder,对象字符序列仍然存放在其父类的属性 char[] value 中,因此字符序列存放在堆中
3、实现了 Serializable 接口,序列化(所谓序列化即可以保存类型和数据本身,可以保存到文件)
4、StringBuilder 的方法,没有做互斥处理,即没有synchronized 关键字,因此在单线程的情况下使用StringBuilder
String、StringBuffer、StringBuilder的比较
1)StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法一样
2)String:不可改变字符序列,效率低,但复用率高
3)StringBuffer:可变字符序列、效率较高(增、删),线程安全
4)StringBuilder:可变字符序列、效率最高、但线程不安全
5)String 使用注意说明:
String s = ”a“; //创建了一个字符
s += ”b“; //实际上原来的”a“字符串对象已经丢弃了,现在又产生了一个字符串 s+”b“(也就是”ab“) 。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能=》结论:如果我们对String 做大量修改,不要使用String
String、StringBuffer、StringBuilder的选择
1、如果字符串存在大量的修改操作,一般使用 StringBuffer 或者 StringBuilder
2、如果字符串存在大量的修改操作,并在单线程的情况下,使用 StringBuilder
3、如果字符串存在大量的修改操作,并在多线程的情况下,使用 StringBuffer
4、如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等
Math类
介绍:Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根、和三角函数
Math类常见方法(均为静态方法):
1)abs 绝对值
2)pow 求幂
3)ceil 向上取整(返回double)
4)floor 向下取整(返回double)
5)round 四舍五入
6)sqrt 求开方
7)random 求随机数(返回的是 [0,1) 的随机小数):如果要求返回一个[a,b]范围内的随机数
公式为: (int)(a + Math.random() * (b-a+1))
8)max 求两个数最大值
9)min 求两个数最小值\
Arrays类
Arrays 里面包含了一系列静态方法,用于管理或操作数组(如:搜索 或 排序)
常用方法:
1、toString 返回数组的字符串形式(遍历输出) Arrays.toString(arr);
2、sort排序 (自然排序与定制排序)注意:
1)因为是数组是引用类型,所以通过sort排序后,会直接影响到 实参 arr
2)sort是重载的,也可以传入一个接口 Comparator 实现定制排序
3)调用定制排序时,传入两个参数 a:排序数组arr b:实现了 Comparator 接口的匿名内部类,要求实现 compare 方法
4)体现了接口编程的方式
Arrays.sort(arr)//默认排序
Arrays.sort(arr,new Comparator()){
@override
public int Compare (Object o1,Object o2){
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i1 - i2;//此为升序 return i2 - i1 ;则为降序
}
});
用冒泡排序改为定制排序
public static void main(String[] args) {
int[] arr = {1, -1, 8, 0, 20};
Arrays_Sort.Bubble_02(arr,new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int i1 = (Integer)o1;
int i2 = (Integer)o2;
return i2 - i1;//此为降序 return i1 - i2 ;为升序
}
});
System.out.println(Arrays.toString(arr));
}
public static void Bubble_01(int[] arr) {
for(int i = 0 ; i < arr.length - 1 ; i++) {
for(int j = 0 ; j < arr.length - 1 - i; j++) {
if(arr[j] > arr[j+1]) {
int tmp;
tmp = arr [j];
arr [j] = arr[j+1];
arr [j+1] = tmp;
}
}
}
}
@SuppressWarnings("rawtypes")
public static void Bubble_02(int []arr, Comparator c) {
for(int i = 0 ; i < arr.length - 1 ; i++) {
for(int j = 0 ; j < arr.length - 1 - i; j++) {
// 由compare(arr[j], arr[j+1])的返回值决定 数组的排序方式
if(c.compare(arr[j], arr[j+1])>0) {//根据动态绑定传给匿名内部类
int tmp;
tmp = arr [j];
arr [j] = arr[j+1];
arr [j+1] = tmp;
}
}
}
}
3、binarySearch 通过二分搜索法进行查找,要求必须排好序 ,返回为一个索引,
找不到则返回 return -(low+1); 即返回一个如果存在的索引加一的负数
int index = Arrays.binarySearch(arr,3);
4、copyOf 数组元素的复制
Integer[] newArr = Arrays.copyOf(arr,arr.length); 注意:
从 arr 数组中拷贝 arr.length 个数据到 newarr中,
如果拷贝长度>arr.length 就在新数组后面 增加null
如果拷贝长度< 0 ,抛出异常:NegativeArraySizeException
底层用到 System.arraycopy()
5、fill 填充数组元素
Integer[] num = new Integer[]{9,3,2};
Arrays.fill(num,99); 使用后面的 数据 去填充前面传入的数组,可以理解为替换原来的元素
6、equals 比较两个数组元素内容是否完全一致 完全一样返回true 反之返回false
boolean equals = Arrays.equals(arr,arr2);
7、asList 将一组值,转换成list
将数据转换为一个List 集合,返回的 asList 编译类型为 List(接口) ,asList 运行类型为java.util.Arrays#ArrayList 它是Arrays 类的静态内部类
List <Integer> asList = Arrays.asList(2,3,4,5,6);
System.out.println("asList = " + asList);
System类
常见方法
1)exit 退出当前程序 exit(0); 表示直接退出,0表示一个状态,正常状态
2)arraycopy 复制数组元素,比较适合底层调用,一般使用Arrays.copyOf 完成复制数组
int[] src = {1,2,3}; int[] dest = new int [3]; System.arraycopy(src,0,dest,0,3);
System.arraycopy(源数组,从源数组开始拷贝的索引,目标数组,拷贝到目标数组的那个索引,拷贝元素个数);
3)currentTimeMillens 返回当前时间距离1970-1-1 的毫秒数
4)gc 运行垃圾回收机制 System.gc();
BigInteger和BigDecimal类
应用场景:
1、BigInteger适合保存比较大的整形
2.BigDecimal适合保存精度更高的浮点型(小数)
BigInteger和BigDecimal常用方法
1)add 加
2)subtract 减
3)multiply 乘
4)divide 除
A:对于 BigInteger 和 BigDecimal 进行加减乘除的时候,需要使用对应的方法,不能直接进行 + - * /
B:可以创建一个 要操作的 BigInteger 然后进行操作 BigInteger big = new BigInteger("5444494358");
BigDecimal big = new BigDecimal("367.327894739274798");
C:BigDecimal 在进行除法计算时可能抛出ArithmeticException,在调用divide时声明精度
big.divide(big1,BigDecimal.ROUND_CEILING));
日期类
第一代日期类
1、Date 精确到毫秒,代表特定的瞬间
2、SimpleDateFormat 格式和解析日期的类 SimpleDateFormat 格式化和解析日期的具体类。它允许进行格式化(日期 - 》文本)、解析(文本 - 》日期)和规范化
Date d1 = new Date();//获取当前系统时间
这里的Date 类在java.util 包,默认输出格式是国外的方式,所以通常需要进行格式转换
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年mm月dd日 hh:mm:ss E");
String fm = sdf.format(d1);//转换为指定格式的字符串
创建SimpleDateFormat对象,可以指定相应的格式,这里的格式使用的字母是规定好,不能乱写
Date d2 = new Date(948359);//通过指定毫秒数得到时间
String s = “1990年01月01日 12:32:32 星期一”;
Date parse = sdf.parse(s);
可以将格式化的String转化成对应的 Date,
得到Date 仍在输出时,还是按照国外的形式,如果希望指定格式输出,需要转化
在把String - 》Date ,使用的 sdf 格式 需要和你给的String的格式一致,否则抛出转换异常(ParseException)
第二代日期类
1)Calendar类(日历)
2)Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日历)提供了一些方法
1、Calendar类是一个抽象类,并且构造器是私有的
2.可以通过 getInstance() 来获取实例
3、Calendar的月份返回时需加一,因为从零开始编号
4、Calendar 没有提供对应的格式化的类,因此需要程序员自己组合输出、
5、如果我们需要按照24小时进制获取时间,Calendar.Hour - 改为 ->Calendar. HOUR_OF_DAY
第三代日期类
Calendar类存在的不足:
1)可变性:像日期和时间这样的类应该是不可变的
2)偏移性:Date中的年份是从1900年开始的,而月份都是从0开始
3)格式化:格式化只对Date 有用,Calendar不行
4)此外,他们的线程不一定是安全的;不能处理闰秒等(每隔两天,多出1s)
第三代日期类常用方法 jdk8加入
一:LocalDate(日期/年月日)、LocalTime(时间/时分秒)、LocalDateTime(日期时间/年月日时分秒)
LocalDate只包含日期,可以获取日期字段
LocalTime只包含时间,可以获取时间字段
LocalDateTime包含日期+时间,可以获取日期和时间字段
LocalDateTime ldt = LocalDateTime.now(). 获取当前时间
二:DateTimeFormatter 格式日期类
类似于SimpleDateFormat
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(格式);
String str = dft.format(日期对象);
使用DateTimeFormatter 对象来进行格式化
部分格式
三:Instant 时间戳
Instant now = Instant.now(); 通过静态方法 now() 获取表示当前时间戳对象
类似于Date
提供一系列和Date类转换的方式
Instant - - 》Date:
Date date = Date.from(instant); 通过 from() 可以将 Instant 转为 Date
Date - - 》Instant:
Instant instant = date.toInstant(); 通过date的 toInstant() 可以将Date 转为 Instant 对象
提供 plus 与 minus 方法可以对当前时间进行加或者减