1. String
1.1 概述
java.lang.String 字符串类
java 9 之前底层为字节数组(char[]),java 9 开始使用字节数组存储(byte[])
1. 字符串一旦确定,不能修改
2. 为了提高字符串的效率,java虚拟机使用了一种“缓存技术”,字符串常量池
3. 在以字面量形式创建一个字符串对象时,先看字符串常量池中是否已经存在相同的值,如果没有就创建一个, 如果常量池中已经有了,就直接调用该对象即可。所以很多时候字符串类型的比较,也可以使用==,因为他们内存地址都一样(仅限于字面量)
4. 以new的方式创建时,会在堆内存创建字符串,同时也会在常量池中创建该字符串的对象。
1.2 基本使用
public class String_00 {
public static void main(String[] args) {
// String字面量写法,只会在字符串常量池中创建一个对象
String s1 = "123";
String s2 = "123";
String s3 = "1234";
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); // true
System.out.println(s1.equals(s3)); // false
// String创建对象写法,会在堆内存中创建不同对象,同时在常量池中创建对象
// s4和s5会在堆内存中创建不同对象,同时在字符串常量池中创建一个字符串常量
String s4 = new String("12345");
String s5 = new String("12345");
// s6指向常量池
String s6 = "12345";
System.out.println(s4 == s5); // false
System.out.println(s4.equals(s5)); // true
System.out.println(s4 == s6); // false
System.out.println(s4.equals(s6)); // true
// inter():将字符串添加到内部的字符串池中,并返回字符串池中的引用的方法
System.out.println(s4.intern() == s5.intern());
System.out.println(s4.intern() == s6.intern());
}
}
1.3 构造方法
public static void main(String[] args) {
// 1.字面量
String s1 = "abc";
// 2.new对象
String s2 = new String("abc");
// 3.字节数组
byte[] bytes = {97,98,99,100};
// 下标从0开始,传入3个字符
String s3 = new String(bytes,0,3);
System.out.println(s3);
// 全部传入
String s4 = new String(bytes);
System.out.println(s4);
// 4.字符数组
char[] chars = {'a','c','d','f'};
// 下标从0开始,传入2个字符
String s5 = new String(chars,0,2);
System.out.println(s5);
// 全部传入
String s6 = new String(chars);
System.out.println(s6);
}
1.4 常用方法
public static void main(String[] args) {
String str = "hello world";
// 1. char charAt(int index) :获取字符串中对应索引的字符
char c = str.charAt(0);
System.out.println(c);
// 2. boolean endWith(String str): 判断某个字符串是否以指定字符串结尾
System.out.println(str.endsWith("ld"));
// 3. byte[] getBytes():把该字符串转换为字节数组
byte[] b = str.getBytes();
// 4 char[] toCharArray() : 把字符串转换为字符数组
char[] chars = str.toCharArray();
// 5 int indexOf(String str) : 获取指定字符串在该字符串中的索引下标 , 如果不存在则返回-1
// 从左到右的找,如果存在多个符合条件的,则返回第一个符合条件的下标
System.out.println(str.indexOf("h"));
// 传入3,表示从下标3开始往后找
System.out.println(str.indexOf("m", 3));
// 6 int lastIndexOf(String str) : 最后一次出现的索引,找不到返回-1
// 从右往左找
System.out.println(str.lastIndexOf("e"));
// 7. int length():返回字符串长度
System.out.println(str.length());
str = "asdfghjkl deggrt ";
System.out.println(str.length());
// 8. String replace(String a,String b):替换,返回替换后的新字符串
System.out.println(str.replace("g", "!"));
// replaceAll:支持正则表达式
System.out.println(str.replaceAll("g", "!"));
// 9. String[] split(String str):以特定字符串进行分割,返回字符串数组,支持正则表达式
str = "2024-01-15";
String[] strs = str.split("-");
for(int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
// 10.String subString(int index):截取字符串,获取指定索引开始(包含指定索引)到结束的字符串
str = "asdfghjkl awsdd";
// 左闭右开jkl awsdd
System.out.println(str.substring(6));
// 截取某下标到某下标的字符串,左闭右开
System.out.println(str.substring(6, 9));
// 11.String toUpperCase():转为大写并返回
System.out.println(str.toUpperCase());
// 12.String toLowerCase():转为小写并返回
str = "ADGHJK jiann LO";
System.out.println(str.toLowerCase());
// 13.String trim():删除两边(首尾)空格并返回
str = " aws weff ";
String str1 = " aws weff ";
System.out.println(str.trim());
System.out.println(str1);
// 删除所有空格并返回,使用替换把所有空格替换为空
System.out.println(str.replace(" ", ""));
// 14.equals():比较两个字符串是否相同
System.out.println("asd".equals("aaa"));
// 15.equalsIgnore():不区分大小写比较两个字符串是否相同
System.out.println("ABC ij".equalsIgnoreCase("ABC ij"));
// 16.static String valueOf(Object obj):调用对象的toString方法,并对null值进行处理,避免空指针
Object obj = null;
System.out.println(String.valueOf(obj));
}
1.5 注意:
字符串不能频繁的做拼接操作,因为字符串一旦确定不能修改,频繁的拼接字符串效率较低且不利于垃圾回收。
2. StringBuffer和StringBuilder
2.1 概述
StringBuffer和StringBuilder是什么
底层都是char数组,只不过数组可变长,所以当我们需要进行频繁的字符串拼接时可以使用
原理:
预先在内存空间中申请一块空间,足够容纳更多字符,如果预留空间不足,会自动进行扩容,默认初始化长度为16.扩大容量为 length*2 + 2 , 源码是 ( (value.length << 1) + 2;)
StringBuffer 和 StringBuilder的区别:
StringBuffer : 线程安全,在多线程环境下不会出现问题,常用于类中。
StringBuilder : 线程不安全,在多线程环境下,可能出现问题,常用于方法中。
2.2 基本使用
public static void main(String[] args) {
// 创建对象
// StringBuilder sb = new StringBuilder("a");
StringBuilder strBulider = new StringBuilder();
// 尾部添加
strBulider.append("a");
strBulider.append("b").append("c");
// 添加到指定位置
strBulider.insert(2, "c");
// 反转
strBulider.reverse();
// 添加元素个数
System.out.println(strBulider.length());
// 当前容量
System.out.println(strBulider.capacity());
// 转化为String类型
String str = strBulider.toString();
System.out.println(str);
}
3. 包装类
3.1 概述
想要对基本数据类型进行更多操作,怎么办
最方便的方法就是将其封装成对象,因为在对象描述中就可以定义更多的属性和行为 对该基本数据类型进行操作。我们不需要自己去对基本数据类型进行封装,JDK已经为我们封装好了
1. 装箱就是自动将基本数据类型转换为包装器类型
2. 拆箱就是自动将包装器类型转换为基本数据类型
3.2 使用(八种包装类,都覆写了equals 和 toString 及 hashCode方法)
public static void main(String[] args) {
// 基本类型
byte b1 = 10;
short s1 = 4;
int a1 = 11;
long l1 = 123456L;
float f1 = 1.23f;
double d1 = 12.3;
boolean flag1 = true;
char ch = 'a';
// 包装类类型
Byte b2 = new Byte(b1);
Byte b3 = new Byte(b1);
System.out.println(b2.equals(b3));
Short sh = new Short(s1);
Integer a2 = new Integer(a1);
Long l2 = new Long(l1);
Float f2 = new Float(f1);
Double d2 = new Double(d1);
Boolean flag2 = new Boolean(flag1);
Character c = new Character(ch);
m1(b2);
m1(b3);
m1(sh);
m1(a2);
m1(l2);
m1(f2);
m1(d2);
m1(flag2);
m1(c);
}
public static void m1(Object obj) {
System.out.println(obj);
}
3.3 Integer
3.3.1 基本使用
public static void main(String[] args) {
// 最大值
System.out.println(Integer.MAX_VALUE);
// 最小值
System.out.println(Integer.MIN_VALUE);
// 创建对象
Integer i1 = new Integer(11);
// 传入纯数字字符串
Integer i2 = new Integer("12");
// 必须纯数字,否则运行会报错
// Integer i3 = new Integer("12ss");
}
3.3.2 相互转换
public class Integer_02 {
// int --> Integer
Integer i1 = Integer.valueOf(11);
// Integer --> int
int i2 = i1.intValue();
// String --> Integer
Integer i3 = Integer.valueOf("1234");
// Integer --> String
String s1 = i3.toString();
// int --> String
String s2 = 12 + "";
// String --> int
int i4 = Integer.parseInt("1234");
}
3.3.3 常用方法
public static void main(String[] args) {
// 创建对象,可以把int 封装为 Integer类型
Integer i1 = new Integer(11);
// 通过intValue 把包装类 转换为 基本类型
int i2 = i1.intValue();
// 重要 : static int parseInt(String s ) : 把纯数字的字符串转换为int类型
i2 = Integer.parseInt("1234");
double d = Double.parseDouble("112.22");
// static String toBinaryString(int value) : 转换为字符串类的二进制表示法
System.out.println(Integer.toBinaryString(15));
// 转十六进制
System.out.println(Integer.toHexString(15));
// 转八进制
System.out.println(Integer.toOctalString(15));
// 重要 static Integer valueOf(int value) : 把int类型转换为Integer类型
Integer i4 = Integer.valueOf(1234);
Integer i5 = Integer.valueOf("1234");
}
3.3.4 自动装箱和自动拆箱
装箱 : 基本类型到引用类型
拆箱 : 引用类型到基本类型
1.5开始 引入自动装箱和自动拆箱
public static void main(String[] args) {
// 1.5之前装箱
Integer i1 = new Integer(11);
i1 = Integer.valueOf(11);
// 1.5之后拆箱
Integer i2 = 12;
// 1.5之前的拆箱
int i3 = i2.intValue();
// 1.5及以后的拆箱
int i4 = i2;
// 此时 15为int类型,会先自动装箱为Integer类型,然后在向上转型发生多态
m1(15);
}
public static void m1(Object obj) {
System.out.println(obj);
}
3.3.5 深入整形常量池
IntegerCache.cache 是整型常量池,是个保存了256个Integer对象的数组,分别是 -128~127,当我们进行自动装箱或手动调用Integer.valueOf()方法时,会先判断是否符合整型常量池
,如果符合范围,则直接在整形常量池中把提前创建好的对象引用,赋值给他即可,不用再次创建。
public static void main(String[] args) {
// 直接在堆内创建对象
Integer a1 = new Integer(11);
Integer a2 = new Integer(11);
System.out.println(a1 == a2);
System.out.println(a1.equals(a2));
// 自动装箱, 会转型为 Integer.valueOf()
// valueOf 中 进行了整形常量池从操作
// 如果 值 -128~127之间,则不需要创建对象 , 否则 就在堆内存创建对象(new Integer())
Integer a3 = 15;
Integer a4 = 15;
System.out.println(a3 == a4);
Integer a5 = 555;// 等同于 i5 = new Integer(555)
Integer a6 = 555;// 等同于 i5 = new Integer(555)
System.out.println(a5 == a6);
}
4. System
4.1 概述
System类代表系统,系统的很多属性和控制方法都放置在该类中。该类位于java.lang包, 由于该类的构造器是private的,所以无法创建该类对象,也就无法实例化该类。其内部的变量和方法都是静态的,所以可以很方便的调用。
1. System类内部包含in,out,err三个静态变量,分别代表标准输入流,标准输出流和标准错误输出流
2. System类提供的public static long currentTimeMillis(),
用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
3. void exit(int atatus):该方法的作用是退出程序,参数为0为正常退出,
非0代表异常退出,使用该方法可以在图形页面编程中实现程序的退出功能。
4.2 常用方法
public static void main(String[] args) {
// out,err,in 都是System中提供的打印方法
// out 标准输出,默认打印在控制台
System.out.println("控制台打印");
// in 标准输入,默认接受控制太输入
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数");
int n = scanner.nextInt();
// err 错误输出,打印颜色为红色,异步打印
System.err.println("控制台错误形式的输出");
// 获取当前系统对应的毫秒数,可用于统计时间
// 从1970-1-1 8:00:00 到当前时间的毫秒数
long startTime = System.currentTimeMillis();
// 其它事务代码
long endTime = System.currentTimeMillis();
// 耗时
System.out.println(endTime - startTime);
// 建议垃圾回收
System.gc();
// 关闭JVM,0 表示正常退出,一般用于图形化界面
System.exit(0);
}
5. Date
5.1 概述
获取时间和时间操作
java 8之前使用Date,java 8中新引入了LocalDateTime,java 8 之后的版本推荐使用LocalDateTime。
Date和LocalDateTime的区别:
1. Date是java早期引入的日期时间类,位于java.util包中,LocalDateTime是java 8中新引入日期时间类,位于java.time包中。
2. Date是可变类,可以直接修改Date对象的值,而LocalDateTime是不可变类,一旦确定不能修改,如果要修改必须重新创建对象。
3. Date在表示日期和时间时会考虑系统时区,而LocalDateTime只表示日期和时间,不会考虑系统时区,如果需要考虑时区可以使用ZonedDateTime实现。
4. Date类精确到毫秒级,但设计存在问题,容易产生线程安全问题,而LocalDateTime类提供了更好的精确度,可以表示纳秒的时间。
5. Date类Api设计过于老旧,一些方法已经过时,LocalDateTime设计更现代化,直观易用。
5.1 构造方法
public class Date_01 {
public static void main(String[] args) {
// 注意导入的包为java.util.Date;
// 使用Date获取当前系统时间
Date date = new Date();
// Date:Tue Jan 16 19:15:09 CST 2024
System.out.println("Date:" + date);
// 注意导入的包为ava.time.LocalDateTime;
// 使用LocalDateTime获取当前系统时间
LocalDateTime localDateTime = LocalDateTime.now();
// localDateTime:2024-01-16T19:17:34.703
System.out.println("localDateTime:" + localDateTime);
// 创建指定日期和时间的Date对象(年的参数是指需设定的年份减去1900的结果,月的参数是从0开始计数的,所以0表示1月)
// 当前构造方法以过时,不推荐使用
Date specifyDate = new Date(124, 0, 16, 19, 23, 12);
// specifyDate:Tue Jan 16 19:23:12 CST 2024
System.out.println("specifyDate:" + specifyDate);
// 创建指定日期时间的LocalDateTime对象
LocalDateTime specifyLocalDateTime = LocalDateTime.of(2014, 1, 16, 19, 23, 12);
// specifyLocalDateTime:2014-01-16T19:23:12
System.out.println("specifyLocalDateTime:" + specifyLocalDateTime);
// 修改Date对象的时间,Date对象是可变的
date.setHours(12);// 方法已过时
// Date:Tue Jan 16 12:32:32 CST 2024
System.out.println("Date:" + date);
// 修改LocalDateTime对象的时间,LocalDateTime是不可变的,需要创建新对象
LocalDateTime reviseLocalDateTime = LocalDateTime.now().withHour(12).withMinute(24);
// reviseLocalDateTime:2024-01-16T12:24:01.980
System.out.println("reviseLocalDateTime:" + reviseLocalDateTime);
}
}
5.2 格式化
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
// 格式化
// y年 M月 d日 H时 m分 s秒 S毫秒
public class Date_02 {
public static void main(String[] args) throws Exception {
// 将Date对象格式化为字符串
// 创建一个Date类时间对象
Date dateTime = new Date();
// 创建一个SimpleDateFormat对象,指定日期时间的格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS");
// format方法:把时间对象按照对应的格式 进行转换,返回转换后的字符串
String strTime = sdf.format(dateTime);
System.out.println(strTime);
// 将字符串解析为Date对象
// 注:时间格式的字符串必须和SimpleDateFormat指定的格式一致.
strTime = "2024-01-16 11:48:24:316";
// parse方法:把时间格式的字符串转换为Date对象
Date newDate = sdf.parse(strTime);
System.out.println(newDate);
// 将LocalDateTime对象格式化为字符串
// 创建一个LocalDateTime类的时间对象
LocalDateTime now = LocalDateTime.now();
// 创建一个DateTimeFormatter对象,表示要使用的格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SS");
// 调用format()方法,将LocalDateTime对象格式化为字符串
String str = now.format(formatter);
System.out.println(str);
// 将字符串解析为LocalDateTime对象
// 创建一个字符串,表示日期和时间
strTime = "2024-01-16 19:52:38:92";
// 调用parse()方法,将字符串解析为LocalDateTime对象
LocalDateTime localTime = LocalDateTime.parse(strTime,formatter);
System.out.println(localTime);
}
}
5.3 Calendar(获取当前系统日历)
import java.util.Calendar;
public class Calenar_01 {
public static void main(String[] args) {
// 获取当前系统日历
Calendar c = Calendar.getInstance();
// 获取当天是本周的第几天,周日为第一天
int i = c.get(Calendar.DAY_OF_WEEK);
// 获取年
System.out.print(c.get(Calendar.YEAR) + "年");
// 获取月,从0开始,0是一月
System.out.print(c.get(Calendar.MONTH)+ 1 + "月");
// 获取日
System.out.print(c.get(Calendar.DAY_OF_MONTH) + "日" + " ");
// 获取时
System.out.print(c.get(Calendar.HOUR_OF_DAY) + "时");
// 获取分
System.out.print(c.get(Calendar.MINUTE)+ "分");
// 获取秒
System.out.print(c.get(Calendar.SECOND)+ "秒");
}
}
6. Random
6.1 概述
random: 从0开始生成随机数
6.2 使用
public class Random_01 {
public static void main(String[] args) {
// 创建生成器对象
Random random = new Random();
// 在int范围内随机生成一个数
int i = random.nextInt();
System.out.println(i);
// 在10个数内随机生成一个,0~9,不包含10
int result = random.nextInt(10);
System.out.println(result);
// 在10~20间随机生成一个数,包含10和20
result = random.nextInt((20 - 10 + 1)) + 10;
System.out.println(result);
// 在100~150之间随机生成一个数,包含100和150
result = random.nextInt((150 - 100 + 1)) + 100;
System.out.println(result);
// 生成a~z之间的字母
char c = (char)((random.nextInt('z' - 'a' + 1)) + 'a');
System.out.println(c);
}
}
7. BigInteger
7.1 概述
1. Integer作为Java的包装类,能存储的最大整型值为2^31-1,Long类也是有限的,最大为2^61-1,如果要表示再大的整数,不管基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。
2. java.math包的BigInteger可以表示不可变的任意精度整数。BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、 位操作以及一些其他操作。
7.2 常用方法
public BigInteger abs():返回此 BigInteger 的绝对值的 BigInteger。
BigInteger add(BigInteger val) :返回其值为 (this + val) 的 BigInteger
BigInteger subtract(BigInteger val) :返回其值为 (this - val) 的 BigInteger
BigInteger multiply(BigInteger val) :返回其值为 (this * val) 的 BigInteger
BigInteger divide(BigInteger val) :返回其值为 (this / val) 的 BigInteger。整数相除只保留整数部分。
BigInteger remainder(BigInteger val) :返回其值为 (this % val) 的 BigInteger。
BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟(this % val) 的两个 BigInteger 的数组。
BigInteger pow(int exponent) :返回其值为 (thisexponent) 的 BigInteger。
7.3 使用
public class BigInteger_00 {
public static void main(String[] args) {
// 两种对象的创建
BigInteger big = new BigInteger("12");
BigDecimal bigNum = new BigDecimal(15);
// 运算操作
BigDecimal b1 = new BigDecimal(12);
BigDecimal b2 = new BigDecimal(36);
// 结果
BigDecimal b3 = null;
// 加
b3 = b1.add(b2);
System.out.println(b3);
// 减
b3 = b1.subtract(b2);
System.out.println(b3);
// 乘
b3 = b1.multiply(b2);
System.out.println(b3);
// 除(BigDecimal要求除法运算结果必须是一个精确的十进制数,如果结果出现循环小数需要做精度处理)
b3 = b1.divide(b2,2, RoundingMode.HALF_UP);
System.out.println(b3);
// 取余
b3 = b1.remainder(b2);
System.out.println(b3);
}
}
7.4 阶乘(例子)
import java.math.BigDecimal;
public class Number_00 {
public static void main(String[] args) {
System.out.println(test(100));
}
// 100的阶乘
public static BigDecimal test(int n) {
BigDecimal result = new BigDecimal(1);
for (int i = 1; i <= n; i++) {
result = result.multiply(new BigDecimal(i));
}
return result;
}
}