Java常用类详解(包装类,字符串,枚举,文件)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
文章目录
先上脑图
1. 基本类型的包装类
1.1 概念
前面说到对象是面向对象程序设计语言的基本单位
而Java中万物皆对象任何事物都可以抽象为一个类并实例化对象。但是我们经常使用的基本数据类型例如 int 却不是对象那么如果想对基本数据类型的变量进行更多的操作我们该怎么办呢
例如我们想要把 String 类型的变量转换为 int 类型该如何操作呢或者是在集合中只能存放引用类型的变量此时是不是就不能对基本数据类型进行操作呢
于是Java中把基本数据类型包装成一个类此时我们就可以定义更多的属性和方法对基本数据类型的变量进行操作这个类叫做包装类。例如获取类型的最大值
Integer.MAX_VALUE;
总的来说增加包装类的概念有以下的优点
- 实现一些重要的功能例如字符串和基本数据类型的转换
- 有的方法需要传递一个对象作为参数此时包装类解决了基本数据不能作为该方法参数的问题
- 提供了例如获取类型最大值这样的功能
八种基本数据类型分别对应了八种包装类型都位于Java.lang
包中。
基本数据类型 | 包装数据类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
1.2 常用的属性
由于不同包装类的使用方法类似这里用 Integer 类型举例其类中封装了很多的属性和方法这里举例其中最常用的属性和方法具体内容移步 Java API文档查看。
包装类中常用的属性有包装类对应的基本数据类型以及基本数据类型表示的最大值最小值。示例
public class Test {
public static void main(String[] args) {
//常用的属性
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.TYPE);
}
}
1.3 常用的方法
包装类中常用的方法是关于 String 类型和基本数据类型包装数据类型的转换的问题。示例
public class Test {
public static void main(String[] args) {
//常用的方法
//1.把String类型转换为int类型
String str="123";
int num=Integer.parseInt(str);
//2.把String类型转换为Integer类型
Integer integer=Integer.valueOf(str);
//3.把Integer类型转换为String类型
String s=integer.toString();
}
}
1.4 自动装箱和自动拆箱
Java 在 JDK 1.5 版本之后增加了自动装箱和自动拆箱的功能在这之前我们要进行手动的转换。示例
public class Test {
public static void main(String[] args) {
//手动装箱
int a = 10;
Integer integer = new Integer(a);
//手动拆箱
int b = integer.intValue();
}
}
实际上自动拆箱时其底层还是调用了 intValue() 方法而自动装箱时底层调用的是 valueOf() 方法相当于也是像手动装箱时 new Integer(a)
此时我们只需要阅读 JDK 源码即可明白。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
示例自动装箱和自动拆箱
public class Test {
public static void main(String[] args) {
//自动装箱
int a = 10;
Integer integer = a;
//自动拆箱
int b = integer;
}
}
其实在我们的程序中还存在很多隐藏的自动装箱和拆箱例如在使用基本数据类型作为参数传入需要引用变量的方法中其实发生了自动装箱在使用包装类型进行运算时实际上发生了自动拆箱。
示例
public class Test {
public static void main(String[] args) {
//拆箱
int a=10;
Integer integer=a;
integer++;
//装箱
int b=20;
integer.equals(b);
}
}
2. 字符串类
字符串类主要包括了 String
StringBuilder
StringBuffer
类等。其相同点是都可以对字符串进行操作底层都是对字符数组 char[] 进行操作。
2.1 String 类
String 类表示字符串Java中所有字符串常量值例如 “abc” 都是此类的对象。
String 使用了 final 修饰其不可以被继承且类的变量值不可以被修改具有不可变性String 对象的内容使用字符数组 char[] 来存储。
在数据量比较小的时候优先使用 String 类而不是 StringBuilder 类或者 StringBuffer 类。
示例
public class Test {
public static void main(String[] args) {
// 不同构造方法声明String变量
String str1 = "HelloWorld";
String str2 = new String("HelloWorld");
String str3 = "Hello";
// 长度:length()
System.out.println(str1.length() >= str3.length() ? "str1长" : "str3长");
//获得字符串的第1个字符e
System.out.println(str1.charAt(1));
// 判断是否以指定字符开头
if (str1.startsWith(str3)) {
// str3第一次出现在str1中的位置
int startIndex = str1.indexOf(str3);
// 截取子串
String str1Sub = str1.substring(startIndex, str3.length() - 1);
String str2Sub = str2.substring(startIndex, str3.length() - 1);
System.out.println("两个字符串是否相等" + str1Sub.equals(str2Sub));
}
}
}
既然已经存在 String 类来操作字符串了为什么还需要其他两个类呢我们来看下面的案例
public class Test {
public static void main(String[] args) {
String str = " ";
for(int i=0;i<100;i++){
str += "hello";
}
}
}
程序在执行第五行时相当于将原来的 String 类引用指向的对象拿出来与 hello 进行字符相加操作再存进另一个新的 String 对象中再让 string 变量指向新生成的对象。其实这样做是非常浪费时间和空间的。
2.2 StringBuilder类
不同于 String 类的是StringBuilder 类为可变字符串解决 String 在字符变更方面的低效问题低层依赖字符数组实现两者都是 final 修饰的都不可被继承。
示例
public class Test {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("Hello");
System.out.println(builder);
//可以拼接几乎所有能看到的东西,并返回自身
System.out.println(builder.append("World"));
//在指定位置追加字符串
System.out.println(builder.insert(10, "你好"));
//获取指定字符
System.out.println(builder.charAt(2));
//设置某个字符
builder.setCharAt(2,'A');
System.out.println(builder);
//删除指定的字符
builder.deleteCharAt(2);
System.out.println(builder);
//替换指定位置的字符串
System.out.println(builder.replace(9,11,"世界"));
//删除这个区间里的字符串
System.out.println(builder.delete(9,11));
//倒转串
System.out.println(builder.reverse());
//StringBuilder转String
String string = builder.toString();
System.out.println(string);
//String转StringBuilder
StringBuilder builder1 = new StringBuilder(string);
System.out.println(builder1);
}
}
由于 StringBuilder 类不用做线程同步检查所以存在线程不安全的问题。
2.3 StringBuffer类
StringBuffer 类的构造方法和用法与 StringBuilder 类相同。两者都是可变字符串可以认为是线程安全的StringBuilder类做线程同步检查效率较低。
两者在常用的方法的使用上十分相似不做赘述。
示例
//测试String,StringBuilder,StringBuilder的执行速度
public class Test {
public static void main(String[] args) {
String s1="";
StringBuilder s2 = new StringBuilder();
StringBuffer s3 = new StringBuffer();
long l = System.currentTimeMillis();//获取系统时间
for (int i = 0; i < 100000; i++) {//这个是十万次,String实在太慢了还浪费内存,设多了电脑跑不过来
s1=s1.concat("拼接");
}
long l1 = System.currentTimeMillis();
System.out.println("String用时:"+(l1-l));
l = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {//下面两个是一百万次
s2.append("拼接");
}
l1 = System.currentTimeMillis();
System.out.println("StringBuilder用时:"+(l1-l));
l = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
s3.append("拼接");
}
l1 = System.currentTimeMillis();
System.out.println("StringBuffer用时:"+(l1-l));
}
}
运行结果
2.4 StringBuilder 的扩容机制
示例
public class Test {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("Test");
System.out.println(builder.length());
//底层数组长度默认为16+传进去的字符串长度
System.out.println(builder.capacity());
for (int i = 0; i < 16; i++) {
builder.append('a');
}
//在数组没装满之前数组长度不变
System.out.println(builder.capacity());
builder.append("123456");
//在长度超出之后,数组会扩容到原来的2倍+2的长度
System.out.println(builder.capacity());
}
}
如上面所示在 StringBuilder 类的对象中底层的数组长度默认为传入的字符串长度加 16在字符串没有达到这个长度时数组长度不变如果超出这个长度数组会扩容到原来的 2 倍加 2 的容量。
3. 数字常用类
3.1 Math 类
Math 类中定义了一些数学运算的方法例如计算最大值最小值绝对值等方便程序的运算。
示例
public class Test {
public static void main(String[] args) {
System.out.println(Math.max(10,2));//获得最大值
System.out.println(Math.min(10, 5));//获得最小值
System.out.println(Math.abs(-20));//获得绝对值
System.out.println(Math.random());//生成0-1的随机数
}
}
3.2 Radom 类
Math 类中虽然为我们提供了产生随机数的方法 Math.random
但是通常我们需要的随机数范围并不是[0, 1)之间的 double 类型的数据这就需要对其进行一些复杂的运算。我们可以使用另外一种方式得到随机数即 Random 类这个类是专门用来生成随机数的。
示例
import java.util.Random;
public class Test {
public static void main(String[] args) {
Random random = new Random();
System.out.println(random.nextInt(100));//获取100以内的随机整数
System.out.println(random.nextFloat());//获取浮点随机
}
}
在JDK源码中的 Math.Radom 方法
private static final class RandomNumberGeneratorHolder {
static final Random randomNumberGenerator = new Random();
}
public static double random() {
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
可以看到Math.random 底层调用的就是 Random 的nextDouble() 方法。
4. 枚举类
所有的枚举类型隐性地继承自 java.lang.Enum
。枚举实质上还是类而每个被枚举的成员实质就是一个枚举类型的实例他们默认都是 public static final 修饰的所以我们可以直接通过枚举类型名使用它们。
在定义一组常量时可以尽量使用枚举类型枚举就是用来表示有限个数的定值不能输入别的参数时使用限制用户输入数据。
示例
public class Test {
public static void main(String[] args) {
//枚举就是用来表示有限个数的定值,不能输入别的参数时使用,限制用户输入数据
TestAddPerson person = new TestAddPerson("张三", Gender.女);
System.out.println(person);
}
}
class TestAddPerson{
String name ;
Gender gender;
public TestAddPerson(String name, Gender gender) {
this.name = name;
this.gender = gender;
}
public TestAddPerson() {
}
@Override
public String toString() {
return "TestAddPerson{" +
"name='" + name + "\'" +
", gender=" + gender +
'}';
}
public String getName() {
return name;
}
public Gender getGender() {
return gender;
}
}
枚举类型
public enum Gender {
男,女;
}
5. 日期类
5.1 Date 类
Date类 是日期类位于 java.util.Date包同时在 java.sql.Date 中也存在日期类两者同时使用时不能两者同时导包会出现歧义。
在Java.sql 包中的日期类有三个子类分别是 Date 类只含有年月日Time 类只含有十分秒和 TimeStamp 类时间戳既含有年月日有含有时分秒。
示例
import java.util.Date;
//日期类
public class Test {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
//获取1970年到现在的毫秒数
System.out.println(date.getTime());
java.sql.Date date1 = new java.sql.Date(System.currentTimeMillis());
//只有年月日
System.out.println(date1);
String t="2019-8-20";
//将字符串转化为日期
java.sql.Date date2 = java.sql.Date.valueOf(t);
System.out.println(date2);
//只含有时分秒
java.sql.Time time=new java.sql.Time(System.currentTimeMillis());
System.out.println(time);
}
}
5.2 DateFormat 类
DateFormat 表示格式化日期类format() 方法用于格式化日期并返回字符串类型。同样我们还可使用 parse() 方法将字符串型日期转化为日期类。
示例
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(String[] args) throws ParseException {
Date date = new Date();
System.out.println(date);
//创建格式化日期格式为:"yyyy-MM-dd hh:mm:ss"。因为DateFormat是一个抽象类不能new对象,所以new一个他的子类
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//格式化这个日期类,返回String字符串
String format = dateFormat.format(date);
//2023-01-11 12:14:42
System.out.println(format);
//这个日期格式一定要和上面注册的格式一样"yyyy-MM-dd hh:mm:ss"
String timer = "2010-12-10 9:15:29";
//将字符串日期转换成日期类,会抛出一个异常
Date parse = dateFormat.parse(timer);
System.out.println(parse);
}
}
5.3 Calender 类
Calender 类表示日历类位于 java.util 包中日期类和日历类可以相互转化。需要注意的是在获取月份时一般是从 0 开始的。
示例
import java.util.*;
public class Test {
public static void main(String[] args) {
//Calendar这也是一个抽象类,需要new他的子类
Calendar calendar = new GregorianCalendar();
System.out.println(calendar);
//获取年月日
System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MARCH));//月是从0开始的
System.out.println(calendar.get(Calendar.DATE));
//获取当前月最大天数
System.out.println(calendar.getActualMaximum(Calendar.DATE));
//日期类和日历类相互转化
Date time = calendar.getTime();//日历类转日期类
Calendar calendar1 = new GregorianCalendar();
calendar1.setTime(time);//日期类转日历类
}
}
6. System 类
System 类代表当前 Java 程序的运行平台程序不能创建 System 类的对象且该类没有构造方法System 类提供了一些类变量和类方法允许直接通过 System 类来调用这些类变量和类方法。
示例
currentTimeMills():获取当前时间毫秒值
exit(int status):退出JVM0表示非异常退出
gc():运行垃圾回收处理机制系统会在某个不确定的时间调用该方法会调用finalize()进行垃圾回收
arrayCopy(Object[] srcArr,int srcPos,Object[] desArr,int destPos,int len):数组复制
7. File 类
Java中 File 类位于 java.io 包中表示文件和文件目录文件夹的抽象形式我们可以使用 File 类中的方法对计算机中的文件和文件夹进行增删查判断等的操作。
Java 属于跨平台运行的语言所以 File 类的操作与系统无关任何操作系统都可以使用 File 类来操作计算机的文件和文件夹。File 类用于对文件和文件夹的增删查等操作与文件的读写无关如果要进行读写操作必须要使用 IO 流。
7.1 静态成员变量
File 类中一共封装了四个成员变量分别是两个路径分隔符和两个默认名称分隔符
示例
import java.io.File;
import static java.io.File.*;
public class Test {
public static void main(String[] args) {
System.out.println(pathSeparator);
System.out.println(pathSeparatorChar);
System.out.println(separator);
System.out.println(separatorChar);
}
}
为什么要定义分隔符的静态成员变量呢
路径中的每级目录之间用一个路径分隔符隔开而路径分隔符与系统有关Windows系统使用 \
而Linux系统使用 /
表示为了方便Java程序的跨平台运行所以定义了该静态变量所以程序中涉及到分隔符的地方一定要慎用以免引起错误。
什么是相对路径绝对路径
绝对路径是一个固定以盘符开始的路径例如"C\\ user \\ Java \\Test.java"
而相对路径是相对于某一个位置开始的路径例如相对于当前项目的根目录"Test.java"
不同的系统中每级目录分隔使用的分隔符不同Windows 使用 \
为了避免和转义字符产生冲突使用 \\
。
7.2 File类的构造方法
在学习一个类是了解他的构造方法是十分重要的
在 File 类的构造方法中既可以传入绝对路径也可以传入相对路径同时创建对象时只是把字符串路径的封装在 File 类中所以不用考虑路径是否真实存在。
示例
import java.io.File;
public class Test {
public static void main(String[] args) {
File file=new File("C:\\user\\a.txt");
System.out.println(file);
}
}
我们还可以把字符串路径拆分为父路径和子路径两个路径都可以变化大大增加了对路径操作的灵活性。
示例
import java.io.File;
public class Test {
public static void main(String[] args) {
File file=new File("C:\\user\\","a.txt");
System.out.println(file);
}
}
同时还可以传入一个 File 和一个字符串类型这样就可以使用 File 类的方法先对路径进行操作在实例化 File 类对象。
示例
import java.io.File;
public class Test {
public static void main(String[] args) {
File file=new File("C:\\user\\");
File file1=new File(file,"a.txt");
System.out.println(file1);
}
}
7.3 File 类常用的方法
File 用来操作文件和目录主要进行的操作有获取判断增删遍历等这里我们先来看一下获取和判断其中构造方法中传入的路径叫做抽象路径。示例
import java.io.File;
public class Test {
public static void main(String[] args) {
//获取
File file=new File("C:\\Users\\24091\\Desktop\\Demo\\JavaDemo\\Java.jpg");
File file1=new File("Java.jpg");
//返回此抽象路径名的绝对路径字符串
String absolutePath = file.getAbsolutePath();
String absolutePath1 = file1.getAbsolutePath();
System.out.println(absolutePath);
System.out.println(absolutePath1);
//将此抽象路径名转换为路径名字符串
String path = file.getPath();
String path1 = file1.getPath();
System.out.println(path);
System.out.println(path1);
//返回由此抽象路径名表示的目录或者文件名
String name = file.getName();
String name1 = file1.getName();
System.out.println(name);
System.out.println(name1);
//表示由此抽象路径名表示的文件的长度
long length = file.length();
System.out.println(length);
//判断
//测试此抽象路径名表示的文件或者目录是否存在
File file2=new File("a.txt");
System.out.println(file.exists());
System.out.println(file2.exists());
//测试此抽象路径名表示的是不是目录前提是该文件或者目录是否存在
File file3=new File("C:\\Users\\24091\\Desktop\\Demo\\JavaDemo");
System.out.println(file.isDirectory());
System.out.println(file3.isDirectory());
//测试此抽象路径名表示的是不是文件前提是该文件或者目录是否存在
System.out.println(file.isFile());
System.out.println(file3.isFile());
System.out.println(file2.isFile());
System.out.println(file2.isDirectory());
}
}
关于 File 类对系统目录和文件的增删操作重点学习由于其操作成功一般返回 boolean 值所以程序两次运行结果可能不同。
示例
import java.io.File;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
/*
创建文件:当且仅当该抽象路径下不存在此文件时创建新的文件
文件不存在创建文件返回true;文件存在不创建返回false
创建文件的抽象路径必须存在否则抛出异常
*/
File file=new File("C:\\Users\\24091\\Desktop\\Demo\\新建文件.txt");
File file1=new File("C:\\Users\\24091\\Desktop\\Demo\\新建文件");//创建时要看类型而不是名字
boolean newFile = file.createNewFile();
System.out.println(newFile);
/*
创建文件夹:mkdir创建由此抽象路径名命名的目录;mkdirs同前者但是可以创建多级目录
文件夹不存在创建文件夹返回true;文件夹存在不创建返回false;抽象路径名不存在返回false
*/
File file2=new File("C:\\Users\\24091\\Desktop\\Demo\\testDemo");
File file3=new File("C:\\Users\\24091\\Desktop\\Demo\\testDemo.txt");//创建时看类型不看名称
boolean mkdir = file2.mkdir();
System.out.println(mkdir);
File file4=new File("C:\\Users\\24091\\Desktop\\Demo\\testDemo\\11\\22");
boolean mkdirs = file4.mkdirs();
System.out.println(mkdirs);
/*
删除文件和目录:删除由此抽象路径名表示的文件或目录
文件/文件夹存在删除成功返回true;文件夹中有内容不会删除返回false抽象路径名不存在返回false
*/
File file5=new File("C:\\Users\\24091\\Desktop\\Demo\\新建文件");
boolean delete = file5.delete();
System.out.println(delete);
File file6=new File("C:\\Users\\24091\\Desktop\\Demo\\testDemo");
boolean delete1 = file6.delete();
System.out.println(delete1);
File file7=new File("C:\\Users\\24091\\Desktop\\Demo\\testDemo\\11\\22");
boolean delete2 = file7.delete();
System.out.println(delete2);
}
}
常见的问题和注意事项都已经注释在程序中不过多赘述。这里只是举例常用 API 的使用详细的内容使用参见 API 文档创作不易如果你读到这里说明你已经学会了Java常用类三连哦
下期见。