Java常用类
多查API帮助文档
1 String
- 引用数据类型
- 双引号括起来的都是String对象
- Java规定,字符串不可变。也就是说“abc",自出生到死亡都不能变为”abcd"
String的存储原理
-
凡是双引号括起来的,都直接存储在方法区的常量池中
原因是字符串在开发中使用太频繁,为了执行效率。
-
例如
String s1 = "abc"; //这里“abc”是在常量池中,对象地址直接给栈里的s1; String s2 = new String("xyz"); //这里"xyz"也是在常量池,new是在堆中创建对象,然后把对象地址给栈
-
注意:垃圾回收器不会释放常量
-
内存图
-
例如
package com.string; public class UserTest { public static void main(String[] args) { //User user = new User(110,"张三"); String s1 = "xyz"; //"xyz"在常量池,不会重建 String s2 = "xyz"; System.out.println(s1 == s2); //true String s3 = new String("abc"); String s4 = new String("abc"); System.out.println(s3 == s4); //false System.out.println(s3.equals(s4)); //true System.out.println("abc" == s3); //false System.out.println("abc".equals(s3));//true } }
String的构造方法
String s1 = "xyz";
String s2 = new String("abc");
String s3 = new String(bytes); //byte[] bytes = {97, 98, 99};//abc
String s4 = new String(bytes, 1, 2); //bc
String s5 = new String(chars); // char[] chars = {'我', '是', '中', '国', '人'};//我是中国人
String类的常用方法
-
char charAt(int index)
找char的某个位置值
package com.string; public class Test05 { public static void main(String[] args) { char c = "中国人".charAt(1); System.out.println(c); //国 } }
-
int compareTo(String anotherString)
比较两个字符串大小,按照字典顺序
package com.string; public class Test05 { public static void main(String[] args) { int x = "xyz".compareTo("xyz"); System.out.println(x); //相等为0 int y = "abcd".compareTo("abce"); System.out.println(y); //小于-1 int z = "abce".compareTo("abcd"); System.out.println(z); //大于1 } }
-
boolean contains(CharSequence s)
前面字符串是否包含后面子字符串
package com.string; public class Test05 { public static void main(String[] args) { System.out.println("xyz.java".contains("z.j")); //true } }
-
boolean endsWith(String suffix)
判断当前字符串是否以某个字符串结尾
package com.string; public class Test05 { public static void main(String[] args) { System.out.println("abc.txt".endsWith(".txt")); //T System.out.println("abc.txt".endsWith(".java")); //F } }
-
boolean equals(Object anObject)
比较字符串是否相等
-
boolean equalsIgnoreCase(String anotherString)
忽略大小写比较字符串
package com.string; public class Test05 { public static void main(String[] args) { System.out.println("xyz".equalsIgnoreCase("xYz")); //T } }
-
byte[ ] getBytes()
将字符串转成byte数组
package com.string; import java.nio.charset.StandardCharsets; public class Test05 { public static void main(String[] args) { byte[] bytes = "xyz".getBytes(StandardCharsets.UTF_8); for (int i = 0; i < bytes.length; i++) { System.out.println(bytes[i]); } /* 120 121 122 */ } }
-
int indexOf(int ch)
判断某个子字符串在当前字符串中第一次出现处的索引
package com.string; public class Test05 { public static void main(String[] args) { System.out.println("xdhuehwvdhdhbdcdhj".indexOf("hwvd")); //5 } }
-
boolean isEmpty()
判断字符串是否为空
package com.string; public class Test05 { public static void main(String[] args) { String s =""; String x ="d"; System.out.println(s.isEmpty()); //T System.out.println(x.isEmpty()); //F } }
-
int length()
计算字符串长度
注意:面试题
判断数组长度呵判断字符串长度都是length。不同处
判断数组长度是length属性,判断字符串长度是length()方法。
-
int lastIndexOf(String str)
计算子字符串出现的最后一次索引
package com.string; public class Test05 { public static void main(String[] args) { System.out.println("dhehdiuhjshisbhje".lastIndexOf("j")); //15 } }
-
String replace(char oldChar, char newChar)
替换
String replace(CharSequence target, CharSequence replacement)
package com.string; public class Test05 { public static void main(String[] args) { String s = "http://baidu.com".replace("http","https"); System.out.println(s); //https://baidu.com } }
-
String[] split(String regex)
拆分字符串
package com.string; public class Test05 { public static void main(String[] args) { String[] s = "1998-01-01".split("-"); for (int i = 0; i < s.length; i++) { System.out.print(s[i]+" "); //1998 01 01 } } }
-
boolean startsWith(String prefix)
判断字符串以某个字符串开始
System.out.println("http://hexo.guyuer.xyz".startsWith("http")); //T
-
String substring(int beginIndex)
截取字符串
System.out.println("http://baidu.com".substring(7)); //baidu.com System.out.println("http://baidu.com".substring(7,10)); //bai,左闭右开
-
char[ ] toCharArray()
将字符串转换为char数组
char[] s1 = "我是中国人".toCharArray(); for (int i = 0; i < s1.length; i++) { System.out.print(s1[i]+" "); //我 是 中 国 人 }
-
String toLowerCase()
转换小写
System.out.println("aBCYFGYHUgfgh".toLowerCase()); //abcyfgyhugfgh
-
String toUpperCase()
转换大写
System.out.println("aBCYFGYHUgfgh".toUpperCase()); //ABCYFGYHUGFGH
-
String trim()
去除字符串前后空白
System.out.println(" hello world ".trim()); //hello world
-
String中唯一的静态方法static String valueOf(boolean b)
将非字符串转换为字符串
tring s2 = String.valueOf(true); System.out.println(s2); //true //valueOf自动调用了对象的toString方法,但是对象没有重写toString方法,输出的还是内存地址 String s5 = String.valueOf(new User()); System.out.println(s5); //com.string.User@1b6d3586
println()就是调用的valueOf方法。由于valueOf方法调用了toString方法,使用输出引用类型的时候,自动调用toString。
面试题
String为什么是不可变的?
答案:我看过源码,String类中有一个byte数组,这个byte数组被final修饰,因为数组一旦被创建后长度不可变,被final修饰的引用一旦指向 某个对象后,不可再指向其他对象,所以String是不可变的!
StringBuffer或者StringBuilder为什么是可变的?
答案:我看过源码,StringBuffer/StringBuilder内部是一个byte数组,这个byte数组没有被final修饰,StringBuffer/StringBuilder的初始容量我记得是16,当存满之后会进行扩容,底层调用了数组拷贝方法System.arraycopy()…是这样扩容的,所以StringBuffer/StringBuilder适合于使用字符串的频繁拼接操作.
2 StringBuffer
使用“+”进行频繁字符串拼接会占用大量内存
字符串拼接建议使用StringBuffer或StringBuilder
StringBuffer本质是一个byte数组,初始容量16,通过append追加,数组满了会自动扩容。
优化:创建StringBuffer的时候确定合适的大小,尽量减少扩容次数
字符串缓冲区对象
package com.stringbuffer;
public class Test01 {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("a");
stringBuffer.append("b");
stringBuffer.append("c");
System.out.println(stringBuffer); //abc
}
}
StringBuilder
作用和用法与StringBuffer一样
区别:
StringBuffer中的方法都有synchronized关键字修饰。表示StringBuffer在多线程环境下运行是安全的
StringBuilder中的方法没有synchronized关键字修饰。表示StringBuffer在多线程环境下运行是不安全的
package com.stringbuffer;
public class Test02 {
public static void main(String[] args) {
StringBuilder s = new StringBuilder();
s.append("heooo");
s.append(223);
System.out.println(s); //heooo223
}
}
3 基本类型对应的8个包装类
java对应8种基本数据类型,提供8中包装类,属于引用类型,父类是Object,SUN公司写好的
需求:
调用 dosome()方法的时候需要传一个数字进去
但是数字属于基本数据类型,而doSome()方法参数的类型是 Object
可见 doSome()方法无法接收基本数据类型的数字。那怎么办呢?可以传一个数字对应的包装类进去。
例如:
package com.integer; public class Test01 { public static void main(String[] args) { MyInt myInt = new MyInt(1); doSome(myInt); } public static void doSome(Object obj){ System.out.println(obj); } } /* package com.integer; public class MyInt { int value; public MyInt(int value) { this.value = value; } public MyInt() { } @Override public String toString() { return String.valueOf(value); //数字变成字符串 } } */
包装类型:记住
基本数据类型 | 包装类型 | 父类 | 拆箱方法 |
---|---|---|---|
byte | java.lang.Byte | Number | byte byteValue() |
short | java.lang.Short | Number | short shortValue() |
int | java.lang.Integer | Number | int intValue() |
long | java.lang.Long | Number | long longValue() |
float | java.lang.Float | Number | float floatValue() |
double | java.lang.Double | Number | double doubleValue() |
boolean | java.lang.Boolean | Object | boolean booleanValue() |
char | java.lang.Character | Object |
构造方法
package com.integer;
public class Test03 {
public static void main(String[] args) {
Integer integer = new Integer(123);//int类型
Integer integer1 = new Integer("123");//字符串
System.out.println(integer);
System.out.println(integer1);
}
}
访问包装类常量,获取最大最小值
package com.integer;
public class Test04 {
public static void main(String[] args) {
//访问包装类常量,获取最大最小值
System.out.println("int最大值:"+Integer.MAX_VALUE); //2147483647
System.out.println("int最小值:"+Integer.MIN_VALUE); //-2147483648
System.out.println("Byte最大值:"+Byte.MAX_VALUE); //127
}
}
JDK1.5后,支持自动装箱
package com.integer;
public class Test05 {
public static void main(String[] args) {
Integer x = 100; //自动装箱
int y = x; //自动拆箱
System.out.println(x);
System.out.println(y);
System.out.println(x+12);//运算时自动拆箱
Integer a = new Integer(100);
Integer b = new Integer(100);
//双等号不会触发自动拆箱
System.out.println(a == b); //false
}
}
整数型常量池
数字没超过byte取值范围,会自动放到整数型常量池
为提高执行效率,Java将[-128,127]之间所有包装对象提前创建好,放到了一个方法去的整数型常量池中,这个区间的数据不需要再new, 直接从整数型常量池中取出.
package com.integer;
public class Test05 {
public static void main(String[] args) {
Integer x = 100; //自动装箱
int y = x; //自动拆箱
System.out.println(x);
System.out.println(y);
System.out.println(x+12);//运算时自动拆箱
Integer a = new Integer(100);
Integer b = new Integer(100);
//双等号不会触发自动拆箱
System.out.println(a == b); //false
}
}
Integer中的常用方法
new Integer()/intValue()方法
装箱拆箱方法:不是一个数字,不能包装成Integer,会报NumberFormatException.
package com.integer;
public class Test07 {
public static void main(String[] args) {
Integer i = new Integer(1000);
System.out.println(i);
//不是一个数字,不能包装成Integer
//NumberFormatException
Integer j = new Integer("gh");
}
}
回顾经典异常
- 空指针异常:NullPointerException
- 类型转换异常:ClassCastException
- 数组下标越界异常:ArrayIndexOutOfBoundsException
- 数字格式化异常:NumberFormatEXception
parseInt()方法
String转int,网页文本框输入数字,格式是字符串,存入数据库时需要转为int
package com.integer;
public class Test07 {
public static void main(String[] args) {
int x = Integer.parseInt("12345");
System.out.println(x);
}
}
类型转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VKWMNcX0-1632293928789)(https://i.loli.net/2021/09/18/HgIEpXFq4dxLRDY.png)]
package com.integer;
public class Test07 {
public static void main(String[] args) {
//int-->String
int i = 100;
String s1 = i + "";
String s2 = String.valueOf(i);
//String-->int
int j = Integer.parseInt("123");
//int-->Integer
Integer i1 = new Integer(123);
Integer i2 = Integer.valueOf(1234);
//Integer-->int
int i3 = i1.intValue();
//String-->Integer
Integer i4 = Integer.valueOf("123");
//Integer-->String
String s3 = String.valueOf(i4);
}
}
4 日期类
获取系统当前时间
调用Date()无参构造
Date---->String
String---->Date
package com.date;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test01 {
public static void main(String[] args) throws Exception{
//获取系统当前时间
// 直接待用无参构造
Date nowTime = new Date();
System.out.println(nowTime); //Mon Sep 20 15:10:01 CST 2021
//日期格式化
/*
yyyy 年
MM 月
dd 日
HH 时
mm 分
ss 秒
SSS 毫秒
*/
//连接符自己组织
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String nowTimeStr = sdf.format(nowTime);
System.out.println(nowTimeStr); //2021/09/20 15:17:49
//日期字符串转换成Date格式
String nowTimeStr2 = "2021/09/20 15:17:49";
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); //日期格式要和字符串格式一样
Date nowDate2 = sdf2.parse(nowTimeStr2);
System.out.println(nowDate2); //Mon Sep 20 15:17:49 CST 2021
}
}
统计方法执行所用时间
package com.date;
public class Test02 {
//获取1970年1月1日 00:00:00:000至今总毫秒数
//1s =1000SSS
public static void main(String[] args) {
long timeMillis = System.currentTimeMillis();
System.out.println(timeMillis); //1632123007219
//统计方法执行所用时间
//开始结束各记录一次
long begin = System.currentTimeMillis();
print();
long end = System.currentTimeMillis();
System.out.println("耗费时长:"+(end-begin)+"毫秒"); //耗费时长:8毫秒
}
public static void print() {
for (int i = 0; i < 1000; i++) {
System.out.println("i="+i);
}
}
}
System类简单总结
- System.out out是System类的静态变量
- System.out.println() println方法不是System类的,是PrintStream类的方法。
- System.gc() 建议启动垃圾回收器
- System.currentTimeMillis() 获取1970年1月1日 00:00:00:000至今总毫秒数
- System.exit(0) 退出JVM
日期格式化
符号 | 日期 |
---|---|
yyyy | 年 |
MM | 月 |
dd | 日 |
HH | 时 |
mm | 分 |
ss | 秒 |
SSS | 毫秒 |
Date类的有参构造
package com.date;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test03 {
public static void main(String[] args) {
//Date有参,参数为1970 1 1 00:00:00:000的格林威治时间,至今毫秒
Date date = new Date(1);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
String format = simpleDateFormat.format(date);
System.out.println(format); //1970-01-01 08:00:00:001 北京是东八区,差8小时
//获取昨天同一时间
Date date1 = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000);
String format1 = simpleDateFormat.format(date1);
System.out.println(format1); //2021-09-19 15:51:42:156
}
}
5 数字类
数字格式化
java.text.DecimalFormat;
package com.number;
import java.text.DecimalFormat;
public class Test01 {
//数字格式化
public static void main(String[] args) {
//DecimalFormat负责数字格式化
/*
数字格式
# 任意数字
, 千分位
. 小数点
0 不够补零
*/
DecimalFormat decimalFormat = new DecimalFormat("#,###.##");
String format = decimalFormat.format(123456.922);
System.out.println(format); //123,456.92
DecimalFormat decimalFormat1 = new DecimalFormat("#,###.0000");
String format1 = decimalFormat1.format(1234567456.87);
System.out.println(format1); //1,234,567,456.8700
}
}
符号 | 含义 |
---|---|
# | 任意数字 |
, | 千分位 |
. | 小数点 |
0 | 不够补零 |
BigDecimal
大数据,精度极高,不属于基本数据类型,属于Java对象,引用数据类型,是SUN提供的一个类。专门用在财务软件中。
财务软件中double不够用。
package com.number;
import java.math.BigDecimal;
public class Test02 {
public static void main(String[] args) {
BigDecimal v1 = new BigDecimal(100);
BigDecimal v2 = new BigDecimal(200);
//求和
//不能简单的v1+v2因为都是引用类型
BigDecimal add = v1.add(v2);
System.out.println(add); //300
//减法
BigDecimal su = v2.subtract(v1);
System.out.println(su);
}
}
6 随机数类
Random()类;
package com.random;
import java.util.Arrays;
import java.util.Random;
//生成5个不重复的随机数[0-100]
public class Test02 {
public static void main(String[] args) {
Random random = new Random();
int[] ints= new int[5];
//默认值改为-1,防止随机数0 重复
for (int i = 0; i < ints.length; i++) {
ints[i] = -1;
}
int index = 0;
while (index < ints.length){
int i = random.nextInt(101);
System.out.println("生成随机数:"+i);
//判断数组中有没有i
if(!contains(ints, i)){
ints[index++] = i;
}
}
//遍历数组
for (int i = 0; i < ints.length; i++) {
System.out.print(ints[i]+ " ");
}
}
//写方法判断是否包含
public static boolean contains(int[] arr, int key){
/*//对数组排序
Arrays.sort(arr);
//二分法查找
return Arrays.binarySearch(arr, key) >= 0; //二分法存在为下标,不存在为-1 返回true为存在。
有bug,数组排序了,原数组顺序乱了
*/
for (int i = 0; i < arr.length; i++) {
if(key == arr[i]){
return true;
}
}
return false;
}
}
7 枚举
枚举:一枚一枚可以列举出来的,才建议使用枚举类型。
枚举编译之后也是生成 class文件
枚举也是一种引用数据类型
枚举中的每一个值可以看做是常量。
大于两种情况建议使用枚举:颜色,四季,星期
package com.enumm;
//包名是标识符
//不能是关键字
public class Test01 {
public static void main(String[] args) {
Result r = divid(10,2);
System.out.println(r == Result.SUCCESS ? "成功": "失败");
}
public static Result divid(int a, int b){
try{
int c = a/b;
return Result.SUCCESS;
}catch (Exception e){
return Result.FAIL;
}
}
}
enum Result{
SUCCESS, FAIL;
}