java 常用类
一,包装
1、基础数据类型包装类
1,基本数据类型和包装类型(Object 类)
基本数据类型 包装类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
2,==与equals()方法
2.1, == 的核心规则
== 是关系运算符,基本类型比值,引用类型比内存地址
它的比较逻辑分两种情况:
基本数据类型(byte/short/int/long/float/double/char/boolean):直接比较变量的实际值是否相等(比如 int a=10; int b=10; a==b 结果为 true)。、
int a = 10;
int b = 10;
System.out.println(a == b); // 输出 true
引用数据类型(类 / 接口 / 数组 / String 等):
比较变量中存储的引用地址(即对象在堆内存中的内存地址),只有当两个引用指向同一个对象时,== 才返回 true(这就是你说的 “存储位置是否是同一个” 的场景)。
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // 输出 false
//由于 str1 和 str2 指向不同的内存对象,即使内容相同,== 也会返回 false。
特殊情况:字符串常量池
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // 输出 true
//String 类型的字面量(直接赋值)会存储在字符串常量池中,相同的字面量可能指向同一对象:
// 此时 s1 和 s2 引用的是常量池中的同一个对象,因此 == 返回 true。
2.2,equals()方法的核心规则
在Java中,equals()方法是用于比较两个对象是否相等的关键方法。使用equals()方法需要重写该方法和 hashCde()方法
以下是其核心规则和实现要点:
作用对象:只能用于引用数据类型(基本数据类型没有这个方法)。
equals() 是方法:默认比地址,重写后可比较对象内容(如 String、Integer 等类已重写)
对称性(Symmetry)
对于任何非空引用x和y,x.equals(y)必须与y.equals(x)返回相同的结果。如果x.equals(y)返回true,那么y.equals(x)也必须返回true。
自反性(Reflexivity)
对于任何非空引用x,x.equals(x)必须返回true。即一个对象必须等于其自身。
传递性(Transitivity)
对于任何非空引用x、y和z,如果x.equals(y)返回true且y.equals(z)返回true,那么x.equals(z)也必须返回true。
一致性(Consistency)
对于任何非空引用x和y,多次调用x.equals(y)必须一致地返回相同的结果,前提是对象中用于比较的信息未被修改。
非空性(Non-nullity)
对于任何非空引用x,x.equals(null)必须返回false。即任何对象与null比较时都应返回false。
使用==检查两个对象是否是同一个引用。如果是,直接返回true。
if (this == obj) return true;
检查传入的对象是否为null,或是否与当前对象的类型不匹配。
if (obj == null || getClass() != obj.getClass()) return false;
将传入的对象转换为当前类型,并逐个比较关键字段是否相等。对于基本类型使用==,对于引用类型使用equals()。
MyClass other = (MyClass) obj;
return field1 == other.field1 && Objects.equals(field2, other.field2);
2.3 ==与equals()比较
class student1 {
private Integer age ;
private String name ;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
student1 class1 = (student1) o;
return age.equals(class1.age) && name.equals(class1.name);
}
@Override
public int hashCode() {
int result = age.hashCode();
result = 31 * result + name.hashCode();
return result;
}
}
//重写equals ,hashCode方法
==和equals
== equals
基本类型 值
引用类型 内存地址 内容
3 ,hashCode()方法
3.1 hashCode()
hashCode()是Java中的一个本地方法,它的定义在java.lang.Object类中:
//hashCode() 返回的是 int 类型的十进制整数,底层存储为二进制,哈希表常用十六进制处理哈希值;
定义:hashCode() 是 Object 类中定义的一个native 方法,返回一个int 类型的整数
返回一个int 类型的整数(哈希值),这个值代表了对象在内存中的 “哈希特征”,主要用于哈希表(比如 HashMap、HashSet、HashTable 等 )中快速定位对象,提升查找效率。
使用hashCode()方法需要重写该方法:
因为查询的结果的默认是改数据的内存地址没有比较性
3.2equals()和hashCode()区别
equals() 用于比较两个对象的内容是否相等。默认情况下,Object 类中的 equals() 方法比较的是对象的内存地址(即引用是否相同),但可以通过重写该方法来实现基于对象属性的逻辑比较。
hashCode() 返回对象的哈希码值,用于支持哈希表(如 HashMap、HashSet)的高效操作。哈希码是一个整数,用于快速定位对象在哈希表中的存储位置。
如果两个对象equals相等,那么这两个对象的HashCode一定也相同,
两个对象的hashCode相同,不代表两个对象就相同,只能够说明这两个对象“存放在同一个篮子里”。
4,toString()方法
4.1 toString()方法的核心概念
toString() 本质是一个对象的字符串表示方法,作用是将非字符串类型(如对象、数字、数组等)转换为可读的字符串形式。
-
在 Java 中:所有类都默认继承自
Object类,Object类自带toString()方法,默认返回类名类的全限定名 + @ + 对象哈希值的十六进制,通常需要重写才能得到有意义的结果。 -
在 JavaScript 中:几乎所有数据类型(包括基本类型)都有
toString()方法,默认实现更友好(如数字123调用toString()会返回"123"),也可自定义对象的toString()。
4.2 使用 toString()方法
使用 toString()方法时候一般都需要重写 ,直接输出属性内容
//重写前
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
//重写后
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
JavaScript 中的 toString()
// 数字转字符串
let num = 123;
console.log(num.toString()); // 输出:"123"
// 布尔值转字符串
let bool = true;
console.log(bool.toString()); // 输出:"true"
// 数组转字符串(默认用逗号分隔)
let arr = [1, 2, 3];
console.log(arr.toString()); // 输出:"1,2,3"
二,包装
1包装类
1.1包装类概述
java针对八种基本数据类型定义了相应的包装类,有了类的特点就可以调用类中的方法操作该数据,基本类型对应的包装
类如下
基本数据类型 包装类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
2 Integer 类
2.1Integer概述
Integer封装了一个int类型的属性,并提供了操作该属性的方法
2.2 Integer构造方法
//传入int类型创建Integer类型
publicInteger(intvalue)
//传入String类型创建Integer类型
publicInteger(Strings)
//publicInteger(intvalue):根据int值创建Integer对象(过时)
Integeri1=newInteger(100);
System.out.println(i1);
//publicInteger(Strings):根据String值创建Integer对象(过时)
Integeri2=newInteger("100");
//Integeri2=newInteger("abc");//NumberFormatException
System.out.println(i2);
2.3 Integer成员方法
//以int类型返回该Integer的值
publicintintValue()
//以long类型返回该Integer的值
publiclonglongValue()
//以float类型返回该Integer的值
publicfloatfloatValue()
//以double类型返回该Integer的值
publicdoubledoubleValue()
//返回一个表示该Integer值的String对象
publicStringtoString(int i)
//比较两个Integer对象的值是否相等
publicbooleanequals(Object obj)
//比较两个Integer对象的值是否相等
publicintcompareTo(Integer anotherInteger)
//返回保存指定的String的值的Integer对象
publicstaticIntegervalueOf(String s)
//将字符串参数作为有符号的十进制整数进行解析
publicstaticintparseInt(String s)
2.4 int和String类型的相互转换
int转换为String
-方式一:直接在数字后加一个空字符串
-方式二:通过String类静态方法valueOf()
public static void main(String[]args){
//int--->String
int number=100;
//方式1
String s1 = number+"";
System.out.println(s1);
//方式2
//public static String valueOf(inti)
String s2 =String.valueOf(number);
System.out.println(s2);
System.out.println("--------");
}
String转换为int
方式一:先将字符串数字转成Integer,再调用valueOf()方法
方式二:通过Integer静态方法parseInt()进行转换
public class StringToIntDemo {
public static void main(String[] args) {
// String--->int
String s = "100";
// 方式1:String---Integer---int(先转包装类,再转基本类型)
Integer i = Integer.valueOf(s);
// public int intValue():将Integer包装类对象转为int基本类型
int x = i.intValue();
System.out.println(x); // 输出:100
// 方式2:直接通过静态方法转为int基本类型
// public static int parseInt(String s)
int y = Integer.parseInt(s);
System.out.println(y); // 输出:100
}
}
2.5自动拆箱和自动装箱
Java 中有基本数据类型(如 int, double, boolean)和对应的包装类(如 Integer, Double, Boolean)
基本类型不是对象,不能直接参与面向对象的操作(比如放入集合);包装类是对象,可以,但使用起来不如基本类型方便。
自动装箱:JVM 自动将基本数据类型转换为对应的包装类对象的过程。
自动拆箱:JVM 自动将包装类对象转换为对应的基本数据类型的过程。
自动装箱(Autoboxing)和自动拆箱(Unboxing)
public class AutoBoxingUnboxingDemo {
public static void main(String[] args) {
// ------------- 自动装箱 -------------
// 场景1:基本类型赋值给包装类变量(int -> Integer)
int basicInt = 100;
Integer wrapperInt = basicInt; // 自动装箱:等价于 Integer.valueOf(100)
// 场景2:基本类型放入集合(集合只能存对象,自动装箱)
List<Integer> numList = new ArrayList<>();
numList.add(200); // 自动装箱:int 200 → Integer 200
// ------------- 自动拆箱 -------------
// 场景1:包装类赋值给基本类型变量(Integer -> int)
Integer wrapperNum = new Integer(300);
int basicNum = wrapperNum; // 自动拆箱:等价于 wrapperNum.intValue()
// 场景2:包装类参与算术运算(自动拆箱为基本类型后计算)
Integer a = 5;
Integer b = 10;
int sum = a + b; // a和b先拆箱为int,再相加,结果赋值给sum
System.out.println("a + b = " + sum); // 输出:a + b = 15
// 场景3:包装类与基本类型比较(包装类拆箱后比较)
Integer c = 100;
int d = 100;
System.out.println(c == d); // 输出:true(c拆箱为int后和d比较)
}
}
自动拆箱和装箱的底层原理:
自动装箱:是编译器调用valueOf将原始类型值转换成对象。
自动拆箱:是编译器调用intValue()这类的方法将对象转换成原始类型值。
//注意
//空指针风险:如果包装类对象是null,自动拆箱会抛出NullPointerException:
Integer nullInt = null;
int num = nullInt; // 运行时抛出NullPointerException
//Integer默认缓存-128~127范围内的对象,超出范围后==比较会有坑:
Integer x = 127;
Integer y = 127;
System.out.println(x == y); // true(用缓存对象)
Integer m = 128;
Integer n = 128;
System.out.println(m == n); // false(新创建对象,==比较地址)
System.out.println(m.equals(n)); // true(equals比较值,推荐用这个)
装箱/拆箱
public class WrapperClassDetail {
public static void main(String[] args) {
// 1. 自动装箱/拆箱(最常用)
int a = 10;
Integer aWrapper = a; // 自动装箱:int → Integer
int aBasic = aWrapper; // 自动拆箱:Integer → int
// 2. 字符串转基础类型(核心方法:parseXxx())
byte b = Byte.parseByte("127"); // byte范围:-128~127
short s = Short.parseShort("32767"); // short范围:-32768~32767
int i = Integer.parseInt("2147483647"); // int最大值
long l = Long.parseLong("9223372036854775807"); // long最大值
float f = Float.parseFloat("3.14");
double d = Double.parseDouble("9.8");
char c = Character.valueOf('A'); // Character无parseChar(),需用valueOf
boolean bool = Boolean.parseBoolean("true"); // 非"true"(忽略大小写)都返回false
// 3. 常用常量
System.out.println("int最大值:" + Integer.MAX_VALUE); // 2147483647
System.out.println("int最小值:" + Integer.MIN_VALUE); // -2147483648
System.out.println("byte最大值:" + Byte.MAX_VALUE); // 127
// 4. 包装类的比较(新手坑!)
Integer num1 = 127;
Integer num2 = 127;
System.out.println(num1 == num2); // true(-128~127缓存池)
Integer num3 = 128;
Integer num4 = 128;
System.out.println(num3 == num4); // false(超出缓存池,新建对象)
System.out.println(num3.equals(num4)); // true(equals比较值,推荐用这个)
}
}
三,字符串类
1,String类
1.1 String 类的核心特性
首先要明确String类的几个关键属性,这是理解它的基础:
不可变性:String对象一旦创建,其内容(字符序列)就不能被修改。这是String最核心的特性,底层是因为String类被final修饰,且存储字符的数组char[] value也是private final的。
字符串常量池:Java 为了节省内存,会把字符串字面量(如"hello")存储在 JVM 的常量池中,相同字面量只会创建一个对象,复用内存。
值传递:String作为引用类型,但因不可变性,实际使用中表现出 “类似基本类型” 的传递特性。
public class StringBasicDemo {
public static void main(String[] args) {
// 1. 字符串常量池复用
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true(指向常量池同一个对象)
// 2. new String会创建新对象(堆内存),不使用常量池
String s3 = new String("hello");
System.out.println(s1 == s3); // false(地址不同)
System.out.println(s1.equals(s3)); // true(值相同,equals比较内容)
// 3. 不可变性:看似修改,实际是创建新对象
String s4 = "java";
s4 += "script"; // 不是修改原对象,而是创建新的"javascript"对象
System.out.println(s4); // 输出:javascript
// 原"java"对象仍存在,s4只是指向了新对象
}
}
1.2 String 类的常用方法
public class StringMethodsDemo {
public static void main(String[] args) {
String str = " Hello Java World! ";
// 1. 去除首尾空格:trim()(JDK11+可用strip(),支持全角空格)
String trimStr = str.trim();
System.out.println(trimStr); // 输出:Hello Java World!
// 2. 按指定字符分割:split()
String[] splitArr = trimStr.split(" ");
for (String s : splitArr) {
System.out.println(s); // 依次输出:Hello、Java、World!
}
// 3. 获取子串:substring(起始索引, 结束索引)(左闭右开)
String subStr = trimStr.substring(6, 10);
System.out.println(subStr); // 输出:Java
// 4. 查找字符/字符串位置:indexOf()(找不到返回-1)
int index = trimStr.indexOf("Java");
System.out.println(index); // 输出:6
// 5. 替换字符/字符串:replace()
String replaceStr = trimStr.replace("Java", "Python");
System.out.println(replaceStr); // 输出:Hello Python World!
// 6. 转换大小写:toUpperCase()/toLowerCase()
String upperStr = trimStr.toUpperCase();
System.out.println(upperStr); // 输出:HELLO JAVA WORLD!
// 7. 判断是否包含子串:contains()
boolean isContain = trimStr.contains("World");
System.out.println(isContain); // 输出:true
// 8. 判断字符串是否为空/空白:isEmpty()/isBlank()(JDK11+)
String emptyStr = "";
System.out.println(emptyStr.isEmpty()); // 输出:true
String blankStr = " ";
System.out.println(blankStr.isBlank()); // 输出:true(JDK11+)
// 9. 获取字符串长度:length()
int len = trimStr.length();
System.out.println(len); // 输出:16
}
}
1.3 字面量和构造方法的区别
字面量(Literal):直接写出值的语法形式(比如 5、"hello"、true),是创建数据最简洁的方式,属于 “直接量”。
String str1 = "hello"; 直接给str1赋值
构造方法(Constructor):通过 new 类名() 的方式创建对象 / 数据,是调用类的构造函数来实例化,属于 “显式实例化”。
String str2 = new String("hello");//创建一个str2的对象
字面量 和 构造方法 的地址

public class LiteralVsConstructor {
public static void main(String[] args) {
// 1. 字面量创建 String
String str1 = "hello";
// 2. 构造方法创建 String
String str2 = new String("hello");
// 核心差异1:内存位置
// str1 存在【字符串常量池】(节省内存,复用相同值)
// str2 存在【堆内存】(新对象,即使值相同也会新建)
String str3 = "hello";
System.out.println(str1 == str3); // true(常量池复用,地址相同)
System.out.println(str1 == str2); // false(地址不同)
System.out.println(str1.equals(str2)); // true(值相同)
// 核心差异2:性能/内存
// 字面量:复用常量池,内存占用少、速度快
// 构造方法:每次new都新建对象,内存占用多、速度慢
}
}
2StringBuffer类 和StringBuilder类
1.1StringBuffer,StringBuilder类的概述
StringBuffer,StringBuilder 是可变的字符序列,可以把它看成是一个容器能对字符串内容进行增删。
修改操作直接在原对象上进行,不会创建新对象,大幅提升字符串拼接的性能。
1.2 核心特性
可变字符序列:支持增、删、改、查等操作,直接修改内部数组。
效率略低:因为加了同步锁,单线程下性能不如 StringBuilder。
初始容量:默认初始容量是 16,若预估字符串长度,建议指定初始容量(减少数组扩容次数)。
StringBuffer
线程安全:所有方法都用 synchronized 修饰,多线程环境下操作不会出问题。
1.3 StringBuffer类 和StringBuilder类 方法
方法一样名字不同而已
public class StringBufferDemo {
public static void main(String[] args) {
// 1. 创建对象(指定初始容量,推荐)
StringBuffer sb = new StringBuffer(32); // 初始容量32,避免扩容
// 2. 拼接字符串(append,最常用)
sb.append("Java");
sb.append(8);
sb.append(true);
System.out.println(sb); // 输出:Java8true
// 3. 插入字符串(insert)
sb.insert(4, "SE"); // 在索引4的位置插入"SE"
System.out.println(sb); // 输出:JavaSE8true
// 4. 修改字符(setCharAt)
sb.setCharAt(0, 'j'); // 把索引0的字符改为小写j
System.out.println(sb); // 输出:javaSE8true
// 5. 删除字符(delete)
sb.delete(8, 12); // 删除索引8到11的字符(左闭右开)
System.out.println(sb); // 输出:javaSE8
// 6. 反转字符串(reverse)
sb.reverse();
System.out.println(sb); // 输出:8ESavaj
// 7. 转为String类型
String str = sb.toString();
System.out.println(str); // 输出:8ESavaj
}
}
public class StringBuilderDemo {
public static void main(String[] args) {
// 创建对象
StringBuilder sb = new StringBuilder(); // 默认容量16
// 拼接操作(和StringBuffer用法完全一致)
sb.append("Hello")
.append(" ")
.append("World"); // 链式调用,更简洁
System.out.println(sb); // 输出:Hello World
// 插入
sb.insert(5, ",");
System.out.println(sb); // 输出:Hello, World
// 替换
sb.replace(6, 12, "Java"); // 替换索引6到11的字符为Java
System.out.println(sb); // 输出:Hello, Java
// 长度和容量
System.out.println("字符长度:" + sb.length()); // 输出:11
System.out.println("当前容量:" + sb.capacity()); // 输出:16(未扩容)
}
}
3.String类 ,StringBuffer类的,StringBuilder类比较
特性 String StringBuffer StringBuilder
可变性 不可变 可变 可变
线程安全 安全(不可变) 安全(同步锁) 不安全
效率 最低(频繁创建对象) 中等(同步开销) 最高(无同步)
适用场景 少量字符串操作 多线程环境下的字符串操作 单线程环境下的字符串操作(推荐)
关键注意点
-
扩容机制:当字符长度超过当前容量时,会自动扩容为
原容量 * 2 + 2,并复制原数组内容,频繁扩容会损耗性能,因此预估长度并指定初始容量是优化关键。示例:new StringBuilder(100)比默认的 16 容量更高效。 -
链式调用:
append()、insert()等方法会返回对象本身(return this),因此支持链式调用(如sb.append("a").append("b"))。 -
线程安全场景:如果多线程同时修改字符串,优先用
StringBuffer;若用StringBuilder,需手动加锁(如synchronized)。
更多推荐




所有评论(0)