常用类
包装类(Wrapper)
包装类的分类
- 八种基本数据类型相应的引用类型—包装类
- 有了类的特点,就可以调用类中的方法
(下面六种的父类为Number)
包装类与基本数据类型的转换
装箱:基本数据类型—>包装类型
拆箱:包装类型—>基本数据型
自动装箱底层调用的是valueOf方法,比如Integer.valueOf()
代码如下:
public class Wrapper01 {
public static void main(String[] args) {
//演示 int <--> Integer 的装箱拆箱
//jdk5以前是手动装箱和拆箱
//手动装箱 int -> Integer
int n1 = 100;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueOf(n1);
//手动拆箱 Integer -> int
int num1 = integer.intValue();
//jdk5后,就可以自动拆箱和自动装箱
int n2 = 200;
//自动装箱 int -> Integer
Integer integer2 = n2; //底层使用的是 Integer.valueOf(n2)
//自动拆箱 Integer -> int
int num2 = integer2; //底层仍然使用的是 intValue()方法
}
}
包装类型和String类型的相互转换
public class WrapperString {
public static void main(String[] args) {
//包装类(Integer) -> String
Integer i = 100; //自动装箱
//方式1
String str1 = i + "";
//方式2
String str2 = i.toString();
//方式3
String str3 = String.valueOf(i);
//String -> 包装类
String str4 = "1234";
//方式1
Integer i2 = Integer.parseInt(str4); //使用到自动装箱
//方式2
Integer i3 = new Integer(str4); //构造器
}
}
Integer练习题:
public void method(){
//手动装箱
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j); //false
//自动装箱
/*底层: Integer.valueOf(1);通过底层代码可得:
在 -128到127 范围内的数字,是直接返回;
如果超出则 new Integer(xx);
*/
Integer m = 1;
Integer n = 1;
System.out.println(m == n); //true
//自动装箱
Integer x = 128;
Integer y = 128;
System.out.println(x == y); //false
}
Integer.valueOf(1)底层:
BigInteger和BigDecimal
- BigInteger适合保存比较大的整型
- BigDecimal适合保存精度更高的浮点型(小数 )
String类
String类的理解和创建对象
- String对象用于保存字符串,也就是一组字符序列
- 字符串常量对象是用双引号括起来的字符序列
- 字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节
- String类较常用构造方法
String s1 = new String();
String s2 = new String(“xxx”);
String s3 = new String(char[] a);
String s4 = new String(char[] a, int startIndex, int count)
String s5 = new String(byte[] b);
- String类实现了Serializable接口 【String 可串行化:可以在网络上传输】, 实现了Comparable接口 【String 对象可以比较大小】
- String 是 final 类,不能被其它类继承
- String 有属性 private final char value[ ]; 用于存放字符串内容
- 注意: value 是一个final类型,不可以修改(地址不可修改);value不能指向新的地址,但是单个字符内容可以变化
public class String01 {
public static void main(String[] args) {
final char value[] = {'a','b','c'};
char[] v2 = {'t','o','m'};
value[0] = 'z';
//value = v2; 无法将值赋给 final 变量 'value'
System.out.println(value[0]); //输出z
}
}
两种创建String对象的区别
方式一:直接赋值 String s = “hyk”;
方式二:调用构造器 String s2 = new String(“hyk”);
- 方式一:先从常量池查看是否有“hyk”数据空间,如果有直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址
- 方式二:先在堆中创建空间,里面维护了value属性,指向常量池的hyk空间。如果常量池中没有hyk,重新创建,如果有则直接通过value指向。最终指向的是堆中的空间地址
public class StringTest3 {
public static void main(String[] args) {
String a = "hyk"; //a指向常量池的hyk
String b = new String("hyk"); // b指向堆中对象
System.out.println(a.equals(b)); //true
System.out.println(a == b); //false
System.out.println(a == b.intern()); //true
System.out.println(b == b.intern()); //false
/*
解析:b.intern 是指向常量池中的hyk,而b是指向堆中的,
所以不会相等。而a也是指向常量池中的hyk,则a == b.intern();
当调用intern方法时,如果池已经包含一个等于此String对象的字符串
则返回池中的字符串(b.intern 输出 hyk)。否则,将此String对象
添加到池中,并返回此String对象的引用
总结:b.intern()方法最终返回的是常量池的地址(对象)
*/
}
}
字符串特性
- String是一个final类,代表不可变的字符序列
- 字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的
- String s1 = “ab” + “cd”;常量相加看常量池
- String s1 = a+b; 变量相加,是在堆中
String类的常用方法
public class StringMethod {
public static void main(String[] args) {
String str = "Hello, World!"; //有空格
int length = str.length(); // 返回 13 length(): 返回字符串的长度
// charAt(int index): 返回指定索引位置的字符
char charAtIndex = str.charAt(7); // 返回 'W'
// substring(int beginIndex): 返回从指定索引开始到字符串末尾的子字符串
String substring = str.substring(7); // 返回 "World!"
// split(String regex): 将字符串根据指定正则表达式分割成字符串数组。
String sentence = "Java is a programming language";
String[] words = sentence.split("\\s"); // 使用空白字符作为分隔符
// 结果:words = ["Java", "is", "a", "programming", "language"]
// format(String format, Object... args): 使用指定的格式字符串和参数创建一个格式化字符串。
String formattedString = String.format("Hello, %s! Today is %dth day of %s.", "John", 12, "March");
// 结果:formattedString = "Hello, John! Today is 12th day of March."
// substring(int beginIndex, int endIndex): 返回从指定索引开始到指定索引结束的子字符串
// (不包含 endIndex 处的字符)
String sub = str.substring(7, 12); // 返回 "World"
// equals(Object obj): 比较字符串是否与指定对象相等
String anotherString = "Hello, World!";
boolean isEqual = str.equals(anotherString); // 返回 true
// equalsIgnoreCase(String anotherString): 比较字符串是否与指定字符串相等,忽略大小写
boolean isEqualIgnoreCase = str.equalsIgnoreCase("hello, world!"); // 返回 true
// startsWith(String prefix): 检查字符串是否以指定前缀开头
boolean startsWith = str.startsWith("Hello"); // 返回 true
// endsWith(String suffix): 检查字符串是否以指定后缀结尾
boolean endsWith = str.endsWith("!"); // 返回 true
// indexOf(String str): 返回指定子字符串在字符串中第一次出现的索引
int indexOfWorld = str.indexOf("World"); // 返回 7
// replace(char oldChar, char newChar): 替换字符串中的指定字符。
String replacedString = str.replace('o', '0'); // 返回 "Hell0, W0rld!"
// toLowerCase() 和 toUpperCase(): 将字符串转换为小写或大写形式。
String lowercase = str.toLowerCase(); // 返回 "hello, world!"
String uppercase = str.toUpperCase(); // 返回 "HELLO, WORLD!"
// trim(): 去除字符串两端的空白字符。
String spacedString = " Hello, World! ";
String trimmedString = spacedString.trim(); // 返回 "Hello, World!"
}
}
关于format方法的测试题
public class Test {
/*
编写java程序,输入形式为: Hu Lu Ya 的人名,以Ya,Hu .L的形式打印
其中.L是中间单词的首字母
*/
public static void main(String[] args) {
String name = "Hu Lu Ya";
printName(name);
}
/* 思路分析:
1.对输入的字符串进行分割 split(" ")
2.对得到的String[] 进行格式化String.format()
3.对输入的字符串进行校验即可
*/
public static void printName(String str){
if (str == null){
System.out.println("你输入的字符串不能为空");
return; //结束方法
}
String [] names = str.split(" "); //调用split对str进行字符串分割
if (names.length != 3){ //如果空格不等于3则结束方法
System.out.println("您输入的字符串格式错误");
return;
}
//String.format()方法用于将字符串格式化,以便根据指定的格式和参数生成新的字符串。
String format = String.format("%s,%s .%c", names[2],names[0],names[1].toUpperCase().charAt(0));
/* 设置成字符串,字符串, .字符的格式
names[1].toUpperCase().charAt(0)
names[1] 为 Yi 通过toUpperCase()将字符串全部转成大写
通过charAt(0)单独调用出Y
*/
System.out.println(format);
}
}
StringBuilder类和StringBuffer类
String类是保存字符串常量的。每次更新都需要重新开辟空间,效率较低。java提供了StringBuilder和StringBuffer来增强String的功能,并提高效率
StringBuilder
1.一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。此类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。它比StringBuffer要快
2.StringBuilder 上主要操作是 append 和 insert 方法。可以重载这些方法,以接收任何类型的数据
3.StringBuilder允许字符串的内容在不创建新的对象的情况下进行修改。与String类不同,StringBuilder是可变的,因此在需要频繁修改字符串内容的场景下,使用StringBuilder可以提高性能。
StringBuilder常用方法
public class StringBuilderExample {
public static void main(String[] args) {
// 创建一个 StringBuilder 对象并初始化
StringBuilder sb = new StringBuilder("Hello");
// 追加字符串到末尾
sb.append(", World!");
System.out.println(sb);// sb = "Hello, World!"
// 在指定位置插入字符串
sb.insert(5, " Awesome");
System.out.println(sb);// sb = "Hello Awesome, World!"
// 删除指定范围内的字符
sb.delete(6, 15);
System.out.println(sb);// sb = "Hello, World!"
// 替换指定范围内的字符串
sb.replace(6, 14, "Universe");
System.out.println(sb);// sb = "Hello Universe"
// 反转字符串内容
sb.reverse();
System.out.println(sb);// sb = "esrevinU olleH"
// 获取最终的字符串
String result = sb.toString(); //esrevinU olleH
}
}
StringBuffer
可变的字符序列,可对字符串内容进行增删
很多方法与String相同,但StringBuffer是可变长度的
StringBuffer是一个容器
String与StringBuffer
1.String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低 // private final char value[];
2.StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高 // char[] value;
示例代码:
public class StringAndStringBuffer {
public static void main(String[] args) {
//String ——> StringBuffer
String str = "hello hyk";
//方式1 使用构造器 返回的才是StringBuffer对象 对str本身没有影响
StringBuffer stringBuffer1 = new StringBuffer(str);
//方式2 使用append方法
StringBuffer stringBuffer2 = new StringBuffer();
stringBuffer2 = stringBuffer2.append(str);
//StringBuffer ——> String
StringBuffer stringBuffer3 = new StringBuffer("胡怿铠");
//方式1 使用 StringBuffer 提供的 toString 方法
String str2 = stringBuffer3.toString();
//方式2 使用构造器来转换
String str3 = new String(stringBuffer3);
}
}
StringBuffer常用方法
public class StringBufferMethod {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("Hello");
//增
s.append(','); // "Hello,"
s.append("葫芦鸭"); // "Hello,葫芦鸭"
s.append("张三").append(100).append(true).append(10.5);
System.out.println(s);
//输出: Hello,葫芦鸭张三100true10.5
/* 删
删除索引为 >=start && <end 处的字符
删除11~14的字符(包含11,不包含14)
*/
s.delete(11,14);
System.out.println(s); //Hello,葫芦鸭张三true10.5
/* 改
使用 陈佳琪 替换 索引9~11的字符
(一般情况下包含9 不包含11)
把 张三 替换成 陈佳琪
*/
s.replace(9,11,"陈佳琪");
System.out.println(s); //Hello,葫芦鸭陈佳琪true10.5
/* 查
查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
*/
int indexOf = s.indexOf("陈佳琪");
System.out.println(indexOf); //9
/* 插入
在索引为9的位置插入 赵敏
索引9为 陈 在 陈 之前插入
原来索引为9的内容自动后移
*/
s.insert(9,"赵敏");
System.out.println(s); //Hello,葫芦鸭陈敏陈佳琪true10.5
//长度
System.out.println(s.length()); //22
}
}
String、StringBuffer、StringBuilder的比较
- StringBuffer和StringBuilder非常相似,均代表可变的字符序列,方法也一样
- String:不可变字符序列,效率低,但复用率高
- StringBuffer:可变字符序列,效率较高(增删),线程安全
- StringBuilder:可变字符序列,效率最高,线程不安全
Math类
基本介绍:Math类包含用于执行基本数学运算的方法。
public class MathMethod {
public static void main(String[] args) {
// abs 求绝对值
int number1 = Math.abs(-12333);
System.out.println(number1); //12333
// pow 求幂
double number2 = Math.pow(2,3); //2的三次方
System.out.println(number2); //8.0
// ceil 向上取整,返回 >= 该参数的最小整数
double number3 = Math.ceil(3.1);
System.out.println(number3); //4.0
// floor 向下取整,返回 <= 该参数的最大整数
double number4 = Math.floor(3.1);
System.out.println(number4); //3.0
// round 四舍五入
long number5 = Math.round(3.6);
System.out.println(number5); //4
// sqrt 求开方
double number6 = Math.sqrt(9.0);
System.out.println(number6); //3.0
//random 求随机数 random默认返回0~1之间的一个随机小数
for (int i = 0; i < 10; i++) {
System.out.println(Math.random());
}
}
}
Arrays类
Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索)
- toString 返回数组的字符串形式
- sort排序 (自然排序和定制排序)
- binarySearch 通过二分搜索法进行查找,要求必须排好序
示例代码:
public class ArrayMethod {
public static void main(String[] args) {
Integer [] i1 = {-1,-2,22,13,1};
//直接使用Arrays.toString方法,显示数组
System.out.println(Arrays.toString(i1));
//输出 [-1, -2, 22, 13, 1]
//演示 sort 方法的使用
Integer arr[] = {1,-1,8,12,-3};
/*进行排序
1.可以使用冒泡排序,
也可以直接使用Arrays提供的sort方法排序
2.因为数组是引用类型,所以通过sort排序后,
会直接影响实参 arr
3.sort是重载的,可以通过传入一个
接口 Comparator 实现定制排序
*/
System.out.println("====排序前====");
System.out.println(Arrays.toString(arr));
Arrays.sort(arr); //自然排序
System.out.println("====排序后====");
System.out.println(Arrays.toString(arr));
//定制排序
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer)o1;
Integer i2 = (Integer)o2;
return i2 - i1;
}
});
System.out.println("===通过定制排序从大到小===");
System.out.println(Arrays.toString(arr));
/* 冒泡排序
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if (arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
*/
//使用 binarySearch 进行二分查找 要求数组必须有序 不存在则返回-1
Integer numbers[] = {1,3,22,28,37};
int index = Arrays.binarySearch(numbers,37);
System.out.println("你所查找的数字索引是"+index);
// copyOf 数组元素的复制
//从arr数组中,拷贝arr.length个元素到 newArr 数组中
Integer newArr[] = Arrays.copyOf(arr,arr.length);
//如果拷贝的长度 > arr.length 就在新数组后面增加 null
//拷贝长度 < 0 则会抛出异常
System.out.println("====拷贝完毕后====");
System.out.println(Arrays.toString(newArr));
// fill 数组元素的填充
Integer num[] = {9,2,1};
//使用 99 去填充 num 数组,可以理解成是替换原来的元素
Arrays.fill(num,99);
System.out.println("====填充完毕后====");
System.out.println(Arrays.toString(num));
// 输出[99, 99, 99]
// equals 比较两个数组元素内容是否完全一致
Integer arr1[] = {2,-1,8,12,-3};
Integer arr2[] = {1,-1,8,12,-3};
// 如果 arr 和 arr2 数组元素一样,则返回true
boolean equals = Arrays.equals(arr1,arr2);
System.out.println(equals);
// asList 将一组值,转成List
// asList方法,会将(2,3,4,5,6,1)数据转成一个List集合
List asList = Arrays.asList(2,3,4,5,6,1);
System.out.println(asList);
// asList 运行类型 class java.util.Arrays$ArrayList
System.out.println(asList.getClass());
}
}
Arrays测试题
public class ArraysTest {
public static void main(String[] args) {
Book [] books = new Book[4];
books[0] = new Book("红楼梦",12.9);
books[1] = new Book("西游记",22.9);
books[2] = new Book("水浒传",13.8);
books[3] = new Book("三国演义",30.8);
//price 从大到小
Arrays.sort(books, new Comparator<Book>() {
//是对Book数组排序,因此 o1,o2就是Book对象
@Override
public int compare(Book o1, Book o2) {
double Val = o2.price - o1.price;
//按照书名长度:return o2.name.length() - o1.name.length()
//如果发现结果不一样,只需要修改返回的 -1 和 1
if (Val > 0)
return -1;
else if (Val < 0) {
return 1;
}else
return 0;
}
});
System.out.println(Arrays.toString(books));
}
}
class Book{
String name;
double price;
public Book(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
System类
- exit 退出当前程序
- arraycopy:复制数组元素,比较适合底层使用,一般使用Arrays.copyOf完成复制数组
- currentTimeMillens:返回当前事件距离 1970-1-1的毫秒数
- gc:运行垃圾回收机制 System.gc();
public class SystemDemo {
public static void main(String[] args) {
//arraycopy
int arr[] = {1,2,3};
int copy[] = new int[3]; // copy数组当前是 {0,0,0}
/* arr 代表 源数组
srcPOS:表示从哪一个索引开始拷贝,0 代表从索引0开始
copy:目标数组,即源数组的数据拷贝到的数组
destPos:把源数组的数据拷贝到 目标数组的哪个开始索引
length:从源数组拷贝多少个数据到目标数组
*/
System.arraycopy(arr,0,copy,0,3);
System.out.println(Arrays.toString(copy));
//输出:[1, 2, 3]
// currentTimeMillis:返回当前事件距离 1970-1-1的毫秒数
System.out.println(System.currentTimeMillis());
//输出:1710295960452
//gc:运行垃圾回收机制
System.gc();
//exit退出当前程序
System.out.println("ok1"); //输出
System.exit(0); // 0 表示一个状态 正常的状态
System.out.println("ok2"); //不输出,程序已退出
}
}
Date类
第一代日期类——Date类
- Date:精确到毫秒
- SimpleDateFormat() 自定义日期格式
示例代码:
public class DateDemo {
public static void main(String[] args) throws ParseException {
Date date1 = new Date(); //获取当前系统的时间
System.out.println(date1);
// Wed Mar 13 10:17:14 CST 2024
Date date2 = new Date(123414); //通过指定毫秒数得到时间
System.out.println("date2="+date2); //获取某个时间对应的毫秒数 date2=Thu Jan 01 08:02:03 CST 1970
//自定义日期格式 SimpleDateFormat()
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
String format = sdf.format(date1); // format:将日期转换成指定格式的字符串
System.out.println(format);
//2024年03月13日 10:17:14 星期三
//可以把一个格式化的 String 转换成对应的 Date
String s1 = "2024年02月07日 04:38:03 星期三";
Date parse = sdf.parse(s1);
System.out.println(parse);
//Wed Feb 07 04:38:03 CST 2024
}
}
第二代日期类——Calendar类(日历)
- Calendar类是一个抽象类,并且它的构造器是私有的
- 可以通过 getInstance() 来获取实例
示例代码:
public class CalendarDemo {
public static void main(String[] args) {
// Calendar calendar = new Calendar(); 报错 Calendar构造器私有
Calendar c = Calendar.getInstance();
System.out.println(c);
//获取日历对象的某个日历字段 月要 +1 因为Calendar返回月的时候,是按 0 返回
System.out.println("年:"+ c.get(Calendar.YEAR));
System.out.println("月:"+ c.get(Calendar.MONDAY));
System.out.println("日:"+ c.get(Calendar.DAY_OF_MONTH)+1);
System.out.println("小时:"+ c.get(Calendar.HOUR));
System.out.println("分钟:"+ c.get(Calendar.MINUTE));
System.out.println("秒:"+ c.get(Calendar.SECOND));
//Calendar没有提供对应的格式化方法/类,所以需要自己编写
System.out.println(c.get(Calendar.YEAR)+"-"+c.get(Calendar.MONDAY)+"-"+c.get(Calendar.DAY_OF_MONTH));
// 输出 2024-2-13
}
}
第三代日期类——time类
解决前两代的问题,Java 8 引入了新的日期和时间 API,位于java.time包中。
特点: 不可变且线程安全,引入了新的类,如 LocalDate
、LocalTime
、LocalDateTime
、ZonedDateTime
等。
方法: 提供了丰富的方法,支持时区、格式化、持续时间等更为复杂的时间操作。
格式化日期:
DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH小时mm分ss秒");
示例代码:
public class LocalDateDemo {
public static void main(String[] args) {
//第三代日期 使用 now() 返回表示当前日期时间的对象
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
//单独获取年月日
System.out.println(ldt.getYear());
System.out.println(ldt.getMonth());
System.out.println(ldt.getDayOfMonth());
//格式化日期类 DateTimeFormatter格式化日期类
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH小时mm分ss秒");
String format = dateTimeFormatter.format(ldt);
System.out.println(format);
// 2024年02月07日 17小时17分27秒
//通过静态方法 now() 获取当前对象的时间戳对象
Instant now = Instant.now();
System.out.println(now);
// 2024-02-07T09:20:30.888Z
//通过 from 把 Instant 转成 Date
Date date = Date.from(now);
//通过 date 的 toInstant() 方法 可以把 date 转成 Instant
Instant instant = date.toInstant();
}
}